| Author: | Eric Aling (23 feb 1999) |
| Download: |
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!