HB_FUNC Bridge Reference

The HB_FUNC bridge is the critical layer that connects Harbour's OOP runtime to native platform APIs. Every HarbourBuilder control operation — creating a window, setting a property, handling an event — flows through this bridge. This page documents the core HB_FUNC functions and explains how the architecture works.

What is an HB_FUNC?

HB_FUNC is a Harbour C API macro used to define C/C++ functions that can be called from Harbour code. Each HB_FUNC receives parameters from the Harbour stack via hb_par* functions and returns values via hb_ret* functions. HarbourBuilder uses approximately 130–160 HB_FUNC functions depending on the platform backend.

Bridge Architecture

The bridge sits between Harbour's OOP layer and the native platform API. When you call oForm:Create() in Harbour, the OOP method internally calls UI_FormNew(), which is an HB_FUNC that invokes the platform's native window creation API:

graph TB A["Harbour OOP Code
oForm:Create()"] --> B["Harbour Class Method
TForm:Create()"] B --> C["HB_FUNC Call
UI_FormNew( cTitle, nW, nH )"] C --> D1["Win32 Backend
CreateWindowEx()"] C --> D2["Cocoa Backend
[NSWindow alloc]"] C --> D3["GTK3 Backend
gtk_window_new()"] D1 --> E["Native Window"] 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
One bridge, three backends

The Harbour OOP code and the HB_FUNC names are identical across all platforms. Only the C/C++/Obj-C implementation behind each HB_FUNC changes. This means your .prg code is 100% portable — it doesn't need to know whether it's running on Windows, macOS, or Linux.

Core HB_FUNC Functions

Form Management

FunctionParametersReturnsDescriptionBackend
UI_FormNew cTitle, nWidth, nHeight nFormHandle Creates a new top-level window with the specified title and dimensions. Returns a numeric handle that identifies the form in all subsequent calls. Win32: CreateWindowEx()
Cocoa: [[NSWindow alloc] init]
GTK3: gtk_window_new()
UI_FormShow nFormHandle void Makes the form visible on screen. On Windows, calls ShowWindow(hWnd, SW_SHOW). On macOS, makes the NSWindow key and order front. On GTK3, calls gtk_widget_show_all(). Win32: ShowWindow()
Cocoa: [win orderFront:]
GTK3: gtk_widget_show_all()
UI_FormClose nFormHandle void Closes and destroys the form. Triggers cleanup of all child controls and native resources. Win32: DestroyWindow()
Cocoa: [win close]
GTK3: gtk_widget_destroy()
UI_FormCenter nFormHandle void Centers the form on the screen. Calculates screen dimensions and positions the window accordingly. Win32: SetWindowPos()
Cocoa: [win cascadeTopLeft:]
GTK3: gtk_window_set_position()
UI_SetTitle nHandle, cTitle void Sets the title bar text of a form. Win32: SetWindowText()
Cocoa: [win setTitle:]
GTK3: gtk_window_set_title()

Control Creation

FunctionParametersReturnsDescriptionBackend
UI_ControlCreate nType, nParentHandle, nLeft, nTop, nWidth, nHeight nControlHandle Creates a native widget of the specified type (CT_BUTTON, CT_EDIT, etc.) within a parent container. The type constant determines which native widget is instantiated. Returns a handle for subsequent property and event calls. Win32: CreateWindowEx()
Cocoa: [[NSButton alloc] init]
GTK3: gtk_button_new()
UI_ButtonCreate nParentHandle, nLeft, nTop, nWidth, nHeight, cCaption nHandle Convenience function that creates a button with caption in one call. Win32: CreateWindowEx("BUTTON")
Cocoa: NSButton
GTK3: gtk_button_new_with_label()
UI_EditCreate nParentHandle, nLeft, nTop, nWidth, nHeight nHandle Creates a single-line text input field. Win32: CreateWindowEx("EDIT")
Cocoa: NSTextField
GTK3: gtk_entry_new()
UI_LabelCreate nParentHandle, nLeft, nTop, nWidth, nHeight, cText nHandle Creates a static text label. Win32: CreateWindowEx("STATIC")
Cocoa: NSTextField
GTK3: gtk_label_new()

Property Management

FunctionParametersReturnsDescriptionBackend
UI_SetProp nHandle, nPropId, xValue void Generic property setter. nPropId is a constant identifying which property to set (e.g., PROP_TEXT, PROP_VISIBLE, PROP_COLOR). The value type depends on the property. This is the primary way all control properties are modified at runtime. Win32: various API calls
Cocoa: property setters
GTK3: g_object_set()
UI_GetProp nHandle, nPropId xValue Generic property getter. Returns the current value of the specified property. The return type depends on the property being queried. Win32: GetWindowText etc.
Cocoa: property getters
GTK3: g_object_get()
UI_SetText nHandle, cText void Sets the text content of a control. Convenience wrapper around UI_SetProp(PROP_TEXT, cText). Win32: SetWindowText()
Cocoa: [ctrl setStringValue:]
GTK3: gtk_label_set_text()
UI_GetText nHandle cText Gets the text content of a control. Convenience wrapper around UI_GetProp(PROP_TEXT). Win32: GetWindowText()
Cocoa: [ctrl stringValue]
GTK3: gtk_label_get_text()
UI_SetColor nHandle, nForeColor, nBackColor void Sets the foreground and background colors of a control. Win32: SetTextColor()/SetBkColor()
Cocoa: NSColor
GTK3: CSS/GDK RGBA
UI_SetFont nHandle, cFontName, nSize, lBold, lItalic void Sets the font of a control with full style specification. Win32: CreateFont()
Cocoa: NSFont
GTK3: PangoFontDescription
UI_SetBounds nHandle, nLeft, nTop, nWidth, nHeight void Sets position and size in a single call for efficiency. Win32: MoveWindow()
Cocoa: [view setFrame:]
GTK3: gtk_widget_set_size_request()
UI_SetVisible nHandle, lVisible void Shows or hides a control. Win32: ShowWindow()
Cocoa: [view setHidden:]
GTK3: gtk_widget_show/hide()
UI_SetEnabled nHandle, lEnabled void Enables or disables a control (grayed out when disabled). Win32: EnableWindow()
Cocoa: [ctrl setEnabled:]
GTK3: gtk_widget_set_sensitive()

Event Management

FunctionParametersReturnsDescriptionBackend
UI_OnEvent nHandle, nEventId, bCodeBlock void Registers a Harbour code block to be executed when the specified event fires on the control. The code block is stored in a Harbour-side event table keyed by handle and event ID. When the native event fires, the backend calls FireEvent() to evaluate the block. Stores block in Harbour
event table (cross-platform)
FireEvent nHandle, nEventId, [params...] Result of code block Internal function called by the native backend's event handler (WndProc, action target, or g_signal callback). Looks up the registered code block and evaluates it with hb_xcompEval() or Eval(). Called from native
event handler
UI_RemoveEvent nHandle, nEventId void Removes a previously registered event handler. Removes from Harbour
event table

Lifecycle and Utility

FunctionParametersReturnsDescriptionBackend
UI_Destroy nHandle void Destroys a control and frees all associated native resources. Removes the control from the Harbour-side object table and calls the platform's native destroy function. Win32: DestroyWindow()
Cocoa: [view removeFromSuperview]
GTK3: gtk_widget_destroy()
UI_Refresh nHandle void Forces an immediate redraw of the control. Invalidates the display area and triggers a paint cycle. Win32: InvalidateRect()
Cocoa: [view setNeedsDisplay:]
GTK3: gtk_widget_queue_draw()
UI_SetFocus nHandle void Gives input focus to the specified control. Win32: SetFocus()
Cocoa: [win makeFirstResponder:]
GTK3: gtk_widget_grab_focus()
UI_AppInit cAppName void Initializes the application-level resources. Called once at startup. Sets up the event table, initializes the backend subsystem, and prepares the message loop. Win32: CoInitialize()
Cocoa: [NSApplication sharedApplication]
GTK3: gtk_init()
UI_MsgLoop none void (blocks) Enters the platform event loop. This function blocks until the application exits. It dispatches native OS events to the appropriate Harbour code blocks. Win32: GetMessage/DispatchMessage
Cocoa: [NSApp run]
GTK3: gtk_main()
UI_Quit none void Exits the event loop and terminates the application. Win32: PostQuitMessage()
Cocoa: [NSApp terminate:]
GTK3: gtk_main_quit()
UI_MsgInfo cMessage, [cTitle] void Displays a simple information message box. Win32: MessageBox()
Cocoa: NSAlert
GTK3: GtkMessageDialog

How the Bridge Works: A Complete Example

Here is the complete journey from Harbour source code to native API call:

=== Step 1: Your Harbour source code ===
DEFINE FORM oForm TITLE "Hello" SIZE 400, 300
ACTIVATE FORM oForm CENTERED

=== Step 2: Preprocessor expansion (hbbuilder.ch) ===
oForm := TForm():New( nil )
oForm:cTitle  := "Hello"
oForm:nWidth  := 400
oForm:nHeight := 300
oForm:lCentered := .T.
oForm:Activate()

=== Step 3: Harbour OOP layer (TForm class) ===
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

=== Step 4: HB_FUNC bridge (C/C++ backend) ===
// On 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 );
}

