GDI Resources
FiveWin wraps the Windows GDI (Graphics Device Interface) objects into Harbour classes. These
objects represent fonts, brushes, cursors, icons, bitmaps, and images. All GDI resources
must be released when no longer needed by calling :End() to prevent resource leaks.
This page also covers TIni (INI file management) and TReg32 (Windows Registry access).
Resource Lifecycle
Windows, Dialogs] B --> C[":End() / Release()"] C --> D[GDI Handle Freed] style A fill:#2d6a4f,color:#fff style C fill:#d32f2f,color:#fff
TFont
Fonte: source/classes/font.prg
Key DATA Members
| DATA | Type | Description |
|---|---|---|
cFaceName | Character | Font face name (e.g. "Arial", "Segoe UI") |
hFont | Numeric | Windows HFONT handle |
lBold | Logical | Bold weight |
lItalic | Logical | Italic style |
lUnderline | Logical | Underline decoration |
lStrikeOut | Logical | Strikeout decoration |
nWeight | Numeric | Font weight (400=normal, 700=bold) |
nCharSet | Numeric | Character set (0=ANSI, 1=DEFAULT, 255=OEM) |
nEscapement | Numeric | Text angle in tenths of degrees |
nOrientation | Numeric | Character orientation angle |
nInpHeight | Numeric | Requested height (negative = point size) |
Key Methods
| Method | Description |
|---|---|
New( cFaceName, nWidth, nHeight, lFromUser, lBold, ... ) | Create a font (or return cached instance) |
Choose( @nRGBColor ) | Show font picker dialog, return selected font |
nSize() | Get font size in points |
Bold( lBold ) | Create a new font with bold toggled |
Italic( lItalic ) | Create a new font with italic toggled |
Modify( nHeight, lBold, lItalic, lUnderline, lStrikeOut, nEsc ) | Create a modified copy |
Rotate( nRotateBy ) | Create a rotated copy |
Clone() | Share the same handle (reference counting) |
Activate( hDC ) | Select font into a device context |
DeActivate( hDC ) | Restore previous font |
End() | Release the font handle |
Example
#include "FiveWin.ch"
function Main()
local oFont, oFontBig, oFontItalic
// Standard definition via command
DEFINE FONT oFont NAME "Segoe UI" SIZE 0, -14
// Bold variant
DEFINE FONT oFontBig NAME "Segoe UI" SIZE 0, -20 BOLD
// Italic via method
oFontItalic := oFont:Italic( .T. )
// Use in a dialog
DEFINE DIALOG oDlg TITLE "Font Demo" SIZE 400, 200 FONT oFont
@ 1, 1 SAY "Normal text" OF oDlg
@ 2, 1 SAY "Bold text" OF oDlg FONT oFontBig
@ 3, 1 SAY "Italic text" OF oDlg FONT oFontItalic
ACTIVATE DIALOG oDlg CENTER
// Font picker
// local oChosen := oFont:Choose()
oFont:End()
oFontBig:End()
oFontItalic:End()
return nil
TBrush
Fonte: source/classes/brush.prg
Key DATA Members
| DATA | Type | Description |
|---|---|---|
hBrush | Numeric | Windows HBRUSH handle |
cStyle | Character | Brush style name |
nRGBColor | Numeric | Solid color RGB value |
cBmpFile | Character | Bitmap file for pattern fill |
cBmpRes | Character | Bitmap resource name |
aGrad | Array | Gradient definition array |
nResizeMode | Numeric | 0=no resize, 1=stretch, 2=tile |
Brush Styles
| Style | Description |
|---|---|
"HORIZONTAL" | Horizontal hatch lines |
"VERTICAL" | Vertical hatch lines |
"FDIAGONAL" | Forward diagonal hatch |
"BDIAGONAL" | Backward diagonal hatch |
"CROSS" | Cross hatch |
"DIAGCROSS" | Diagonal cross hatch |
"BORLAND" | Borland-style gradient |
"BRICKS" | Brick pattern |
"TILED" | Tiled bitmap pattern |
Example
#include "FiveWin.ch"
function Main()
local oWnd, oBrush
// Solid color brush
DEFINE BRUSH oBrush COLOR nRGB( 30, 40, 60 )
// Hatch pattern brush
// DEFINE BRUSH oBrush STYLE "DIAGCROSS" COLOR CLR_BLUE
// Bitmap brush
// DEFINE BRUSH oBrush FILE "marble.bmp"
DEFINE WINDOW oWnd TITLE "Brush Demo" BRUSH oBrush
ACTIVATE WINDOW oWnd
oBrush:End()
return nil
TCursor
TCursor wraps Windows cursor handles. Predefined cursors can be loaded by name, or custom cursors from resource files.
Example
#include "FiveWin.ch"
function Main()
local oCursor
// Predefined cursor
DEFINE CURSOR oCursor HAND
// From resource
// DEFINE CURSOR oCursor RESOURCE "MyCursor"
// Assign to a control
// oBtn:oCursor := oCursor
oCursor:End()
return nil
TIcon
TIcon wraps Windows icon handles (HICON). Icons can be loaded from resources compiled into the executable or from .ico files on disk.
Example
#include "FiveWin.ch"
function Main()
local oWnd, oIcon
// From resource (compiled into .exe)
DEFINE ICON oIcon RESOURCE "APPICON"
// From file
// DEFINE ICON oIcon FILE "myapp.ico"
DEFINE WINDOW oWnd TITLE "Icon Demo" ICON oIcon
ACTIVATE WINDOW oWnd
oIcon:End()
return nil
TBitmap
Fonte: source/classes/bitmap.prg
TBitmap is a control that displays bitmap images (BMP, PNG, JPG, GIF, ICO). It extends TControl, so it can be placed on windows and dialogs. Supports scrolling, stretching, transparency, and alpha blending.
Key DATA Members
| DATA | Type | Description |
|---|---|---|
hBitmap | Numeric | Windows HBITMAP handle |
hPalette | Numeric | Color palette handle |
cBmpFile | Character | Source bitmap file path |
cResName | Character | Resource name |
lStretch | Logical | Stretch image to fit control |
lScroll | Logical | Enable scrolling |
lTransparent | Logical | Transparent background |
lHasAlpha | Logical | Image has alpha channel |
nZoom | Numeric | Zoom level (1 = 100%) |
nImgWidth | Numeric | Original image width |
nImgHeight | Numeric | Original image height |
Key Methods
| Method | Description |
|---|---|
LoadFromClipboard( oWnd ) | Load bitmap from clipboard |
CopyToClipboard() | Copy bitmap to clipboard |
LoadFromString( cString ) | Load bitmap from a binary string |
Zoom( nZoom ) | Set zoom level |
Example
#include "FiveWin.ch"
function Main()
local oDlg, oBmp
DEFINE DIALOG oDlg TITLE "Bitmap Demo" SIZE 600, 400
@ 1, 1 BITMAP oBmp FILE "photo.bmp" OF oDlg SIZE 250, 180 STRETCH
// or from reFonte:
// @ 1, 1 BITMAP oBmp RESOURCE "LOGO" OF oDlg SIZE 250, 180
ACTIVATE DIALOG oDlg CENTER
return nil
TImage
Fonte: source/classes/image.prg
TImage extends TBitmap with FreeImage library support, enabling loading and saving of many image formats: BMP, PNG, JPEG, GIF, TIFF, WebP, ICO, PSD, RAW, and more. It can also load images from URLs.
Additional Methods (beyond TBitmap)
| Method | Description |
|---|---|
LoadImage( cResName, cBmpFile, cResFile ) | Load any format via FreeImage |
SaveImage( cFile, nFormat, nQuality ) | Save to any supported format |
LoadFromURL( cUrl ) | Download and display an image from a URL |
LoadFromMemory( cBuffer, nWidth, nHeight ) | Load from a memory buffer |
RotateImage( nAngle ) | Rotate the image by n degrees |
Progress( lProgress ) | Show/hide loading progress |
FreeImage DLL
TImage requires freeimage.dll (32-bit) or freeimage64.dll (64-bit)
in the application directory or system PATH.
Example
#include "FiveWin.ch"
function Main()
local oDlg, oImg
DEFINE DIALOG oDlg TITLE "Image Demo" SIZE 800, 600
// Load any format (PNG, JPG, GIF, WebP, etc.)
@ 1, 1 IMAGE oImg FILE "photo.png" OF oDlg SIZE 350, 250 STRETCH
// Load from URL (after dialog init)
// oImg:LoadFromURL( "https://example.com/image.jpg" )
// Save to different format
// oImg:SaveImage( "output.jpg", FIF_JPEG, 85 )
// Rotate
// oImg:RotateImage( 90 )
ACTIVATE DIALOG oDlg CENTER
return nil
TIni
Fonte: source/classes/ini.prg
TIni manages Windows INI configuration files. It uses the Windows API Funções
GetPrivateProfileString() and WritePrivateProfileString() for reliable
INI file access.
Key DATA Members
| DATA | Type | Description |
|---|---|---|
cIniFile | Character | INI file path |
lAutoSet | Logical | Auto-save on Get (write default if missing) |
Methods
| Method | Description |
|---|---|
New( cIniFile ) | Create INI manager (adds ".ini" extension if missing) |
Get( cSection, cEntry, uDefault, @uVar ) | Read a value (auto-detect type from default) |
Set( cSection, cEntry, uValue ) | Write a value |
Sections() | Get array of all section names |
DelSection( cSection ) | Delete an entire section |
DelEntry( cSection, cEntry ) | Delete a single entry |
Example
#include "FiveWin.ch"
function Main()
local oIni, cUser, nPort, lDebug
oIni := TIni():New( "myapp.ini" )
// Read settings (with defaults)
oIni:Get( "Database", "Server", "localhost", @cServer )
oIni:Get( "Database", "Port", 3306, @nPort )
oIni:Get( "App", "Debug", "N", @cDebug )
lDebug := ( cDebug == "Y" )
// Write settings
oIni:Set( "App", "LastRun", DToC( Date() ) + " " + Time() )
oIni:Set( "App", "Version", FWVersion() )
// Delete
oIni:DelEntry( "Temp", "CacheFile" )
? "Server:", cServer, "Port:", nPort
return nil
This creates/reads an INI file like:
[Database]
Server=localhost
Port=3306
[App]
Debug=N
LastRun=03/24/2026 14:30:45
Version=FWH 26.05
TReg32
Fonte: source/classes/reg32.prg
TReg32 provides read/write access to the Windows Registry. It wraps the Windows Registry API Funções (RegOpenKeyEx, RegQueryValueEx, RegSetValueEx, etc.).
Key DATA Members
| DATA | Type | Description |
|---|---|---|
cRegKey | Character | Registry key path |
nKey | Numeric | Root key (HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, etc.) |
nHandle | Numeric | Open key handle |
nError | Numeric | Last error code (0 = success) |
lError | Logical | Error flag |
Methods
| Method | Description |
|---|---|
New( nKey, cRegKey ) | Open an existing registry key |
Create( nKey, cRegKey ) | Create a new registry key (or open if exists) |
Get( cSubKey, @uVar ) | Read a value |
GetBinary( cSubKey ) | Read binary data |
Set( cSubKey, uVar, nType ) | Write a value (REG_SZ, REG_DWORD, REG_BINARY) |
Delete( cSubKey ) | Delete a subkey |
Close() | Close the registry key handle |
Root Key Constants
| Constant | Description |
|---|---|
HKEY_CLASSES_ROOT | File associations and COM classes |
HKEY_CURRENT_USER | Current user settings |
HKEY_LOCAL_MACHINE | Machine-wide settings (requires admin) |
HKEY_USERS | All user profiles |
HKEY_CURRENT_CONFIG | Current hardware configuration |
Example
#include "FiveWin.ch"
#define HKEY_CURRENT_USER 2147483649
function Main()
local oReg, cValue := ""
// Read a registry value
oReg := TReg32():New( HKEY_CURRENT_USER, ;
"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" )
if oReg:nError == 0
oReg:Get( "AppsUseLightTheme", @cValue )
? "Dark mode:", iif( cValue == Chr(0), "Yes", "No" )
oReg:Close()
endif
// Create and write a value
oReg := TReg32():Create( HKEY_CURRENT_USER, "Software\MyApp" )
if oReg:nError == 0
oReg:Set( "LastRun", DToC( Date() ) + " " + Time() )
oReg:Set( "Version", FWVersion() )
oReg:Close()
endif
// Read it back
oReg := TReg32():New( HKEY_CURRENT_USER, "Software\MyApp" )
if oReg:nError == 0
oReg:Get( "LastRun", @cValue )
? "Last run:", cValue
oReg:Close()
endif
return nil
Resource Management Best Practices
- Always call :End() on GDI resources (TFont, TBrush, TIcon, TBitmap, TImage) when you are done with them. Windows has a limited pool of GDI handles.
- Font caching: TFont internally caches fonts. Creating the same font twice returns the same object with an incremented reference count. Calling :End() decrements the count and only frees the handle when it reaches zero.
- Brush for windows: When assigning a brush to a window, the window takes ownership. The brush is freed when the window is destroyed.
- TIni and TReg32 do not use GDI handles, but TReg32:Close() should be called to release the registry key handle.
- Use
GDI_GetObjectCount()during development to monitor GDI handle usage and detect leaks.