Tutorial: Tratamento de Eventos
Eventos sao a espinha dorsal de aplicacoes interativas. Toda vez que um usuario clica em um botao, digita uma tecla, redimensiona uma janela ou fecha um formulario, o HarbourBuilder dispara um evento que seu codigo pode tratar. Este tutorial cobre todos os principais tipos de evento e as diferentes formas de responder a eles.
Passo 1: Entendendo Eventos no HarbourBuilder
Cada controle do HarbourBuilder expoe um conjunto de propriedades de evento (ex. OnClick, OnChange).
Voce atribui um bloco de codigo ou uma referencia de metodo a essas propriedades. Quando o evento
dispara, o HarbourBuilder executa seu manipulador.
(clique, tecla, redimensionar)"] --> B["Mensagem do SO
WM_COMMAND etc."] B --> C["Dispatcher de Eventos
HarbourBuilder"] C --> D["Seu Manipulador
Bloco 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
Passo 2: Gerando Manipuladores de Eventos pelo Inspetor de Objetos
- Selecione um controle no formulario (ex. um Botao).
- No Inspetor de Objetos, alterne para a aba Eventos.
- Clique duas vezes no nome do evento (ex.
OnClick). - A IDE automaticamente:
- Cria um stub de
static functionno seu arquivo fonte. - Atribui o bloco de codigo para chamar essa funcao.
- Posiciona o cursor no corpo da nova funcao para voce comecar a codificar.
- Cria um stub de
Clicar duas vezes em um evento no Inspetor de Objetos e o fluxo de trabalho recomendado. Ele gera
manipuladores com nomes adequados (ex. OnBtnSaveClick) e conecta o bloco de codigo automaticamente.
Passo 3: OnClick — Cliques em Botao e Controle
O evento mais comum. Dispara quando o usuario clica em um botao, rotulo, imagem ou qualquer controle clicavel.
Bloco de codigo inline (logica simples):
oBtn:OnClick := { || MsgInfo( "Botao foi clicado!" ) }
Chamando uma funcao separada (logica complexa):
oBtn:OnClick := { || OnBtnSaveClick( oForm, oGet ) } static function OnBtnSaveClick( oForm, oGet ) local cValue := oGet:GetValue() if Empty( cValue ) MsgAlert( "Por favor, informe um valor." ) return nil endif MsgInfo( "Salvo: " + cValue ) oForm:SetTitle( "Salvo!" ) return nil
Passo 4: OnChange — Alteracoes de Valor
Dispara sempre que o valor de um controle de entrada muda. Util para TextBox (TGet), ComboBox,
CheckBox e 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
Para controles TextBox, OnChange dispara apos cada caractere digitado. Se voce estiver fazendo operacoes custosas
(como consultas a banco de dados), considere usar um TTimer para suavizar a entrada.
Passo 5: OnKeyDown — Entrada de Teclado
Dispara quando uma tecla e pressionada enquanto o controle tem foco. O manipulador recebe o codigo da tecla e flags de modificadores como parametros.
oGet:OnKeyDown := { |nKey, nFlags| OnGetKeyDown( nKey, nFlags, oGet ) } static function OnGetKeyDown( nKey, nFlags, oGet ) do case case nKey == VK_RETURN MsgInfo( "Enter pressionado! Valor: " + oGet:GetValue() ) case nKey == VK_ESCAPE oGet:SetValue( "" ) case nKey == VK_F1 MsgInfo( "Ajuda: digite um valor e pressione Enter." ) endcase return nil
Constantes de teclas comuns: VK_RETURN, VK_ESCAPE, VK_TAB, VK_DELETE,
VK_F1 ate VK_F12, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT.
Passo 6: OnResize — Redimensionamento de Formulario e Controle
Dispara quando o usuario redimensiona o formulario. Use isso para reposicionar ou redimensionar controles dinamicamente para um layout responsivo.
oForm:OnResize := { || OnFormResize( oForm, oMemo, oStatusBar ) } static function OnFormResize( oForm, oMemo, oStatusBar ) local nW := oForm:nWidth local nH := oForm:nHeight // Fazer o memo preencher o formulario com margem de 10 pixels oMemo:SetSize( nW - 20, nH - 80 ) // Manter barra de status na parte inferior oStatusBar:SetPos( nH - 30, 0 ) oStatusBar:SetSize( nW, 30 ) return nil
Passo 7: OnClose — Fechamento de Formulario
Dispara quando o usuario tenta fechar o formulario (clicando no botao X, pressionando Alt+F4 ou chamando
Close()). Retorne .F. do manipulador para impedir o fechamento do formulario — util para
prompts de alteracoes nao salvas.
oForm:OnClose := { || OnFormClose( oForm ) } static function OnFormClose( oForm ) local nAnswer if lDataModified nAnswer := MsgYesNoCancel( "Salvar alteracoes antes de fechar?" ) do case case nAnswer == 1 // Sim SaveData() return .T. case nAnswer == 2 // Nao return .T. case nAnswer == 3 // Cancelar return .F. // Impedir fechamento endcase endif return .T.
Este e um padrao poderoso para formularios de entrada de dados. Sempre de ao usuario uma forma de forc ar o fechamento (ex. a opcao Cancelar) para que nunca fique preso em um formulario que nao consegue sair.
Resumo de Parametros de Eventos
| Evento | Parametros | Retorno | Controles |
|---|---|---|---|
OnClick |
(nenhum) | ignorado | Button, Label, Image, Panel |
OnChange |
(nenhum) | ignorado | TGet, ComboBox, CheckBox, Spinner |
OnKeyDown |
nKey, nFlags |
ignorado | Todos os controles com foco |
OnResize |
(nenhum) | ignorado | TForm |
OnClose |
(nenhum) | .T. permitir, .F. impedir |
TForm |
Bloco de Codigo vs. Manipulador de Metodo
O HarbourBuilder suporta dois estilos para manipuladores de eventos:
Bloco de codigo — ideal para logicas inline curtas:
oBtn:OnClick := { || oLabel:SetValue( Time() ) }
Manipulador de metodo — ideal para logicas complexas que precisam de sua propria funcao:
oBtn:OnClick := { || OnBtnClick( oForm ) } static function OnBtnClick( oForm ) // Logica complexa aqui: chamadas de banco, validacao, etc. ... return nil
Se o manipulador tem mais de uma expressao, use uma funcao separada. Isso mantem a definicao do formulario limpa e facilita a depuracao e teste da logica.
Agora que voce entende eventos, continue para o tutorial CRUD de Banco de Dados para construir uma aplicacao orientada a dados com SQLite.