O TBrowse é interessante, porque atende tudo.
Basicamente é definir os campos, e definir as rotinas de posicionamento.
E uma coisa é um TBrowse de visualização, e outra coisa é o que as LIBs GUIs costumam fazer... colocando edição junto.
Para ADO é a mesma coisa mas.... costumam querer colocar edição.
Browse:GoTop()
DBF: { || dbGoTop() }
Array: { || nIndex := 1 }
ADO: { | Rs | Rs:MoveFirst() }
Browse:GoBottom()
DBF: { || dbGoBottom() }
Array: { || nIndex := Len( aArray ) }
ADO: { | Rs | Rs:MoveLast() }
Browse:Skip()
DBF: { | nSkip | dbSkip( nSkip ) }
Array: { | nSkip, t | t := nItem, nItem := Max( 1, Min( Len( aArray ), nItem + nSkip ) ), nItem := t }
ADO: { | nSkip, Rs, t | t = Rs:AbsolutePosition, Rs:Move( nSkip ), Rs:AbsolutePosition - t }
Colunas:
DBF: { "titulo", { || Pad( dbf->Campo, 10 ) } }
Array: { "itulo", { || Array[ nIndex ] } }
ADO: { "titulo", { || Pad( Rs:Fields( Campo ):Value, 10 ) } }
Apenas exemplos genéricos. No caso de bases de dados dferentes de DBF, lógico que pode existir campo com NULL, e eventualmente precisar ajuste no codeblock do campo.
Trata-se de adequar à necessidade.
Mas como dá pra ver no ADO... é no recordset, não tem nada a ver com conexão, tipo de banco de dados, etc. coisa que está sempre presente nas rotinas pra ADO das LIBs GUI
Deixar preso a alguma outra "coisa", é obrigar o usuário a usar essa "coisa", e ficar eternamente dependente.
Porque a maioria das GUIs não seguem o esquema do tbrowse... não sei.
Talvez queiram fazer demais, e acabam fazendo de menos.... rs
Pra ter dimensionamento automático dos campos?
Isso a Picture faz, deixava por conta do usuário e pronto, recursos infinitos igual tbrowse.
Editar no browse?
LIB GUI é pra trabalhar com janelas... uma janela a mais ou a menos no browse... qual a diferença? Só pra limitar?
Console: SAVE SCREEN/RESTORE SCREEN
GUI: abrir janela nova, muito melhor isso do que deixar limitado.
Só pra lembrar:
Nem o browse do Harbour funciona direito pra edição, justamente porque é pra atender mais que DBF, e acaba não atendendo o DBF.