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.
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:
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
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
| Function | Parameters | Returns | Description | Backend |
|---|---|---|---|---|
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
| Function | Parameters | Returns | Description | Backend |
|---|---|---|---|---|
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: NSButtonGTK3: gtk_button_new_with_label() |
UI_EditCreate |
nParentHandle, nLeft, nTop, nWidth, nHeight |
nHandle |
Creates a single-line text input field. | Win32: CreateWindowEx("EDIT")Cocoa: NSTextFieldGTK3: gtk_entry_new() |
UI_LabelCreate |
nParentHandle, nLeft, nTop, nWidth, nHeight, cText |
nHandle |
Creates a static text label. | Win32: CreateWindowEx("STATIC")Cocoa: NSTextFieldGTK3: gtk_label_new() |
Property Management
| Function | Parameters | Returns | Description | Backend |
|---|---|---|---|---|
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: NSColorGTK3: CSS/GDK RGBA |
UI_SetFont |
nHandle, cFontName, nSize, lBold, lItalic |
void | Sets the font of a control with full style specification. | Win32: CreateFont()Cocoa: NSFontGTK3: 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
| Function | Parameters | Returns | Description | Backend |
|---|---|---|---|---|
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
| Function | Parameters | Returns | Description | Backend |
|---|---|---|---|---|
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/DispatchMessageCocoa: [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: NSAlertGTK3: 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
| Backend | Language | HB_FUNC count | Lines of code |
|---|---|---|---|
| Windows Win32 | C++ | ~135 | ~7,100 |
| macOS Cocoa | Objective-C++ | ~158 | ~3,800 |
| Linux GTK3 | C | ~132 | ~7,300 |
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:
- Define the HB_FUNC in each platform's backend source file:
// In win32_backend.cpp: HB_FUNC( UI_NEWWIDGET ) { // ... Win32 implementation ... hb_retni( nResult ); }
- Register the function in the Harbour function table (usually automatic with
HB_FUNCmacro). - Add the Harbour-side wrapper in the OOP class:
METHOD CreateNewWidget( nType ) CLASS TControl local nHandle := UI_NewWidget( nType, ::nParent ) ::nHandle := nHandle return self
- Add the xBase command (optional) in
hbbuilder.ch:#xcommand DEFINE WIDGET <o> TYPE <nType> OF <oParent> ; => <o> := TControl():New( <oParent> ); <o>:CreateNewWidget( <nType> )