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

flowchart LR A[DEFINE / New] --> B[Use in Controls
Windows, Dialogs] B --> C[":End() / Release()"] C --> D[GDI Handle Freed] style A fill:#2d6a4f,color:#fff style C fill:#d32f2f,color:#fff

TFont

Fuente: source/classes/font.prg

Key DATA Members

DATATypeDescription
cFaceNameCharacterFont face name (e.g. "Arial", "Segoe UI")
hFontNumericWindows HFONT handle
lBoldLogicalBold weight
lItalicLogicalItalic style
lUnderlineLogicalUnderline decoration
lStrikeOutLogicalStrikeout decoration
nWeightNumericFont weight (400=normal, 700=bold)
nCharSetNumericCharacter set (0=ANSI, 1=DEFAULT, 255=OEM)
nEscapementNumericText angle in tenths of degrees
nOrientationNumericCharacter orientation angle
nInpHeightNumericRequested height (negative = point size)

Key Methods

MethodDescription
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

Fuente: source/classes/brush.prg

Key DATA Members

DATATypeDescription
hBrushNumericWindows HBRUSH handle
cStyleCharacterBrush style name
nRGBColorNumericSolid color RGB value
cBmpFileCharacterBitmap file for pattern fill
cBmpResCharacterBitmap resource name
aGradArrayGradient definition array
nResizeModeNumeric0=no resize, 1=stretch, 2=tile

Brush Styles

StyleDescription
"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

Fuente: 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

DATATypeDescription
hBitmapNumericWindows HBITMAP handle
hPaletteNumericColor palette handle
cBmpFileCharacterSource bitmap file path
cResNameCharacterResource name
lStretchLogicalStretch image to fit control
lScrollLogicalEnable scrolling
lTransparentLogicalTransparent background
lHasAlphaLogicalImage has alpha channel
nZoomNumericZoom level (1 = 100%)
nImgWidthNumericOriginal image width
nImgHeightNumericOriginal image height

Key Methods

MethodDescription
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 reFuente:
   // @ 1, 1 BITMAP oBmp RESOURCE "LOGO" OF oDlg SIZE 250, 180

   ACTIVATE DIALOG oDlg CENTER

return nil

TImage

Fuente: 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)

MethodDescription
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

Fuente: source/classes/ini.prg

TIni manages Windows INI configuration files. It uses the Windows API Funciones GetPrivateProfileString() and WritePrivateProfileString() for reliable INI file access.

Key DATA Members

DATATypeDescription
cIniFileCharacterINI file path
lAutoSetLogicalAuto-save on Get (write default if missing)

Methods

MethodDescription
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

Fuente: source/classes/reg32.prg

TReg32 provides read/write access to the Windows Registry. It wraps the Windows Registry API Funciones (RegOpenKeyEx, RegQueryValueEx, RegSetValueEx, etc.).

Key DATA Members

DATATypeDescription
cRegKeyCharacterRegistry key path
nKeyNumericRoot key (HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, etc.)
nHandleNumericOpen key handle
nErrorNumericLast error code (0 = success)
lErrorLogicalError flag

Methods

MethodDescription
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

ConstantDescription
HKEY_CLASSES_ROOTFile associations and COM classes
HKEY_CURRENT_USERCurrent user settings
HKEY_LOCAL_MACHINEMachine-wide settings (requires admin)
HKEY_USERSAll user profiles
HKEY_CURRENT_CONFIGCurrent 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