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.

O que e um HB_FUNC?

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:

graph TB A["Codigo Harbour OOP
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
Uma bridge, tres backends

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

FuncaoParametrosRetornaDescricaoBackend
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

FuncaoParametrosRetornaDescricaoBackend
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: NSButton
GTK3: 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: NSTextField
GTK3: gtk_entry_new()
UI_LabelCreate nParentHandle, nLeft, nTop, nWidth, nHeight, cText nHandle Cria um rotulo de texto estatico. Win32: CreateWindowEx("STATIC")
Cocoa: NSTextField
GTK3: gtk_label_new()

Gerenciamento de Propriedades

FuncaoParametrosRetornaDescricaoBackend
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: NSColor
GTK3: 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: NSFont
GTK3: 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

FuncaoParametrosRetornaDescricaoBackend
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

FuncaoParametrosRetornaDescricaoBackend
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/DispatchMessage
Cocoa: [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: NSAlert
GTK3: 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

BackendLinguagemContagem HB_FUNCLinhas de codigo
Windows Win32 C++ ~135 ~7.100
macOS Cocoa Objective-C++ ~158 ~3.800
Linux GTK3 C ~132 ~7.300
Por que contagens diferentes?

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:

  1. Definir o HB_FUNC no arquivo fonte backend de cada plataforma:
    // Em win32_backend.cpp:
    HB_FUNC( UI_NEWWIDGET )
    {
       // ... Implementacao Win32 ...
       hb_retni( nResult );
    }
  2. Registrar a funcao na tabela de funcoes do Harbour (geralmente automatico com a macro HB_FUNC).
  3. Adicionar o wrapper do lado Harbour na classe OOP:
    METHOD CreateNewWidget( nType ) CLASS TControl
       local nHandle := UI_NewWidget( nType, ::nParent )
       ::nHandle := nHandle
       return self
  4. Adicionar o comando xBase (opcional) em hbbuilder.ch:
    #xcommand DEFINE WIDGET <o> TYPE <nType> OF <oParent> ;
       => <o> := TControl():New( <oParent> );
          <o>:CreateNewWidget( <nType> )

Nesta Página

Primeiros Passos Paleta de Componentes Recursos do IDE Tutoriais Referencia Plataformas Arquitetura da Bridge Funcoes HB_FUNC Principais Gerenciamento de Formularios Criacao de Controles Gerenciamento de Propriedades Gerenciamento de Eventos Ciclo de Vida e Utilitarios Como a Bridge Funciona: Um Exemplo Completo Contagem de Funcoes por Plataforma Adicionando um Novo HB_FUNC