Borland Online And The Cobb Group Present:


November, 1995 - Vol. 2 No. 11

Interfacing with Resource Workshop

In the accompanying article, Using OWL to create custom controls we mention that there are very few good resources for information about writing custom controls. If you're looking for information about writing controls that are compatible with Resource Workshop, you'll find even fewer. Here, we'll review the functions you have to create when building your own custom controls, as well as the special ListClasses() function that Resource Workshop supports.

Info()

A dialog editor will call the Info() function to retrieve a CTLINFO data structure that describes the characteristics of the custom control. This data structure (defined in the run-time library file CUSTCNTL.H) contains information such as

This information allows the dialog editor to display appropriate information about the control at design time.

The prototype for the Info() function is straightforward, as you can see:

HGLOBAL CALLBACK Info(void);

When you create this function, it needs to call the GlobalAlloc() API function to allocate a block of memory, fill in the appropriate locations in a CTLINFO or RWCTLINFO data structure, and then return an identifier for this block of memory. (The RWCTLINFO data type extends the CTLINFO type to include information necessary for Resource Workshop to display a toolbox icon for the control. This type definition also appears in the CUSTCTRL.H file.)

Flags()

The Flags() function allows you to determine how the dialog editor will translate the style information for a control into text that the editor can store in an RC file. (If you want to view this type of information, locate an RC file in a BC++ project window, right-click it, and choose Text Edit from the View submenu.) The prototype for the Flags() function is

UINT CALLBACK Flags(DWORD dwFlags,
                    LPSTR lpStyle,
                    UINT wMaxString);

Let's look at each of the parameters.

The dwFlags parameter represents one of the styles that your control specified in the Info() function. (Each control style may store its text description in a different way.) The lpStyle parameter identifies a block of memory where you can insert the translated text for the control's style information. The last parameter, wMaxString, tells you how big this block of memory is so you won't accidentally write data past the end of the block.

Style()

The dialog editor will call the Style() function in your control's DLL when you attempt to edit the control. For example, when you double-click a control in Resource Workshop, it displays a dialog box that you can use to manipulate the characteristics and style of the control.

The prototype for the Style() function is somewhat complex, as shown here:

BOOL CALLBACK Style(HND hWnd,
                    HGLOBAL hCtlStyle, 
                    LPFNSTRTOID lpfnStrToId, 
                    LPFNIDTOSTR lpfnIdToStr);

For the return value, you'll specify TRUE if the user makes valid changes to the control and FALSE if the user abandons the changes or enters invalid data.

The hWnd parameter, contrary to what you might expect, isn't an identifier for the control's window. Instead, it's an identifier for the parent window that will display the dialog box. (For example, Resource Workshop calls this function and passes the identifier for the Resource Workshop main window.)

The hCtlStyle parameter is an identifier you can use to access a block of memory that contains a CTLSTYLE or RWCTLSTYLE structure. The CTLSTYLE data structure (also defined in CUSTCNTL.H) contains size, position, and style information for the control, as well as descriptive text strings that contain the control's class name and its caption, if any. The RWCTLSTYLE data structure contains these same elements plus an optional block of up to 255 bytes that you can use to contain additional information that's common to all controls of this class.

The last two parameters, lpfnStrToId and lpfnIdToStr, are function pointers that address two functions that you can use to convert a text string into a resource ID and vice versa. If Resource Workshop can locate an RH file that associates specific resource IDs with text strings using #define directives, you can pass the control's resource ID to the function that lpfnIdToStr identifies, and it will copy the text to a buffer. You can display the text from that buffer to help the user identify the control.

ListClasses()

Of the four functions we're examining, the ListClasses() function is unique to controls that support Resource Workshop. The other three functions are necessary for both Resource Workshop and Microsoft Dialog Editor. The ListClasses() function performs one important task: It identifies a custom control DLL as one that supports the Resource Workshop versions of the Style() and Info() functions' data structures.

The return value from the ListClasses() function is an identifier for a block of memory that contains one or more sets of pointers to the three functions we just mentioned and text strings that identify the corresponding custom control class. For example, if you define two custom control classes in a DLL, that DLL should contain two Info() functions, two Flags() functions, and two Style() functions. Each function corresponds to one of the two control classes.

However, you'll need to define only one ListClasses() function. This one function will return an identifier for the block of memory that contains the addresses of the functions and the class name strings for both control classes in a CTLCLASSLIST data structure. As with the other information, you'll find the definition for the CTLCLASSLIST type in the CUSTCTRL.H file.

More custom control information

If you have version 4.02 of Borland C++, you'll find the file CUSTCNTL.TXT in the \BC4\DOC subdirectory. This file describes some of the basics of creating custom controls that we've discussed here. Unfortunately, it doesn't go into great detail.

In contrast, Windows Programming Power with Custom Controls, by Paul Cilwa and Jeff Duntemann (Coriolis Group Books), is a comprehensive tutorial on creating all sorts of custom controls. This book doesn't focus on Resource Workshop compatibility the way the CUSTCNTL.TXT file does, but it goes into much greater detail about Windows custom controls in general.

Return to the Borland C++ Developer's Journal index

Subscribe to the Borland C++ Developer's Journal


Copyright (c) 1996 The Cobb Group, a division of Ziff-Davis Publishing Company. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of Ziff-Davis Publishing Company is prohibited. The Cobb Group and The Cobb Group logo are trademarks of Ziff-Davis Publishing Company.