Events Reference A-Z

This page documents every event available in HarbourBuilder. Events are code blocks assigned to control properties that are invoked when the corresponding OS-level event fires. Events form the core of HarbourBuilder's reactive programming model.

How events work

Each event is a property on a control object. You assign a Harbour code block ({ || ... }) to it. When the user interacts with the control, HarbourBuilder routes the native OS event through the backend (Win32/Cocoa/GTK3) and evaluates your code block.

Event Assignment Syntax

Events are assigned using the standard Harbour assignment operator with a code block:

--- Simple event: show a message ---
oBtn:OnClick := { || MsgInfo( "Button clicked!" ) }

--- Event calling a function ---
oBtn:OnClick := { || ProcessClick( oBtn, oForm ) }

--- Event with parameters (keyboard events) ---
oEdit:OnKeyDown := { | nKey, nFlags | HandleKey( nKey, nFlags ) }

--- Event with mouse coordinates ---
oPaintBox:OnMouseMove := { | nX, nY | TrackMouse( nX, nY ) }

--- Multi-statement code block ---
oBtn:OnClick := { || ;
   LogAction( "button clicked" ), ;
   MsgInfo( "Done!" ), ;
   oForm:Close() ;
}
Designer-assigned events

In the Form Designer, select a control, go to the Events tab in the Object Inspector, and double-click an event. The IDE generates the code block and jumps to the code editor.

Mouse Events

EventParametersAvailable ControlsDescription
OnClick none All interactive controls Fires when the user clicks the control with the left mouse button. This is the most commonly used event for buttons, list items, and tree nodes.
OnDblClick none All interactive controls Fires on a double-click. For list/grid controls, this often triggers an "edit" or "open" action. For forms, can trigger default behavior.
OnMouseDown nButton, nShiftState, nX, nY All visual controls Fires when any mouse button is pressed. nButton: 1=left, 2=right, 3=middle. nShiftState: bitmask for Shift/Ctrl/Alt.
OnMouseUp nButton, nShiftState, nX, nY All visual controls Fires when any mouse button is released. Useful for drag-and-drop completion or measuring click duration.
OnMouseMove nX, nY All visual controls Fires continuously as the mouse moves over the control. Use sparingly; it fires very frequently. Good for tracking cursor position or hover effects.
OnMouseWheel nDelta, nX, nY All visual controls Fires when the mouse wheel is scrolled. nDelta is positive for scroll up/forward, negative for scroll down/back. Typically used for zooming or scrolling content.

Mouse Event Examples

--- OnClick: simple button action ---
oBtn:OnClick := { || MsgInfo( "Hello!" ) }

--- OnMouseDown: detect right-click context menu ---
oPanel:OnMouseDown := { | nBtn, nShift, nX, nY | ;
   if nBtn == 2  /// right click
      ShowContextMenu( nX, nY )
   endif ;
}

--- OnMouseWheel: zoom in/out on an image ---
oImage:OnMouseWheel := { | nDelta, nX, nY | ;
   if nDelta > 0
      oImage:nZoom += 0.1
   else
      oImage:nZoom -= 0.1
   endif, ;
   oImage:Refresh() ;
}

Keyboard Events

EventParametersAvailable ControlsDescription
OnKeyDown nKey, nFlags All focusable controls Fires when a key is pressed down. nKey is the virtual key code (VK_ constants). nFlags contains repeat count and scan code. Fires before the character is processed.
OnKeyUp nKey, nFlags All focusable controls Fires when a key is released. Useful for detecting how long a key was held or for key-chord detection.
OnKeyPress cKey Edit, Memo, MaskEdit, ComboBox Fires when a character key is typed. cKey is the actual character (not virtual code). Allows you to modify or cancel the character by changing the parameter.

Keyboard Event Examples

--- OnKeyDown: handle Enter and Escape ---
oForm:OnKeyDown := { | nKey, nFlags | ;
   if nKey == VK_RETURN
      AcceptForm()
   elseif nKey == VK_ESCAPE
      CancelForm()
   endif ;
}

