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