Referencia da Bridge HB_FUNC
A bridge HB_FUNC e a camada critica que conecta o runtime OOP do Harbour as APIs nativas da plataforma. Cada operacao de controle do HarbourBuilder — criar uma janela, definir uma propriedade, tratar um evento — passa por esta bridge. Esta pagina documenta as funcoes HB_FUNC principais e explica como a arquitetura funciona.
HB_FUNC e uma macro da API C do Harbour usada para definir funcoes C/C++ que podem ser chamadas a partir
do codigo Harbour. Cada HB_FUNC recebe parametros da pilha Harbour via funcoes hb_par*
e retorna valores via funcoes hb_ret*. O HarbourBuilder usa aproximadamente 130–160
funcoes HB_FUNC dependendo do backend da plataforma.
Arquitetura da Bridge
A bridge fica entre a camada OOP do Harbour e a API nativa da plataforma. Quando voce chama
oForm:Create() em Harbour, o metodo OOP internamente chama UI_FormNew(), que
e um HB_FUNC que invoca a API nativa de criacao de janelas da plataforma:
oForm:Create()"] --> B["Metodo da Classe Harbour
TForm:Create()"] B --> C["Chamada HB_FUNC
UI_FormNew( cTitle, nW, nH )"] C --> D1["Backend Win32
CreateWindowEx()"] C --> D2["Backend Cocoa
[NSWindow alloc]"] C --> D3["Backend GTK3
gtk_window_new()"] D1 --> E["Janela Nativa"] D2 --> E D3 --> E style A fill:#58a6ff,stroke:#388bfd,color:#0d1117 style B fill:#8b5cf6,stroke:#7c3aed,color:#fff style C fill:#f59e0b,stroke:#d97706,color:#0d1117 style D1 fill:#0078d4,stroke:#005a9e,color:#fff style D2 fill:#555,stroke:#333,color:#fff style D3 fill:#e95420,stroke:#c34113,color:#fff style E fill:#3fb950,stroke:#2ea043,color:#0d1117
O codigo Harbour OOP e os nomes HB_FUNC sao identicos em todas as plataformas. Apenas a implementacao C/C++/Obj-C por tras de cada HB_FUNC muda. Isso significa que seu codigo .prg e 100% portavel — ele nao precisa saber se esta rodando no Windows, macOS ou Linux.
Funcoes HB_FUNC Principais
Gerenciamento de Formularios
| Funcao | Parametros | Retorna | Descricao | Backend |
|---|---|---|---|---|
UI_FormNew |
cTitle, nWidth, nHeight |
nFormHandle |
Cria uma nova janela de nivel superior com o titulo e dimensoes especificados. Retorna um handle numerico que identifica o formulario em todas as chamadas subsequentes. | Win32: CreateWindowEx()Cocoa: [[NSWindow alloc] init]GTK3: gtk_window_new() |
UI_FormShow |
nFormHandle |
void | Torna o formulario visivel na tela. No Windows, chama ShowWindow(hWnd, SW_SHOW). No macOS, torna o NSWindow key e order front. No GTK3, chama gtk_widget_show_all(). | Win32: ShowWindow()Cocoa: [win orderFront:]GTK3: gtk_widget_show_all() |
UI_FormClose |
nFormHandle |
void | Fecha e destroi o formulario. Aciona limpeza de todos os controles filhos e recursos nativos. | Win32: DestroyWindow()Cocoa: [win close]GTK3: gtk_widget_destroy() |
UI_FormCenter |
nFormHandle |
void | Centraliza o formulario na tela. Calcula as dimensoes da tela e posiciona a janela conforme necessario. | Win32: SetWindowPos()Cocoa: [win cascadeTopLeft:]GTK3: gtk_window_set_position() |
UI_SetTitle |
nHandle, cTitle |
void | Define o texto da barra de titulo de um formulario. | Win32: SetWindowText()Cocoa: [win setTitle:]GTK3: gtk_window_set_title() |
Criacao de Controles
| Funcao | Parametros | Retorna | Descricao | Backend |
|---|---|---|---|---|
UI_ControlCreate |
nType, nParentHandle, nLeft, nTop, nWidth, nHeight |
nControlHandle |
Cria um widget nativo do tipo especificado (CT_BUTTON, CT_EDIT, etc.) dentro de um container pai. A constante de tipo determina qual widget nativo e instanciado. Retorna um handle para chamadas subsequentes de propriedade e evento. | Win32: CreateWindowEx()Cocoa: [[NSButton alloc] init]GTK3: gtk_button_new() |
UI_ButtonCreate |
nParentHandle, nLeft, nTop, nWidth, nHeight, cCaption |
nHandle |
Funcao de conveniencia que cria um botao com legenda em uma chamada. | Win32: CreateWindowEx("BUTTON")Cocoa: NSButtonGTK3: gtk_button_new_with_label() |
UI_EditCreate |
nParentHandle, nLeft, nTop, nWidth, nHeight |
nHandle |
Cria um campo de entrada de texto de linha unica. | Win32: CreateWindowEx("EDIT")Cocoa: NSTextFieldGTK3: gtk_entry_new() |
UI_LabelCreate |
nParentHandle, nLeft, nTop, nWidth, nHeight, cText |
nHandle |
Cria um rotulo de texto estatico. | Win32: CreateWindowEx("STATIC")Cocoa: NSTextFieldGTK3: gtk_label_new() |
Gerenciamento de Propriedades
| Funcao | Parametros | Retorna | Descricao | Backend |
|---|---|---|---|---|
UI_SetProp |
nHandle, nPropId, xValue |
void | Setter generico de propriedades. nPropId e uma constante que identifica qual propriedade definir (ex: PROP_TEXT, PROP_VISIBLE, PROP_COLOR). O tipo de valor depende da propriedade. Esta e a principal forma de modificar propriedades de controles em tempo de execucao. |
Win32: chamadas API variadas Cocoa: setters de propriedade GTK3: g_object_set() |
UI_GetProp |
nHandle, nPropId |
xValue |
Getter generico de propriedades. Retorna o valor atual da propriedade especificada. O tipo de retorno depende da propriedade consultada. | Win32: GetWindowText etc. Cocoa: getters de propriedade GTK3: g_object_get() |
UI_SetText |
nHandle, cText |
void | Define o conteudo de texto de um controle. Wrapper de conveniencia em torno de UI_SetProp(PROP_TEXT, cText). | Win32: SetWindowText()Cocoa: [ctrl setStringValue:]GTK3: gtk_label_set_text() |
UI_GetText |
nHandle |
cText |
Obtem o conteudo de texto de um controle. Wrapper de conveniencia em torno de UI_GetProp(PROP_TEXT). | Win32: GetWindowText()Cocoa: [ctrl stringValue]GTK3: gtk_label_get_text() |
UI_SetColor |
nHandle, nForeColor, nBackColor |
void | Define as cores de primeiro plano e fundo de um controle. | Win32: SetTextColor()/SetBkColor()Cocoa: NSColorGTK3: CSS/GDK RGBA |
UI_SetFont |
nHandle, cFontName, nSize, lBold, lItalic |
void | Define a fonte de um controle com especificacao completa de estilo. | Win32: CreateFont()Cocoa: NSFontGTK3: PangoFontDescription |
UI_SetBounds |
nHandle, nLeft, nTop, nWidth, nHeight |
void | Define posicao e tamanho em uma unica chamada para eficiencia. | Win32: MoveWindow()Cocoa: [view setFrame:]GTK3: gtk_widget_set_size_request() |
UI_SetVisible |
nHandle, lVisible |
void | Exibe ou oculta um controle. | Win32: ShowWindow()Cocoa: [view setHidden:]GTK3: gtk_widget_show/hide() |
UI_SetEnabled |
nHandle, lEnabled |
void | Habilita ou desabilita um controle (acinzentado quando desabilitado). | Win32: EnableWindow()Cocoa: [ctrl setEnabled:]GTK3: gtk_widget_set_sensitive() |
Gerenciamento de Eventos
| Funcao | Parametros | Retorna | Descricao | Backend |
|---|---|---|---|---|
UI_OnEvent |
nHandle, nEventId, bCodeBlock |
void | Registra um bloco de codigo Harbour para ser executado quando o evento especificado e acionado no controle. O bloco de codigo e armazenado em uma tabela de eventos do lado Harbour, chaveada por handle e ID de evento. Quando o evento nativo e acionado, o backend chama FireEvent() para avaliar o bloco. |
Armazena bloco na tabela de eventos Harbour (cross-platform) |
FireEvent |
nHandle, nEventId, [params...] |
Resultado do bloco de codigo | Funcao interna chamada pelo manipulador de eventos nativo do backend (WndProc, action target ou callback g_signal). Busca o bloco de codigo registrado e o avalia com hb_xcompEval() ou Eval(). |
Chamado do manipulador de eventos nativo |
UI_RemoveEvent |
nHandle, nEventId |
void | Remove um manipulador de eventos registrado anteriormente. | Remove da tabela de eventos Harbour |
Ciclo de Vida e Utilitarios
| Funcao | Parametros | Retorna | Descricao | Backend |
|---|---|---|---|---|
UI_Destroy |
nHandle |
void | Destroi um controle e libera todos os recursos nativos associados. Remove o controle da tabela de objetos do lado Harbour e chama a funcao nativa de destruicao da plataforma. | Win32: DestroyWindow()Cocoa: [view removeFromSuperview]GTK3: gtk_widget_destroy() |
UI_Refresh |
nHandle |
void | Forca um redesenho imediato do controle. Invalida a area de exibicao e aciona um ciclo de pintura. | Win32: InvalidateRect()Cocoa: [view setNeedsDisplay:]GTK3: gtk_widget_queue_draw() |
UI_SetFocus |
nHandle |
void | Da foco de entrada ao controle especificado. | Win32: SetFocus()Cocoa: [win makeFirstResponder:]GTK3: gtk_widget_grab_focus() |
UI_AppInit |
cAppName |
void | Inicializa os recursos de nivel de aplicacao. Chamado uma vez na inicializacao. Configura a tabela de eventos, inicializa os subsistemas do backend e prepara o loop de mensagens. | Win32: CoInitialize()Cocoa: [NSApplication sharedApplication]GTK3: gtk_init() |
UI_MsgLoop |
nenhum | void (bloqueia) | Entra no loop de eventos da plataforma. Esta funcao bloqueia ate a aplicacao sair. Ela despacha eventos nativos do SO para os blocos de codigo Harbour apropriados. | Win32: GetMessage/DispatchMessageCocoa: [NSApp run]GTK3: gtk_main() |
UI_Quit |
nenhum | void | Sai do loop de eventos e encerra a aplicacao. | Win32: PostQuitMessage()Cocoa: [NSApp terminate:]GTK3: gtk_main_quit() |
UI_MsgInfo |
cMessage, [cTitle] |
void | Exibe uma caixa de mensagem de informacao simples. | Win32: MessageBox()Cocoa: NSAlertGTK3: GtkMessageDialog |
Como a Bridge Funciona: Um Exemplo Completo
Aqui esta a jornada completa do codigo fonte Harbour ate a chamada de API nativa:
=== Passo 1: Seu codigo fonte Harbour === DEFINE FORM oForm TITLE "Ola" SIZE 400, 300 ACTIVATE FORM oForm CENTERED === Passo 2: Expansao do preprocessador (hbbuilder.ch) === oForm := TForm():New( nil ) oForm:cTitle := "Ola" oForm:nWidth := 400 oForm:nHeight := 300 oForm:lCentered := .T. oForm:Activate() === Passo 3: Camada OOP Harbour (classe TForm) === METHOD Activate CLASS TForm local nHandle nHandle := UI_FormNew( ::cTitle, ::nWidth, ::nHeight ) ::nHandle := nHandle if ::lCentered UI_FormCenter( nHandle ) endif UI_FormShow( nHandle ) UI_MsgLoop() RETURN nil === Passo 4: Bridge HB_FUNC (backend C/C++) === // No Windows (win32_backend.cpp): HB_FUNC( UI_FORMNEW ) { const char * cTitle = hb_parc( 1 ); int nWidth = hb_parni( 2 ); int nHeight = hb_parni( 3 ); HWND hWnd = CreateWindowEx( 0, // dwExStyle "HBBUILDER_FORM", // lpClassName cTitle, // lpWindowName WS_OVERLAPPEDWINDOW, // dwStyle CW_USEDEFAULT, CW_USEDEFAULT, // x, y nWidth, nHeight, // width, height NULL, NULL, // parent, menu hInstance, // hInstance NULL // lpParam ); hb_retni( ( int ) ( intptr_t ) hWnd ); }
Contagem de Funcoes por Plataforma
| Backend | Linguagem | Contagem HB_FUNC | Linhas de codigo |
|---|---|---|---|
| Windows Win32 | C++ | ~135 | ~7.100 |
| macOS Cocoa | Objective-C++ | ~158 | ~3.800 |
| Linux GTK3 | C | ~132 | ~7.300 |
Cada plataforma tem capacidades ligeiramente diferentes. O backend macOS Cocoa tem mais funcoes HB_FUNC porque o estilo de mensageria do Objective-C as vezes requer funcoes de bridge separadas para operacoes que outras plataformas podem combinar. O backend GTK3 tem mais linhas porque C requer mais codigo boilerplate para funcionalidade equivalente.
Adicionando um Novo HB_FUNC
Para estender o HarbourBuilder com um novo recurso nativo, voce precisa:
- Definir o HB_FUNC no arquivo fonte backend de cada plataforma:
// Em win32_backend.cpp: HB_FUNC( UI_NEWWIDGET ) { // ... Implementacao Win32 ... hb_retni( nResult ); }
- Registrar a funcao na tabela de funcoes do Harbour (geralmente automatico com a macro
HB_FUNC). - Adicionar o wrapper do lado Harbour na classe OOP:
METHOD CreateNewWidget( nType ) CLASS TControl local nHandle := UI_NewWidget( nType, ::nParent ) ::nHandle := nHandle return self
- Adicionar o comando xBase (opcional) em
hbbuilder.ch:#xcommand DEFINE WIDGET <o> TYPE <nType> OF <oParent> ; => <o> := TControl():New( <oParent> ); <o>:CreateNewWidget( <nType> )