--- OnKeyPress: filter input to digits only ---
oEdit:OnKeyPress := { | cKey | ;
   if !( cKey >= "0" .and. cKey <= "9" ) .and. cKey != Chr( 8 )
      Alert( "Only digits allowed" )
      return .F.   /// cancel the key
   endif ;
}

--- OnKeyUp: detect Ctrl+S for save shortcut ---
oForm:OnKeyUp := { | nKey, nFlags | ;
   if nKey == 83 .and. GetKeyState( VK_CONTROL ) < 0
      SaveProject()
   endif ;
}

Focus and Selection Events

EventParametersAvailable ControlsDescription
OnEnter none All focusable controls Fires when the control receives input focus (via Tab, click, or programmatically). Useful for highlighting the active field or showing context-sensitive help.
OnExit none All focusable controls Fires when the control loses focus. Use this for validation: check the field value and prevent focus loss by returning .F. if invalid.
OnChange none Edit, Memo, ComboBox, CheckBox, Radio, TrackBar, UpDown Fires when the control's value changes. For edit controls, fires on every keystroke. For combos, fires when the selection changes.

Focus Event Examples

--- OnEnter: highlight the active field ---
oEdit:OnEnter := { || ;
   oEdit:nBackColor := CLR_YELLOW, ;
   oEdit:Refresh() ;
}

--- OnExit: validate email format ---
oEmailEdit:OnExit := { || ;
   local cVal := oEmailEdit:GetValue()
   if "@" $ cVal .and. "." $ cVal
      return .T.
   else
      MsgStop( "Invalid email address" )
      return .F.   /// keep focus
   endif ;
}

--- OnChange: live character counter ---
oMemo:OnChange := { || ;
   oStatusLabel:SetText( ;
      LTrim( Str( Len( oMemo:GetValue() ) ) ) + " characters" ;
   ) ;
}

Form Lifecycle Events

EventParametersAvailable ControlsDescription
OnCreate none Form Fires when the form object is first created, before any controls are added. Use this for early initialization, loading configuration, or setting up data connections.
OnInit none Form Fires after all controls have been created and the form is about to be displayed. This is the ideal place for final setup: populating lists, setting default values, positioning.
OnShow none Form Fires each time the form becomes visible. Fires on initial display and again if the form was hidden and shown again.
OnHide none Form Fires when the form is hidden (via Hide() or minimized). Use to pause timers or stop background tasks.
OnActivate none Form Fires when the form gains focus (becomes the active window). Distinct from OnShow: a form can be shown but not activated if another window is on top.
OnDeactivate none Form Fires when the form loses focus to another window in the same application.
OnActivateApp lActive Form Fires when the entire application gains or loses focus at the OS level. lActive is .T. when the app is foregrounded, .F. when backgrounded.
OnCloseQuery @lCanClose Form Fires before the form closes. Set lCanClose to .F. to cancel the close operation. Use for "Save changes?" prompts.
OnClose none Form Fires when the form is closing (after OnCloseQuery allows it). Use for cleanup: closing database connections, saving state, releasing resources.
OnDestroy none Form, all controls Fires when the control/form is being destroyed and memory is about to be freed. Last chance for cleanup.

Form Lifecycle Examples

--- OnCreate: early initialization ---
oForm:OnCreate := { || ;
   LoadConfig( "app.ini" ), ;
   oForm:cTitle := "My App v" + GetVersion() ;
}

--- OnInit: populate controls after everything is created ---
oForm:OnInit := { || ;
   oComboBox:aItems := { "Option A", "Option B", "Option C" }, ;
   oComboBox:nItemIndex := 0, ;
   LoadRecentFiles() ;
}

--- OnCloseQuery: prompt to save changes ---
oForm:OnCloseQuery := { | @lCanClose | ;
   if lDataModified
      local nResp := MsgYesNo( "Save changes before closing?" )
      if nResp == 6  /// IDYES
         SaveData()
      elseif nResp == 2  /// IDCANCEL
         lCanClose := .F.
         return
      endif
   endif, ;
   lCanClose := .T. ;
}