Platform-Specific Function Counts

BackendLanguageHB_FUNC countLines of code
Windows Win32 C++ ~135 ~7,100
macOS Cocoa Objective-C++ ~158 ~3,800
Linux GTK3 C ~132 ~7,300
Why different counts?

Each platform has slightly different capabilities. The macOS Cocoa backend has more HB_FUNC functions because Objective-C's messaging style sometimes requires separate bridge functions for operations that other platforms can combine. The GTK3 backend has the most lines because C requires more boilerplate for equivalent functionality.

Adding a New HB_FUNC

To extend HarbourBuilder with a new native capability, you need to:

  1. Define the HB_FUNC in each platform's backend source file:
    // In win32_backend.cpp:
    HB_FUNC( UI_NEWWIDGET )
    {
       // ... Win32 implementation ...
       hb_retni( nResult );
    }
  2. Register the function in the Harbour function table (usually automatic with HB_FUNC macro).
  3. Add the Harbour-side wrapper in the OOP class:
    METHOD CreateNewWidget( nType ) CLASS TControl
       local nHandle := UI_NewWidget( nType, ::nParent )
       ::nHandle := nHandle
       return self
  4. Add the xBase command (optional) in hbbuilder.ch:
    #xcommand DEFINE WIDGET <o> TYPE <nType> OF <oParent> ;
       => <o> := TControl():New( <oParent> );
          <o>:CreateNewWidget( <nType> )

On This Page

Getting Started Component Palette IDE Features Tutorials Reference Platforms Bridge Architecture Core HB_FUNC Functions Form Management Control Creation Property Management Event Management Lifecycle and Utility How the Bridge Works: A Complete Example Platform-Specific Function Counts Adding a New HB_FUNC