Other Pointers in UDTs


Once in a while, you might need to load a pointer to something other than a string into a UDT field. For example, the CHOOSEFONT structure used by the ChooseFont function has a field for a pointer to a LOGFONT structure. This is an obscure problem, and the sample that illustrates it is obsolete, so I’ll be brief here.


Notice that the ChooseFont function and the CHOOSEFONT structure have the same name except for case. That works for C, and apparently the designer of this Windows function didn’t recognize that not all languages are case sensitive. You have to work around this by changing the name of the Basic UDT to TCHOOSEFONT. It looks like this:

Private Type TCHOOSEFONT
lStructSize As Long ‘ Filled with UDT size
hwndOwner As Long ‘ Caller’s window handle
hDC As Long ‘ Printer DC/IC or NULL
lpLogFont As Long ‘ Pointer to LOGFONT
§

You need to fill the lpLogFont field with a LOGFONT pointer, but how? Assume that you have the following:

Dim cfnt As TCHOOSEFONT, lfnt As LOGFONT

Here’s how to make the assignment:

cfnt.lpLogFont = VarPtr(lfnt)

See “Bring Your Hatchet,” page 89, for more information on VarPtr.


One other problem. When you pass a UDT variable directly to an API function, Basic knows what you’ve done and will convert any fixed-length strings in the UDT to ANSI. But when you assign a pointer to a LOGFONT variable to the lpLogFont field of a TCHOOSEFONT variable, Basic has no idea what the pointer points to and it will do no conversion on the UDT field. Normally, LOGFONT could used fixed-length strings in a UDT, such as the following field to hold the font name:

lfFaceName As String * 32

But in this case you have to define lfFaceName as an array of bytes:

lfFaceName(0 To 31) As Byte

Of course, you’d have to do this anyway if you were using a type library. You must handle Unicode conversion yourself, using the BytesToStr and StrToBytes functions described in “Reading and Writing Blobs,” page 277. You can check out the details in COMDLG.BAS.