MSDN Home > MSDN Library > Win32 and COM Development > User Interface > Windows Shell > Shell Programmer's Guide > Advanced Shell Techniques |
Control Panel items are special-purpose dynamic-link libraries (DLLs) that let users configure the environment of Microsoft Windows. This section describes Control Panel items and explains the functions and messages they use and process to complete their work.
About Control Panel ItemsAlthough Windows provides a number of standard Control Panel items, you can create additional items that let users examine and modify the settings and operational modes of specific hardware and software. Item Responsibilities and OperationThe primary responsibility of any Control Panel item is to display a window (typically a dialog box or property sheet) and to carry out any tasks specified by the user. Despite this responsibility, Control Panel items do not provide menus or other direct means for users to access their dialog boxes. Instead, these items operate under the control of another application and launch their subprograms only when requested by the controlling application. Control Panel items, such as the Mouse item, are usually controlled by a Windows system utility specifically designed to give users access to these items. However, any application can load and manage Control Panel items as long as the controlling application sends messages and processes return values in a way recognized by Control Panel items. Most Control Panel items display and manage a single subprogram, giving the user control of the settings and operational modes of a single system component. However, any given Control Panel item can provide any number of subprograms to control any number of system components. To distinguish between subprograms, a Control Panel item typically supplies the controlling application with a unique icon for each subprogram. The controlling application displays these icons, and the user can choose a subprogram by choosing the corresponding icon. Item Entry-Point FunctionEvery Control Panel item must export the standard entry-point function, CPlApplet. This function receives requests in the form of Control Panel (CPL) messages and then carries out the requested work—initializing the item, displaying and managing the dialog box(es), and closing the item. When the controlling application first loads the Control Panel item, it retrieves the address of the CPlApplet function and subsequently uses the address to call the function and pass it messages. The controlling application might send the following messages.
Message ProcessingThe CPlApplet callback function processes all messages sent to a Control Panel item by a controlling application. Messages sent to the function should be in a specific order. By the same token, the application requires the messages to be processed in a specific way. First, the CPlApplet function receives the CPL_INIT message when the controlling application first loads the Control Panel item. The function should carry out any initialization, such as allocating memory, and return nonzero. If CPlApplet cannot complete the initialization, it must return zero, directing the controlling application to terminate communication and release the DLL. Next, if the CPL_INIT message succeeded, the controlling application sends the CPL_GETCOUNT message. The function must then return the number of subprograms supported by the Control Panel item. The CPlApplet function then receives one CPL_INQUIRE message and one CPL_NEWINQUIRE message for each subprogram supported by the Control Panel item. The function fills in a CPLINFO or NEWCPLINFO structure with information about your item, such as its name, icon, and a descriptive string. Most applications should process the CPL_INQUIRE message and ignore the CPL_NEWINQUIRE message. The CPL_INQUIRE message provides information in a form that the controlling application can cache, resulting in much better performance. The CPL_NEWINQUIRE message is useful only if you need to change your item's icon or display strings based on the state of the computer. The CPlApplet function next receives a CPL_DBLCLK message as a notification that the user has chosen the icon representing the subprogram. The function might receive this message any number of times. The message includes the subprogram identifier and the value contained in the uMsg parameter. The function should display the corresponding dialog box and process subsequent user input. Before the controlling application terminates, CPlApplet receives the CPL_STOP message once for each subprogram supported by the Control Panel item. The message includes the identifier for the subprogram and the uMsg value. The function should free any memory that it allocated for the specified dialog box. After the last CPL_STOP message, CPlApplet receives a CPL_EXIT message. The function should free all remaining allocated memory and unregister any private window classes that it might have registered. Immediately after the function returns from this message, the controlling application releases the Control Panel item by calling the FreeLibrary function. Item SetupEvery Control Panel item is a dynamic-link library. However, the DLL file must have a .cpl file name extension. For Windows 2000 and later systems, new Control Panel items should be installed in the associated application's folder under the Program Files folder. The path of the DLL must be registered in one of two ways:
The following two examples register the MyCplApp Control Panel item. The DLL is named MyCpl.cpl and is located in the MyCorp\MyApp application directory. The first registry entry illustrates per-computer registration, and the second illustrates per-user registration.
For systems prior to Windows 2000, new Control Panel items must be set up in one of the following ways:
Creating Control Panel ItemsAlthough a Control Panel item can support more than one subprogram, it processes all requests through the single CPlApplet function. In the following example, the Control Panel item supports three subprograms that let the user set preferences for a component stereo system attached to the computer. The example uses an application-defined StereoSubProgs array that contains three structures, each corresponding to one of the subprograms. Each structure contains all the information required by the CPL_INQUIRE message as well as the dialog box template and dialog box procedure required by the CPL_DBLCLK message. The code demonstrates how to fill the structures in the StereoSubProgs array. #define NUM_SUBPROGS 3 typedef struct tagSubProg { int icon; // icon resource identifier int namestring; // name-string resource identifier int descstring; // description-string resource identifier int dlgtemplate; // dialog box template resource identifier DLGPROC dlgfn; // dialog box procedure } SUBPROG; SUBPROG StereoSubProgs[NUM_SUBPROGS] = { {AMP_ICON, AMP_NAME, AMP_DESC, AMP_DLG, AmpDlgProc,}, {TUNER_ICON, TUNER_NAME, TUNER_DESC, TUNER_DLG, TunerDlgProc,}, {TAPE_ICON, TAPE_NAME, TAPE_DESC, TAPE_DLG, TapeDlgProc,}, }; HANDLE hinst = NULL; HWND hwndCPL; // handle to Control Panel window UINT uMsg; // message LPARAM lParam1; // first message parameter LPARAM lParam2; // second message parameter LONG CALLBACK CPlApplet(hwndCPL, uMsg, lParam1, lParam2) { int i; LPCPLINFO lpCPlInfo; i = (int) lParam1; switch (uMsg) { case CPL_INIT: // first message, sent once hinst = GetModuleHandle("ecp.cpl"); return TRUE; case CPL_GETCOUNT: // second message, sent once return NUM_SUBPROGS; break; case CPL_INQUIRE: // third message, sent once per item lpCPlInfo = (LPCPLINFO) lParam2; lpCPlInfo->lData = 0; lpCPlInfo->idIcon = StereoSubProgs[i].icon; lpCPlInfo->idName = StereoSubProgs[i].namestring; lpCPlInfo->idInfo = StereoSubProgs[i].descstring; break; case CPL_DBLCLK: // item icon double-clicked DialogBox(hinst, MAKEINTRESOURCE(StereoSubProgs[i].dlgtemplate), hwndCPL, StereoSubProgs[i].dlgfn); break; case CPL_STOP: // sent once per item before CPL_EXIT break; case CPL_EXIT: // sent once before FreeLibrary is called break; default: break; } return 0; } Executing Control Panel ItemsThere are two ways to start a Control Panel item:
An application can open the Control Panel programmatically using the WinExec function. WinExec("c:\windows\system32\control.exe", SW_NORMAL); The following example shows how an application can start the Control Panel item named MyCpl.cpl by using the WinExec function. WinExec("c:\windows\system32\control.exe MyCpl.cpl", SW_NORMAL); When Control Panel starts, it immediately executes the Control Panel item MyCpl.cpl. After the user finishes using the item and closes it, Control Panel ends. When you use the WinExec function, the system can recognize special Control Panel commands.
For Windows 2000 and later systems:
Extending System Control Panel ItemsSome of the system items found in the Control Panel are extensible. To install a Control Panel extension, register your Shell extension as follows, where name is the predefined name of the system item (see table below).
The Add or Remove Programs item in Control Panel is not a property sheet and therefore cannot be extended by the methods discussed here. Instead, its content is obtained from application publishers. For more information on adding content to Add or Remove Programs, see IAppPublisher, IEnumPublishedApps, and IPublishedApp. Assigning Control Panel CategoriesAs of Windows XP, Control Panel supports categorization of Control Panel items. Windows XP provides support for third parties to add their Control Panel items to existing categories. However, third parties cannot add custom categories at this time. Registering a Control Panel Item in a CategoryTo register a Control Panel item in a particular category, add a REG_DWORD entry, indicating the desired category, to the registry. The following table lists the possible categories and their category IDs.
The following example registry entry assigns the application MyCPL.cpl to the category Appearance and Themes. Details of the entry are discussed in detail in the following sections.
The registry key {305CA226-D286-468e-B848-2B2E8E697B74} 2 is the container for all category entries. That key represents SCID_CONTROLPANELCATEGORY, and is composed of PSGUID_CONTROLPANEL and PID_CONTROLPANEL_CATEGORY, both defined in Shlguid.h. The Name entry is the full path of your .cpl file, using environment variables if desired. The Data entry for that Name should be one of the category IDs listed earlier, stored as a REG_DWORD. In Windows XP SP2 or later, you can also register a Control Panel item using a string (REG_SZ) rather than a REG_DWORD. The string simply contains the number of the category, in either decimal or hexadecimal format. The following example registry entry assigns the application MyCPL.cpl to the category Appearance and Themes using a string.
Registering a Control Panel Item to Multiple CategoriesAs of Windows XP SP2 or later, you can register a Control Panel item in more than one category. To do so, use a string containing a list of the category IDs, separated by commas, and in either decimal or hexadecimal format. The following example registry entry assigns the application Firewall.cpl to both the Network and Internet Options and Security Center categories, using decimal values.
The following example registry entry assigns the application Firewall.cpl to both the Network and Internet Options and Security Center categories, using hexadecimal values.
The categories Add or Remove Programs and User Accounts work somewhat differently from other categories in Control Panel. When one or more items are added to one of these two categories, the associated link in Control Panel opens a category page. The registered items appear in the lower portion of the page under the heading "or Pick a Control Panel icon". When no items are registered for one of these categories, the associated link in Control Panel directly invokes the standard Windows item for that category. The Security Center category, available in only Windows XP SP2 or later, is also somewhat non-standard. Clicking this category opens the Security Center page in a new window. Items registered for Security Center appear in the lower portion of that page under the heading Manage security settings for:. Clicking an icon brings up its individual Control Panel item. The parent key name Extended Property derives from the fact that you can access this property from script through the ExtendedProperty method on the ShellFolderItem object. The following sample Microsoft JScript code enumerates the Control Panel items and their category identifiers (IDs). var strSCID = "{305CA226-D286-468e-B848-2B2E8E697B74} 2"; var shell = new ActiveXObject("Shell.Application"); var cpls = shell.Namespace(3).Items(); // 3 is the ID for Control Panel for (i=0; i < cpls.Count; i++) { var fldrItem = cpls.Item(i); Document.write("The cpl " + fldrItem.Name + " belongs to category id " + ldrItem.ExtendedProperty(strSCID)); } For Control Panel items that are implemented as Shell namespace extensions—for example, fonts or scheduled tasks—specify the category ID in the registry under the CLSID entry. For example, the registry entry for the Administrative Tools folder is as follows:
In this case, you create a value named {305CA226-D286-468e-B848-2B2E8E697B74} 2, then store the category ID as a REG_DWORD as before. |