The PellesC documentation contains pratically nothing about custom controls integration in the IDE.
Basically PellesC behaves as the dialog editor of MSVC++.
To find documentation around is very difficult because MS pushes to use technologies based on automation interface and removed everything from its databases.
What remains is in comments of 'custcntl.h' in its MS version (PellesC version has been stripped of all comments). You can find it in the Win7 SDK.
I don't want discuss here how you can create a custom control, for which there are better tutorials around (i.e. on
catch22), but just spend few words on optional service routines required to integrate your custom control in the dialog editor of PellesC (and of MSVC++ which is the same).
All you need to interact with the dialog editor is a function that gives all necessary information to the editor, this function is
'CustomControlInfo'.
The editor will search for such function in the custom control DLL (and also for its variants: 'CustomControlInfoA' and 'CustomControlInfoW' for unicode). If the function is not found in the DLL you will get an error message saying that this is not a custom control DLL!.
The prototype of this function is:
UINT CALLBACK CustomControlInfo(LPCCINFO acci)
It requires a valid pointer to a memory area large enough to hold an array of descriptive structures 'acci', and returns the number of custom controls in the DLL.
The normal procedure is to call first the function with a null pointer to get only the number of controls in the library, then allocate memory and call again the function to collect controls data:
int n = CustomControlInfo(NULL);
LPCCINFO p_acci = malloc(n * sizeof(CCINFO));
CustomControlInfo(p_acci);
Now we have an array of 'n' elements of custom controls info structures pointed by p_acci.
Wait, but we are on the other side! the editor call our routine 'CustomControlInfo', and we have to answer correctly!
So when we get a call to our 'CustomControlInfo' with a null parameter we return the number of controls in our library, if the parameter is a valid pointer we fill in the array with appropriate controls data.
UINT CALLBACK CustomControlInfo (LPCCINFO acci)
{
if (!acci) // Editor is querying the number of controls this DLL supports, so return the number.
return NCONTROLS;
//
// Else we can fill in the constant calues.
//
for (int i=0; i<NCONTROLS; i++)
{
acci[i].flOptions = 0;
acci[i].cxDefault = 40; // default width (dialog units)
acci[i].cyDefault = 40; // default height (dialog units)
acci[i].flStyleDefault = WS_CHILD | WS_VISIBLE;
... //Fill the structure
}
//
// Return the number of controls that the DLL supports
//
return NCONTROLS;
}
One of the elements of a custom control info's is the styles that the control supports. These informations are passed in two fields of info structure:
INT cStyleFlags; // Entries in the following style table.
LPCCSTYLEFLAG aStyleFlags; // Points to style flag table.
You have prebuild the array of styles to have it ready to pass:
CCSTYLEFLAG aSpincubeStyleFlags[] = { { SS_ASTYLE, 0, TEXT("SS_ASTYLE") },
{ SS_ANOTHERSTYLE, 0, TEXT("SS_ANOTHERSTYLE") } };
The info structures contains also two procedures, one to set styles of the control and the other to adjust control window dimension according to the text to show.
The first allows to change in the dialog editor the properties (styles) of the control, the other calculates the dimensions taking into account graphical elements of your custom control. Of course these can be NULL if you don't need them.
This is the MS definition and description of them:
/*
* The SizeToText function prototype. This will be called if the user
* requests that the custom control be sized to fit it's text. It
* should use the specified styles, text and font to determine how
* large the control must be to accommodate the text, then return this
* value in pixels. The value of -1 should be returned if an error
* occurs.
*/
typedef INT (CALLBACK* LPFNCCSIZETOTEXT)(DWORD flStyle, DWORD flExtStyle,HFONT hfont, LPSTR pszText);
/*
* The Style function prototype. This will be called when the user
* wants to edit the styles of a custom control. It should display a
* dialog to edit the styles, update the styles in the pccs structure,
* then return TRUE for success. If an error occurs or the user
* cancels the dialog, FALSE should be returned.
*/
typedef BOOL (CALLBACK* LPFNCCSTYLE)(HWND hwndParent, LPCCSTYLEA pccs);
Now on the PellesC IDE side
PellesC custom control management is available only when a dialog is under editing
, so you have to open a dialog to see the menu entry 'Dialog'. Here you have three choises:
'Open custom control', 'Remove Custom control', 'New Custom control'.
The first allows you to load a custom control DLL, the second allows to remove an already loaded control and with the last you can manually define a custom control (basically you give some info normally contained in the 'acci' structure as class name, flags, etc. No helper functions will be available, nor preview).
Once you loaded a custom control DLL you can have preview and double clicking on styles setting of control properties will open the custom control style editing function.
To verify this pratically I attach the PellesC port of the well known MS sample 'SpinCube' that you can still find in Win7 SDK.
Compile the entire workspace (project->Rebuild Workspace), then open a dialog somewhere, choose 'Open custom control', select the 'SpinCube.dll' and load it.
Now selecting 'SpinTest' as active project you can open dialogs, preview them and change styles!
I'm sure it's not exhaustive (and even not very clear ?
), but if you still have questions .... I'll try to answer.
P.S. BORLAND added some other custom functions to interact with its IDE. We don't care about them...
EDIT: Modified project files for eventual library location problems.