1) bPreChange
Para listados de personal me gusta desplegar un listbox con la ficha (Editable: con GET's) de la persona a su lado, de manera que a cada vez que cambio de lĂnea en el listbox me cambian los datos en los Get's de la ficha correspondiente. Esto entraña varios problemas, el más importante es cuando cambio algĂşn dato y despuĂ©s cambio de ficha pulsando alguna tecla o pinchando sobre otra lĂnea del Listbox, todo ello sin haber guardado las modificaciones. Personalmente me gusta que el programa me pregunte si quiero guardar los datos antes de cambiar de ficha (lo tĂpico "SI", "NO" "CANCELAR"). Se puede hacer si previamente has guardado el RECNO() de la ficha: preguntas si deseas volver y si le das a "CANCELAR" "Buscas" el RECNO(), y recuperas la ficha. Pero genaralmente el listbox parpadea de forma desagradable, el VSCroll se desplaza arriba y abajo y la lĂnea en la que estaba el foco del Listbox cambia de lugar. Un efecto desagradable y poco profesional.
Lo solucioné con el CodeBlock ::bPreChange, más una variable lógica ::lContinue, La mecánica es bien simple:
hay que colocar ::lContinue := .T. al principio de los métodos 'KeyDown', 'LButtonDown' y 'VScroll' para que llegue como .T. a todos los métodos que implican movimiento del listbox. Después, en cada uno de esos métodos; GoUp(), GoDown(), GoTop(), Etc..., hay que hacer lo siguiente:
IF Se Puede Procesar Movimiento
IF bPrechange # NIL
EVAL(bPrechange, ... <VARIABLES A GUSTO DEL PROGRAMADOR> ...)
ENDIF
IF ::lContinue
...
PROCESAR MOVIMIENTO
...
IF bChange # NIL
EVAL(bChange,Self)
ENDIF
...
ENDIF
Ahora, cuando contestes "CANCELAR" con hacer oLbx:lContinue := .F. te quedas en la ficha puĂ©s el Listbox no se ha movido. Parece mucho, pero tan sĂłlo supone una quincena de lĂneas (muchas repetidas) en el PRG (muy pocos minutos).
También sirve para cualquier otra acción que tengamos que realizar antes de cambiar de registro. Por ejemplo: oDBD:Save(), un repintado o refresco de pantalla, una consulta a tablas, pedidos, avisos, recordatorios, etc...
2) ::nMaxCol
La segunda propuesta, para quien haya aguantado el tostĂłn, tiene que ver con la estĂ©tica del Listbox. Es más accesoria. Se trata de especificar cuál va a ser la Ăşltima columna visible más a la izquierda del listbox Âż?. Me explico. Normalmente, cuando pulsamos 'flecha derecha' o pinchamos sobre el HSCroll (en la parte derecha), las columnas del listbox se desplazan hacia la izquierda hasta llegar a la Ăşltima. Amenudo esa ultima columna es la más estrecha y en esas condiciones ocupa todo el listbox (casi todo el listbox está en blanco). Con ::nMaxCol podemos hacer que esto no ocurra. Por ejemplo, supongamos que tengo 10 columnas para listar, pero se ven de tres en tres, me desplazo hacia la derecha hasta que la la octava columna está a la vista y pegada a la izquierda del listbox, aparecen asĂ a la vista las columnas 8, 9 y 10. No necesito desplazarme más, para no perder la estĂ©tica de pantalla. Si ::nMaxCol vale 8 (nÂş de la columna más a la izquierda del listbox), ya no se podrĂa desplazar más. Esto me permitirĂa, además ocultar una posible onceava columna.
SoluciĂłn:
Colocar ::nMaxCol := NUMERO MAXIMO DE COLUMAS. en los métodos NEW() y REDEFINE().
Por ejemplo en wBrowse ::nMaxCol := Len( GetColSizes() )
Después hay que establecer el rango del HSCroll: 'RANGE 1,::nMaxCol'
Finalmente en el Método GoRight() habrá que añadir, al principio del todo:
IF ::nColAct < ::nMaxCol // Significa que si la columna más a la izquierda no es menor que ::nMaxCol no se procesa GoRight()
...
RESTO DEL METODO TAL CUAL
...
ENDIF
Para aplicar duarante la programaciĂłn, sencillamente:
REDEFINE oLbx ID .. OF oDlg ... FIELD ...
...
oLbx:nMaxCol := 8
Espero que sirva de algo.
Un saludo.