Tutorial: Manejo de Eventos

Los eventos son la columna vertebral de las aplicaciones interactivas. Cada vez que un usuario hace clic en un boton, escribe una tecla, redimensiona una ventana o cierra un formulario, HarbourBuilder dispara un evento que su codigo puede manejar. Este tutorial cubre todos los tipos principales de eventos y las diferentes formas de responder a ellos.

Paso 1: Comprender los Eventos en HarbourBuilder

Cada control de HarbourBuilder expone un conjunto de propiedades de evento (ej. OnClick, OnChange). Asigna un bloque de codigo o una referencia a metodo a estas propiedades. Cuando el evento se dispara, HarbourBuilder ejecuta su manejador.

graph LR A["Accion del Usuario
(clic, tecla, redimensionar)"] --> B["Mensaje del SO
WM_COMMAND etc."] B --> C["Despachador de Eventos
HarbourBuilder"] C --> D["Su Manejador
Bloque de Codigo / Metodo"] style A fill:#58a6ff,stroke:#388bfd,color:#0d1117 style B fill:#d2a8ff,stroke:#bc8cff,color:#0d1117 style C fill:#3fb950,stroke:#2ea043,color:#0d1117 style D fill:#f0883e,stroke:#d18616,color:#0d1117

Paso 2: Generar Manejadores de Eventos mediante el Inspector de Objetos

  1. Seleccione un control en el formulario (ej. un Boton).
  2. En el Inspector de Objetos, cambie a la pestania Eventos.
  3. Haga doble clic en el nombre del evento (ej. OnClick).
  4. El IDE automaticamente:
    • Crea un esqueleto de static function en su archivo fuente.
    • Asigna el bloque de codigo para llamar a esa funcion.
    • Lleva el cursor al cuerpo de la nueva funcion para que comience a codificar.
El doble clic es la forma mas rapida

Hacer doble clic en un evento en el Inspector de Objetos es el flujo de trabajo recomendado. Genera manejadores con nombres adecuados (ej. OnBtnSaveClick) y conecta el bloque de codigo automaticamente.

Paso 3: OnClick — Clics en Botones y Controles

El evento mas comun. Se dispara cuando el usuario hace clic en un boton, etiqueta, imagen o cualquier control que acepte clics.

Bloque de codigo en linea (logica simple):

oBtn:OnClick := { || MsgInfo( "Se hizo clic en el boton!" ) }

Llamar a una funcion separada (logica compleja):

oBtn:OnClick := { || OnBtnSaveClick( oForm, oGet ) }

static function OnBtnSaveClick( oForm, oGet )

   local cValue := oGet:GetValue()

   if Empty( cValue )
      MsgAlert( "Por favor ingrese un valor." )
      return nil
   endif

   MsgInfo( "Guardado: " + cValue )
   oForm:SetTitle( "Guardado!" )

return nil

Paso 4: OnChange — Cambios de Valor

Se dispara cada vez que cambia el valor de un control de entrada. Util para TextBox (TGet), ComboBox, CheckBox y controles Spinner.

oGetSearch:OnChange := { || OnSearchChange( oGetSearch, oListBox ) }

static function OnSearchChange( oGet, oList )

   local cFilter := oGet:GetValue()

   oList:Filter( { |cItem| Upper( cFilter ) $ Upper( cItem ) } )

return nil
OnChange se dispara con cada pulsacion de tecla

Para controles TextBox, OnChange se dispara despues de cada caracter tecleado. Si esta realizando operaciones costosas (como consultas a base de datos), considere usar un TTimer para aplicar un retardo (debounce) a la entrada.

Paso 5: OnKeyDown — Entrada de Teclado

Se dispara cuando se presiona una tecla mientras el control tiene el foco. El manejador recibe el codigo de tecla y las banderas de modificador como parametros.

oGet:OnKeyDown := { |nKey, nFlags| OnGetKeyDown( nKey, nFlags, oGet ) }

static function OnGetKeyDown( nKey, nFlags, oGet )

   do case
   case nKey == VK_RETURN
      MsgInfo( "Enter presionado! Valor: " + oGet:GetValue() )

   case nKey == VK_ESCAPE
      oGet:SetValue( "" )

   case nKey == VK_F1
      MsgInfo( "Ayuda: escriba un valor y presione Enter." )

   endcase

return nil

Constantes de teclas comunes: VK_RETURN, VK_ESCAPE, VK_TAB, VK_DELETE, VK_F1 hasta VK_F12, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT.

Paso 6: OnResize — Redimensionamiento de Formularios y Controles

Se dispara cuando el usuario redimensiona el formulario. Util para reposicionar o redimensionar controles dinamicamente para un diseno adaptable.

oForm:OnResize := { || OnFormResize( oForm, oMemo, oStatusBar ) }

static function OnFormResize( oForm, oMemo, oStatusBar )

   local nW := oForm:nWidth
   local nH := oForm:nHeight

   // Hacer que el memo llene el formulario con un margen de 10 pixeles
   oMemo:SetSize( nW - 20, nH - 80 )

   // Mantener la barra de estado en la parte inferior
   oStatusBar:SetPos( nH - 30, 0 )
   oStatusBar:SetSize( nW, 30 )

return nil

Paso 7: OnClose — Cierre del Formulario

Se dispara cuando el usuario intenta cerrar el formulario (haciendo clic en el boton X, presionando Alt+F4, o llamando a Close()). Devuelva .F. desde el manejador para prevenir que el formulario se cierre — util para avisos de cambios no guardados.

oForm:OnClose := { || OnFormClose( oForm ) }

static function OnFormClose( oForm )

   local nAnswer

   if lDataModified
      nAnswer := MsgYesNoCancel( "Guardar cambios antes de cerrar?" )

      do case
      case nAnswer == 1   // Si
         SaveData()
         return .T.

      case nAnswer == 2   // No
         return .T.

      case nAnswer == 3   // Cancelar
         return .F.         // Prevenir el cierre

      endcase
   endif

return .T.
Devolver .F. previene el cierre

Este es un patron potente para formularios de entrada de datos. Siempre de al usuario una forma de forzar el cierre (ej. la opcion Cancelar) para que nunca quede atrapado en un formulario del que no pueda salir.

Resumen de Parametros de Eventos

Evento Parametros Retorno Controles
OnClick (ninguno) ignorado Button, Label, Image, Panel
OnChange (ninguno) ignorado TGet, ComboBox, CheckBox, Spinner
OnKeyDown nKey, nFlags ignorado Todos los controles con foco
OnResize (ninguno) ignorado TForm
OnClose (ninguno) .T. permitir, .F. prevenir TForm

Bloque de Codigo vs. Manejador de Metodo

HarbourBuilder soporta dos estilos para manejadores de eventos:

Bloque de codigo — ideal para logica corta en linea:

oBtn:OnClick := { || oLabel:SetValue( Time() ) }

Manejador de metodo — ideal para logica compleja que necesita su propia funcion:

oBtn:OnClick := { || OnBtnClick( oForm ) }

static function OnBtnClick( oForm )
   // Logica compleja aqui: llamadas a BD, validacion, etc.
   ...
return nil
Regla practica

Si el manejador tiene mas de una expresion, use una funcion separada. Mantiene su definicion de formulario limpia y facilita la depuracion y prueba de la logica.

Siguiente paso

Ahora que comprende los eventos, continue al tutorial de CRUD de Base de Datos para construir una aplicacion basada en datos con SQLite.

En Esta Página

Primeros Pasos Paleta de Componentes Funciones del IDE Tutoriales Referencia Plataformas Paso 1: Comprender los Eventos en HarbourBuilder Paso 2: Generar Manejadores de Eventos mediante el Inspector de Objetos Paso 3: OnClick — Clics en Botones y Controles Paso 4: OnChange — Cambios de Valor Paso 5: OnKeyDown — Entrada de Teclado Paso 6: OnResize — Redimensionamiento de Formularios y Controles Paso 7: OnClose — Cierre del Formulario Resumen de Parametros de Eventos Bloque de Codigo vs. Manejador de Metodo