Choosing Fonts (PB6, Feb 23,1999)

Back Up Next

Author: Eric Aling (23 feb 1999)
Accessed:
Download: Download choosefont.zip (9 kb) (choosefont.zip, 9kb)

PowerBuilder does not have dialog boxes for choosing colors and fonts. Well, we already implemented a ChooseColor dialogbox in one of the PFC services. Now it is time for the ChooseFont dialog bix. However, this one is a bit more complex because it is using a pointer to a structure. PowerBuilder does not support pointers very well. Luckily, there's an alternative using some Windows API functions. First of all, here are the needed external function declarations:

function boolean ChooseFontA ( ref str_choosefont c ) library 'comdlg32.dll'
subroutine copymemory ( ref str_logfont d, long s, long l ) library 'kernel32.dll' alias for RtlMoveMemory
subroutine copymemory ( long d, str_logfont s, long l ) library 'kernel32.dll' alias for RtlMoveMemory
function ulong GlobalAlloc(ulong uFlags, long dwBytes ) library 'kernel32.dll'
function ulong GlobalLock(ulong hMem ) library 'kernel32.dll'
function ulong GlobalUnlock(ulong hMem ) library 'kernel32.dll'
function ulong GlobalFree(ulong hMem ) library 'kernel32.dll'

The most important one is the ChooseFont function of course. This function needs the following structure as argument:

$PBExportHeader$str_choosefont.srs
global type str_choosefont from structure
    long        	lstructsize
    unsignedlong        hwndowner
    unsignedlong        hdc
    long        	lplogfont
    long        	ipointsize
    long        	flags
    long        	rgbcolors
    long        	lcustdata
    long        	lpfnhook
    string        	lptemplatename
    unsignedlong        hinstance
    string        	lpszstyle
    integer        	nfonttype
    integer        	missingalignment
    unsignedlong        nsizemin
    unsignedlong        nsizemax
end type

Now, the font information is stored in another structure. The structure above is pointing to it via the lpLogFont member. You can see this is just a long value. So, how do we accomplish this. First of all, the definition of the LogFont structure:

$PBExportHeader$str_logfont.srs
global type str_logfont from structure
    long        	lfheight
    long        	lfwidth
    long        	lfescapement
    long       		lforientation
    long        	lfweight
    character        	lfitalic
    character        	lfunderline
    character        	lfstrikeout
    character        	lfcharset
    character        	lfoutprecision
    character        	lfclipprecision
    character        	lfquality
    character        	lfpitchandfamily
    character        	lffacename[32]
end type

And here is the code:

/* needed constants */

integer CF_SCREENFONTS = 1
integer CF_INITTOLOGFONTSTRUCT = 64
integer CF_EFFECTS = 256
integer GMEM_MOVEABLE = 2

/* pointer variable to the logfont structure */
long ll_LogFont

/* needed structures */
str_choosefont lstr_choosefont
str_logfont lstr_logfont

/* we allocate a piece of memory with the size of the logfont structure */
/* and we lock it */
ll_LogFont = GlobalAlloc ( GMEM_MOVEABLE, 60 )

if ll_LogFont = 0 then
    messagebox('MemError','Unable to alloc memory')
    return -1
end if

ll_LogFont = GlobalLock ( ll_LogFont ) 

if ll_LogFont = 0 then
    messagebox('MemError','Unable to lock memory')
    return -1
end if


/* initialise the logfont structure */

/* default font is arial */
lstr_logfont.lffacename = 'Arial'

/* Bold */
lstr_logfont.lfweight = 700

/* copy the structure to the allocated piece in memory */
copymemory ( ll_LogFont, lstr_Logfont, 60 )


/* assign the pointer to the fontinfo in memory to the dialog font */
lstr_ChooseFont.lplogfont = ll_LogFont

/* initialise the structure further */
lstr_ChooseFont.lstructsize = 60    // size
lstr_ChooseFont.hwndowner = handle(parent)
lstr_ChooseFont.flags = CF_SCREENFONTS+CF_INITTOLOGFONTSTRUCT+CF_EFFECTS

/* call the dialog */
if not ChooseFontA(lstr_ChooseFont) then
    
    /* if failed, release the used memory */
    GlobalUnlock ( ll_LogFont ) 
    GlobalFree ( ll_LogFont ) 
    
    messagebox('ChooseFont','Failed')
    
    return -1
    
end if

/* The memory piece now contains the selected log information */
/* Copy this information back to the structure so e can access it */

copymemory ( lstr_LogFont, lstr_ChooseFont.lplogfont, 60 )

/* release the used memory */

GlobalUnlock ( ll_LogFont ) 
GlobalFree ( ll_LogFont ) 

/* Display the choose fontname and the size */

st_1.textsize   = -lstr_ChooseFont.iPointSize/10
st_1.weight     = lstr_LogFont.lfWeight
st_1.underline 	= ( lstr_LogFont.lfUnderline <> char(0) )
st_1.italic     = ( lstr_LogFont.lfItalic <> char(0) )
st_1.facename   = lstr_LogFont.lffacename
st_1.textcolor  = lstr_ChooseFont.rgbColors

 

Check out the PB6 example. For more information, consult the Win32 API helpfile.

Enjoy!

Back Up Next