This section describes how you can add an application to the Control Panel either as a stand-alone application, or as an extension of another application.
The code examples are part of a complete sample application, Sysinfo.dsp, included in the SDK. Sysinfo.dsp creates a display-only Control Panel application that provides information about system memory.
In Sysinfo.dsp, the three .cpp files are:
C++ files |
Description |
Syssink.cpp | Implements the application message sink |
Sysapp.cpp | Implements the application CSysInfoApp class |
Sysmain.cpp | Provides the entry point into the application |
Design your application install program to copy your .cpl file into the Windows directory.
The following table show the messages the application callback function must process.
Message |
Description |
CPL_INIT | Sent to a Control Panel application to prompt it to perform global initialization, especially memory allocation. Returns 1 when it succeeds. |
CPL_GETCOUNT | Sent to a Control Panel application to retrieve the number of applications supported by the application. Returns the number of applications. |
CPL_NEWINQUIRE | Sent to a Control Panel application to request information about a dialog box that the application supports |
CPL_APCINQUIRE | Requests data from the application |
CPL_DBLCLK | Sent to a Control Panel application when the user double-clicks an icon in the Control Panel |
CPL_STOP | Sent once for each application when the application that controls the Control Panel closes |
CPL_EXIT | Sent once to a Control Panel application before the controlling application releases the DLL that contains the application |
The following code example shows how to create a message sink that handles VK_ESCAPE messages.
STDMETHODIMP
CSysInfoSink::HandleKeyPress(IDispatch *pdispControl, long lKeyDown)
{
switch(lKeyDown)
{
case VK_ESCAPE:
// Send a quit message to the current thread.
PostThreadMessage(GetCurrentThreadId(), WM_QUIT, 0, 0);
return S_OK; // Returns S_OK if message should stop here
}
return S_FALSE; // Returns S_FALSE, if the message should continue
// down the message path
}
The following code example shows how to create a callback function that processes Control Panel messages for Sysinfo.dsp.
LONG CALLBACK CPlApplication(HWND hwndCPL, UINT uMsg, LONG lParam1, LONG
lParam2)
{
DEBUGMSG(ZONE_FUNCTION,(TEXT("+CPlApplication(0x%x, 0x%x, 0x%x,
0x%x)\r\n"), hwndCPL, uMsg, lParam1, lParam2));
int iStringLen;
NEWCPLINFO* pCPLInfo;
APCCPLINFO* pAPCInfo;
switch (uMsg)
{
case CPL_INIT: // The first message received from
// Control Panel.exe is sent once.
return TRUE; // Return success
case CPL_GETCOUNT: // The second message is sent once.
return 1; // Only one application is in this DLL.
case CPL_NEWINQUIRE: // Query for information on the
// application.
pCPLInfo = (NEWCPLINFO*) lParam2; // Where to
// put inquiry
// information
memset(pCPLInfo, NULL, sizeof(NEWCPLINFO)); // Clear out
// inquiry
// structure
// Fill NEWCPLINFO with required information
pCPLInfo->dwSize = (DWORD) sizeof(NEWCPLINFO);
// The display cpl supports a faceplate, but not a VGA screen.
pCPLInfo->dwFlags = CPL_DISPLAY_FACEPLATE | CPL_DISPLAY_NOVGA;
// Load the icon that Control Panel uses.
pCPLInfo->hIcon = LoadIcon(g_hInst,
(LPWSTR)MAKEINTRESOURCE(ICON_APP_SHELL));
// Load the application name into NEWCPLINFO.szName
// with a maximum of 32 characters.
iStringLen = 32;
LoadString(g_hInst, STR_APP_SHELL_NAME, pCPLInfo->szName,
iStringLen );
if( pCPLInfo->hIcon == NULL || pCPLInfo->szName == NULL )
{
DEBUGCHK(0);
return E_FAIL; //Return Error.
}
return NOERROR;
case CPL_APCINQUIRE:
pAPCInfo = (APCCPLINFO*) lParam2;
memset(pAPCInfo, NULL, sizeof(APCCPLINFO));
// Fill APCINQUIRE with the required data.
pAPCInfo->dwSize = (DWORD) sizeof(APCCPLINFO);
// Load the application name into APCCPLINFO.szTTSName with a
// maximum of 32 characters.
iStringLen = 32;
LoadString(g_hInst, STR_APP_SHELL_NAME, pAPCInfo->szTTSName,
iStringLen );
return NOERROR;
/***********************************************************************
*CPL_DBLCLK message
* This application should act just as it would in a WinMain.
* Create a message loop, a Forms Manager, a form, and so on.
----------------------------------------------------------------------*/
case CPL_DBLCLK:
MSG msg;
// Create a new application class instance.
g_pApp = new CSysInfoApp(g_hInst);
if( g_pApp == NULL )
{
DEBUGCHK(0);
return FALSE;
}
if(FAILED(g_pApp->Init()))
{
DEBUGCHK(0);
delete g_pApp;
return FALSE;
}
// Start a message loop.
while (GetMessage(&msg, NULL, 0, 0))
{
if (msg.hwnd)
{
DispatchMessage(&msg);
}
}
delete g_pApp;
return TRUE;
case CPL_STOP: // Sent once per application before
// CPL_EXIT
break;
case CPL_EXIT: // Sent once before FreeLibrary called
break;
default:
break;
}
DEBUGMSG(ZONE_FUNCTION,(TEXT("-CPlApplication(0x%x)\r\n")));
return TRUE;
}