--- OnClose: cleanup resources ---
oForm:OnClose := { || ;
   oDb:Close(), ;
   oTimer:lRunning := .F., ;
   SaveWindowState( oForm ) ;
}

Timer Events

EventParametersAvailable ControlsDescription
OnTimer none Timer Fires at regular intervals set by the Timer's nInterval property (in milliseconds). Use for periodic tasks: updating a clock, polling a server, animating, auto-saving.

Timer Event Example

--- OnTimer: update a clock label every second ---
oTimer:nInterval := 1000   /// 1 second
oTimer:OnTimer := { || ;
   oClockLabel:SetText( Time() ) ;
}
oTimer:lRunning := .T.    /// start the timer

--- OnTimer: auto-save every 5 minutes ---
oAutoSave:nInterval := 300000   /// 5 minutes
oAutoSave:OnTimer := { || ;
   if lDataModified
      AutoSave()
   endif ;
}

Paint and Resize Events

EventParametersAvailable ControlsDescription
OnPaint none PaintBox, Form, Panel, Shape, all visual controls Fires when the control needs to be redrawn. Use with PaintBox for custom GDI/Cairo drawing. Access the device context via platform-specific drawing functions.
OnResize nNewWidth, nNewHeight Form, Panel, ScrollBox Fires when the container is resized. Parameters provide the new dimensions. Use for repositioning child controls or recalculating layout.

Paint and Resize Examples

--- OnPaint: custom drawing on a PaintBox ---
oPaintBox:OnPaint := { || ;
   DrawLine( 0, 0, oPaintBox:nWidth, oPaintBox:nHeight ), ;
   DrawRect( 10, 10, 50, 50, CLR_BLUE ), ;
   DrawText( 70, 10, "Custom Drawing", CLR_BLACK ) ;
}

--- OnResize: keep controls proportionally positioned ---
oForm:OnResize := { | nW, nH | ;
   oGrid:nWidth  := nW - 40, ;
   oGrid:nHeight := nH - 100, ;
   oBtn:nTop    := nH - 50, ;
   oBtn:nLeft   := nW - 160 ;
}

Complete Event Summary Table

EventCategoryPrimary Controls
OnClickMouseButton, ListBox, TreeView, MenuItem, Image
OnDblClickMouseListBox, TreeView, StringGrid, Form
OnMouseDownMouseAll visual controls
OnMouseUpMouseAll visual controls
OnMouseMoveMouseAll visual controls
OnMouseWheelMouseAll visual controls
OnKeyDownKeyboardAll focusable controls
OnKeyUpKeyboardAll focusable controls
OnKeyPressKeyboardEdit, Memo, MaskEdit, ComboBox
OnChangeValueEdit, Memo, ComboBox, CheckBox, TrackBar
OnEnterFocusAll focusable controls
OnExitFocusAll focusable controls
OnCreateLifecycleForm
OnInitLifecycleForm
OnShowLifecycleForm
OnHideLifecycleForm
OnActivateLifecycleForm
OnDeactivateLifecycleForm
OnActivateAppLifecycleForm
OnCloseQueryLifecycleForm
OnCloseLifecycleForm
OnDestroyLifecycleAll controls
OnTimerTimerTimer
OnPaintDrawingPaintBox, Shape, Form, Panel
OnResizeLayoutForm, Panel, ScrollBox
Event firing order

When a user clicks a button, the event order is: OnMouseDownOnMouseUpOnClick. For keyboard input: OnKeyDownOnKeyPressOnKeyUp. Understanding this order helps you choose the right event for your use case.

On This Page

Getting Started Component Palette IDE Features Tutorials Reference Platforms Event Assignment Syntax Mouse Events Mouse Event Examples Keyboard Events Keyboard Event Examples Focus and Selection Events Focus Event Examples Form Lifecycle Events Form Lifecycle Examples Timer Events Timer Event Example Paint and Resize Events Paint and Resize Examples Complete Event Summary Table