The WM SDK ships with a little sample project that demonstrates how to create your own custom control panel applet. Basically, each icon is a DLL that is loaded into the Shell32 process, which looks for an entry point called CPlApplet. The sample applet is called MyBacklight. Below is the CPlApplet function which could serve for many control panel applets without modification. The framework talks to this entry point through the messages CPL_INIT, CPL_GET_COUNT, CPL_NEW_INQUIRE, CPL_DBLCLK, etc., which allow you to define the applet’s behavior and appearance. Often these applets are just fancy front-ends on a bunch of registry settings. Now if only I could think of something that needs configuring…
extern “C”
__declspec(dllexport)
LONG WINAPI CPlApplet(HWND hwndCPL, UINT uMsg, LONG lParam1, LONG lParam2)
{
static int iInitCount = 0;
int iApplet;
switch (uMsg)
{
// First message sent. It is sent only once to
// allow the dll to initialize it’s applet(s)
case CPL_INIT:
if (!iInitCount)
{
if (!InitApplet(hwndCPL))
return FALSE;
}
iInitCount++;
return TRUE;
// Second message sent. Return the count of applets supported
// by this dll
case CPL_GETCOUNT:
// Return the number of applets we support
return (LONG)((sizeof(SystemApplets))/(sizeof(SystemApplets[0])));
// Third message sent. Sent once for each applet supported by this dll.
// The lParam1 contains the number that indicates which applet this is
// for, from 0 to 1 less than the count of applets.
// lParam2 is a NEWCPLINFO that should be filled with information about
// this applet before returning
case CPL_NEWINQUIRE:
{
LPNEWCPLINFO lpNewCPlInfo;
lpNewCPlInfo = (LPNEWCPLINFO)lParam2;
iApplet = (int)lParam1;
lpNewCPlInfo->dwSize = (DWORD)sizeof(NEWCPLINFO);
lpNewCPlInfo->dwFlags = 0;
lpNewCPlInfo->dwHelpContext = 0;
lpNewCPlInfo->lData = SystemApplets[iApplet].icon;
lpNewCPlInfo->hIcon = LoadIcon(g_hInstance,(LPCTSTR)MAKEINTRESOURCE(SystemApplets[iApplet].icon));
lpNewCPlInfo->szHelpFile[0] = ‘\0′;
LoadString(g_hInstance,SystemApplets[iApplet].namestring,lpNewCPlInfo->szName,32);
LoadString(g_hInstance,SystemApplets[iApplet].descstring,lpNewCPlInfo->szInfo,64);
}
break;
// This is sent whenever the user clicks an icon in Settings for one of
// the applets supported by this dll. lParam1 contains the number indicating
// which applet. Return 0 if applet successfully launched, non-zero otherwise
case CPL_DBLCLK:
iApplet = (UINT)lParam1;
if (!CreatePropertySheet(hwndCPL,iApplet))
return 1;
break;
// Sent once per applet, before CPL_EXIT
case CPL_STOP:
break;
// Sent once before the dll is unloaded
case CPL_EXIT:
iInitCount–;
if (!iInitCount)
TermApplet();
break;
default:
break;
}
return 0;
}