什麼是控制台程式?看到就一目瞭然了。控制台應用程式是一個以cpl為尾碼的檔案,其實是個dll檔案(把項目產生的dll檔案尾碼改為cpl,或者從VS中修改配置直接生產cpl檔案)。部署控制台程式非常簡單,直接把生產的cpl檔案Copy到手機的Windows目錄下即可。當你點擊自己編寫的控制台程式的表徵圖時,ctlpnl.exe進程會載入Windows目錄下對應的cpl檔案。
其實系統內建的一些控制台程式被整合在cplmain.cpl中(但是像無線管理器等並不是cpl檔案,而是一個exe程式,這個可以從註冊表中找到設定,微軟這麼設計的原因是因為無線管理器在很多地方都是需要的。),所以如果你需要在你的程式中開啟這些面板的話會經常看到如下代碼:
SHELLEXECUTEINFO info; TCHAR szControlPanelCmdLine[ 200 ];swprintf( szControlPanelCmdLine, L//windows//cplmain.cpl,5); //參數5代表調用aboutinfo.cbSize = sizeof( info );info.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;info.lpVerb = NULL;info.lpFile = TEXT("ctlpnl.exe");info.lpParameters = szControlPanelCmdLine;info.lpDirectory = NULL;info.nShow = SW_SHOW;info.hInstApp = NULL;ShellExecuteEx( &info );
以下是更多對應關係:
ctlpnl.exe cplmain.cpl,1 - set password
ctlpnl.exe cplmain.cpl,2 - set ownerinfo
ctlpnl.exe cplmain.cpl,3 - battery status
ctlpnl.exe cplmain.cpl,4 - memory status
ctlpnl.exe cplmain.cpl,5 - about
ctlpnl.exe cplmain.cpl,7 - align
ctlpnl.exe cplmain.cpl,8 - keyboard settings
ctlpnl.exe cplmain.cpl,9 - sound
ctlpnl.exe cplmain.cpl,10 - remove programs
ctlpnl.exe cplmain.cpl,11 - start menu
ctlpnl.exe cplmain.cpl,12 - button assignments
ctlpnl.exe cplmain.cpl,13 - today screen
ctlpnl.exe cplmain.cpl,15 - beam settings
ctlpnl.exe cplmain.cpl,16 - clock
ctlpnl.exe cplmain.cpl,17 - network adapters
ctlpnl.exe cplmain.cpl,18 - regional settings
ctlpnl.exe cplmain.cpl,19 - connections
ctlpnl.exe cplmain.cpl,20 - phone settings
ctlpnl.exe cplmain.cpl,22 - manage certificates
ctlpnl.exe cplmain.cpl,23 – bluetooth
言歸正傳開始介紹cpl的編寫
cpl檔案中的回呼函數CPlApplet為ctlpnl.exe進程進入你的cpl的進入點(需要匯出,不管你在def檔案裡面,還是在函數前制定dllexport屬性),一個cpl可以支援多個applets,見下面的代碼中的注釋。
LONG CPlApplet( HWND hwndCPl, //Handle to the main window of the controlling application. UINT msg, //Message being sent to the Control Panel application. LPARAM lParam1, LPARAM lParam2);
msg有:
CPL_INIT
初始化,控制台應用程式此時做一些全域的初始化工作,如記憶體配置。
CPL_GETCOUNT
擷取控制台應用程式支援的dialog boxes個數。
CPL_NEWINQUIRE
查詢控制台應用程式的dialog boxes的資訊,資訊包含在lParam2參數中,使用(LPNEWCPLINFO) lParam2獲得指標。
typedef struct tagNEWCPLINFO { DWORD dwSize; DWORD dwFlags; DWORD dwHelpContext; LONG lData; HICON hIcon; //Handle to the icon that represents the dialog box. TCHAR szName[32]; //The name is intended to be displayed below the icon. TCHAR szInfo[64]; //The description is intended to be displayed when the icon for the dialog
box is selected. TCHAR szHelpFile[128]; //忽略。要想使用協助,處理WM_NOTIFY訊息,然後取
得“lppsn = (LPPSHNOTIFY) lParam;”判斷是否等於PSN_HELP,如果是即可調出協助文檔。} NEWCPLINFO;
CPL_IDNAME
獲得控制台應用程式的名稱,通過設定註冊表索引值[HKEY_LOCAL_MACHINE/ControlPanel/<ID name>]
可以改變應用位於控制台屬性頁面的位置,主索引值"Group"預設為dword類型1,也就是說當你不指定位置時,預設放在系統這個tab中。另外還有如下值可以選擇:
0
Personal
1 (default value) System
2 Connections
CPL_DBLCLK
當使用者雙擊控制台上的icon時,系統會發送這個訊息給你的控制面部應用程式,此時你可以彈出一個dialog box。處理完這個訊息之後返回0表示你成功處理這個訊息了(其它訊息也一樣),非0表示其它。
CPL_STOP
關閉控制面部應用程式之前那一刻發送這個訊息給你的控制台應用程式。
CPL_EXIT
釋放DLL檔案之前那一刻發送這個訊息給你的控制台應用程式。
//////////////////////////////////////////////////////////This is the entry point called by ctlpnl.exe// ////////////////////////////////////////////////////////extern "C"__declspec(dllexport)LONG WINAPI CPlApplet(HWND hwndCPL, UINT uMsg, LONG lParam1, LONG lParam2){static intiInitCount = 0;intiApplet; 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 dllcase CPL_GETCOUNT:// Return the number of applets we supportreturn (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 returningcase CPL_NEWINQUIRE:{LPNEWCPLINFOlpNewCPlInfo;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 otherwisecase CPL_DBLCLK:iApplet = (UINT)lParam1;if (!CreatePropertySheet(hwndCPL,iApplet))return 1;break;// Sent once per applet, before CPL_EXITcase CPL_STOP:break;// Sent once before the dll is unloadedcase CPL_EXIT:iInitCount--;if (!iInitCount)TermApplet();break;default:break; } return 0;}
更詳細的代碼請見例子/Samples/PocketPC/CPP/win32/myBackLight,或者點這裡下載。
關於任何調試cpl代碼,請參照下面的文章。
作者: 王克偉
出處: http://wangkewei.cnblogs.com/
著作權聲明: 本文的著作權歸作者與部落格園共有。轉載時須註明本文的詳細連結,否則作者將保留追究其法律責任的權利。