WINCE6.0在控制面板添加控制面板应用程序
?********************************LoongEmbedded********************************
作者:LoongEmbedded(kandi)
時間:2011.8.25
類別:WINCE 系統開發
********************************LoongEmbedded********************************
1.??? WINCE控制面板架構
?
WINCE系統的控制面板提供的應用是基于windows桌面系統下應用的小子集,在WINCE系統中,控制面板系統由三部分組成,分別是Ctlpnl.exe、Control.exe和一些控制面板文件(.cpl)。Ctlpnl.exe和Control.exe相應地被操作系統用于控制控制面板文件夾顯示和機構,這兩部分構成控制面板系統架構的最根本部分,而那些.cpl文件對應于控制面板功能的應用。如果要創建子集的控制面板應用,我們必須創建一個.cpl文件,這個文件導出適合于Control.exe建立的架構的回調函數
?
一個控制面板應用程序實際是一個dll,但它的擴展名是.cpl的文件,這個文件導出回調函數CPlApplet來處理控制面板系統發送過來的CPL_INIT、CPL_GETCOUNT、CPL_NEWINQURE、CPL_STOP|和CPL_EXIT消息,在處理這些消息的時候可以只直接調用某個.exe來執行相應的應用,也可以是直接的處理。當用戶打開控制面板的時候,OS通過搜索位于“\Windows”目錄下面的.cpl文件來列舉出控制面板系統下的控制面板應用,比如我們當前的系統中有下面的.cpl:
圖1
我雙擊“控制面板”圖標進入控制面板的時候,輸出下面的出錯提示信息:
CPL: Failed to load '\Windows\system.cpl'
說明加載system.cpl失敗,而我在系統中添加自己的應用HelloCPL.cpl的系統中,在雙擊“控制面板”的時候,也相應的提示下面的信息:
CPL: Failed to load '\Windows\HelloCPL.cpl'
后來在HelloCPL.文件中加入下面的內容才成功加載HelloCPL.cpl的
LIBRARY?????? HelloCPL
EXPORTS
??? CPlApplet
可以在WINCE600的目錄下沒有找到生成system.cpl的地方,只在下面的目錄中
\WINCE600\PUBLIC\DATASYNC\OAK\CTLPANEL\SYSTEM找到生成systemcpl.cpl的源代碼所在地方,但其導出函數為KillAllApps,并且為空函數,所以在控制面板下是看不到此控制面板應用程序對應的圖標。
?
CTLPNL文件夾中有九個文件夾,分別對應不同的CPL文件:
ADVBACKLIGHT:高級背光燈管理。
BTHPNL:藍牙。
CONNPNL:撥號網絡。
CONTROL:主控制臺,我們在explorer中看到的"控制面板"應該就是這個。
CPLMAIN:會生成cplmain.cpl,控制面板的大多數選項均源自于此。
CTLPNL:和CONTROL相關聯的
DMPNL:對應設備管理器。
INTL2:區域和語言設置。
STGUI:存儲器管理。
圖2
2.??? 控制面板應用程序的入口和導出函數
2.1?? 入口函數DllMain
因為.cpl文件實際就是dll,而dll的入口函數是DllMain,所以控制面板應用程序的入口函數是DllMain也就很自然的事情了。在進程和現場被初始化和終止的時候,系統會調用這個函數,或者在調用LoadLibrary()和FreeLibrary()函數的時候會調用這個入口函數。
?
DllMai函數在這里的作用主要是保存好傳遞進來的指向DLL的句柄,以便后面使用。
2.2?? .def函數要導出的回調函數CPlApplet
LONG CPlApplet(HWND hwndCPl, UINT msg, LPARAM lParam1, LPARAM lParam2)
hwndCPl:控制面板窗口的句柄
msg:發給控制面應用程序的消息?
WinCE中所支持的控制面板消息如下:
CPL_INIT:被首次加載的時候會收到該消息,也是第一個消息,控制面板應用程序接收到該消息后會立刻執行全局變量的初始化,尤其是內存的分配的動作也在這里執行。
CPL_GETCOUNT:第二個被收到的消息,該消息用于獲得該控制面板應用程序中的組件數,因為.cpl文件中可能包含多個Applet程序,比如cplmain.cpl中就有十幾個Applent程序,見圖2。
CPL_NEWINQUIRE:查詢當前控制面板程序支持的對話框(dialog box)信息,如果該.cpl中包含多個對話框,那么lParam1表示對話框號,lParam2是一個指向NEWCPLINFO結構的指針,描述的是一個對話框的相關信息,見圖2,connpnl.cpl中有14個組件,比如“筆針”就是其支持的一個對話框,我們在雙擊“筆針”圖標的時候,串口輸出下面的信息:
CTLPNL: cmdline=\Windows\cplmain.cpl,9
--->>>CTLPNL: CPL='\Windows\cplmain.cpl' icon=9 tab=0
說明“筆針”是cplmain.cpl支持的第9個對話框,而雙擊圖2的“顯示分辨率”圖標的時候,輸出下面的串口信息:
CTLPNL: cmdline=\Windows\HelloCPL.cpl,0
--->>>CTLPNL: CPL='\Windows\HelloCPL.cpl' icon=0 tab=0
因為添加的控制面板應用程序HelloCPL.cpl只支持一個對話框,上面的0表示第0個對話框。lParam2指向的NEWCPLINFO結構體定義如下:
typedef struct tagNEWCPLINFO {
? DWORD dwSize;
? DWORD dwFlags;
? DWORD dwHelpContext;
? LONG lData;
? HICON hIcon;
? TCHAR szName[32];
? TCHAR szInfo[64];
? TCHAR szHelpFile[128];
} NEWCPLINFO;
?
dwSize:該結構的信息
dwFlags:忽略
dwHelpContext:忽略
lData:傳給組建程序的數據
hIcon:顯示在控制面板中的圖標的句柄,見圖2,就是這些圖標信息。
szName:顯示在控制面板中的組件的名字,比如“筆針”
szInfo:顯示在控制面板中的描述信息
szHelpFile:忽略
?
CPL_DBCLK:用戶在控制面板界面中雙擊某個應用時,會收到該消息,在該消息中執行對應的應用程序。如果包含多個對話框,那么lParam1表示對話框號,lParam2為傳給應用程序的數據。
CPL_STOP:關閉控制面應用程序時,收到該消息,用于釋放資源。如果包含多個對話框,那么lParam1表示對話框號,lParam2為傳給應用程序的數據。
CPL_EXIT:在CPL_STOP消息之后,控制面板釋放該應用程序時,收到該消息。
?
lParam1:消息參數1
lParam2:消息參數2
?
?
3.??? 在WINCE控制面板中添加控制面板應用程序的步驟
?
3.1?? 創建一個添加一個應用程序
在創建應用程序之前,我們首先要有一個WINCE的系統工程,在打開這個工程的基礎上我們創建一個應用程序子工程,在File->New->Subproject中選擇WCE Application,這里我們選擇Hello World應用程序,創建這個應用程序的目的為后面創建的控制面板應用程序調用的。
3.2?? 創建控制面板應用程序的CPL工程
點擊File->New->Subproject,然后選擇WCE Dynamic-Link Library,工程名為HelloCPL。
圖3
然后點擊Next,在Auto-generated subproject files頁面中選擇A Dll that exports some symbols。
圖4
然后點擊Finish完成,經過前面兩部后我們可以看到:
圖5
?
3.3?? 修改DllMain和添加CPlApplet函數
?
#include "Cpl.h" //因為添加CPlApplet函數,此函數又對CPL_XXX消息的處理
#include "resource.h"// IDI_HELLO_CPL、IDS_HELLO_KANDI和IDS_HELLO_SANDI的定義在這里
?
#define lengthof(exp) ((sizeof((exp)))/sizeof((*(exp))))
?
HMODULE g_hModule = NULL;?? // Handle to the DLL.
?
BOOL APIENTRY DllMain( HANDLE hModule,
?????????????????????? DWORD? ul_reason_for_call,
?????????????????????? LPVOID lpReserved
???????????????????? )
{
??? switch (ul_reason_for_call)
??? {
??????? case DLL_PROCESS_ATTACH:
?????????? {
?????????? g_hModule = (HMODULE) hModule;
?????????? }
?
??????? case DLL_THREAD_ATTACH:
??????? case DLL_THREAD_DETACH:
??????? case DLL_PROCESS_DETACH:
??????????? break;
??? }
??? return TRUE;
}
?
?
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// The entry point to the Control Panel application.
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
extern "C"? LONG CALLBACK CPlApplet(HWND hwndCPL,
????????????????? UINT message, LPARAM lParam1, LPARAM lParam2)
{
? switch (message)
? {
??? case CPL_INIT:
????? // Perform global initializations, especially memory
?? ???// allocations, here.
????? // Return 1 for success or 0 for failure.
????? // Control Panel does not load if failure is returned.
?????? //RETAILMSG(1, (TEXT("kandi helloworld test 1111\r\n")));
????? return 1;
?
??? case CPL_GETCOUNT:
????? // The number of actions supported by this Control
????? // Panel application.
?????? //RETAILMSG(1, (TEXT("kandi helloworld test 2222\r\n")));
????? return 1;
?
??? case CPL_NEWINQUIRE:
????? // This message is sent once for each dialog box, as
????? // determined by the value returned from CPL_GETCOUNT.
????? // lParam1 is the 0-based index of the dialog box.
????? // lParam2 is a pointer to the NEWCPLINFO structure.
??? {
????? ASSERT(0 == lParam1);
????? ASSERT(lParam2);
?
????? NEWCPLINFO* lpNewCplInfo = (NEWCPLINFO *) lParam2;
??? ?// Release((TEXT("kandi test 1111\r\n")));
??? ?// RETAILMSG(1, (TEXT("kandi helloworld test 3333\r\n")));
???? if (lpNewCplInfo)
????? {
???????? lpNewCplInfo->dwSize = sizeof(NEWCPLINFO);
???????? lpNewCplInfo->dwFlags = 0;
???????? lpNewCplInfo->dwHelpContext = 0;
???????? lpNewCplInfo->lData = IDI_HELLO_CPL;
?????????? //RETAILMSG(1, (TEXT("kandi helloworld test 44444\r\n")));
???????? // The large icon for this application. Do not free this
???????? // HICON; it is freed by the Control Panel infrastructure.
???????? lpNewCplInfo->hIcon = LoadIcon(g_hModule,
????????????????????????????????? MAKEINTRESOURCE(IDI_HELLO_CPL));
?
????????? LoadString(g_hModule, IDS_HELLO_KANDI, lpNewCplInfo->szName,
???????????????????? lengthof(lpNewCplInfo->szName));
????????? LoadString(g_hModule, IDS_HELLO_SANDI, lpNewCplInfo->szInfo,
???????????????????? lengthof(lpNewCplInfo->szInfo));
????????? _tcscpy(lpNewCplInfo->szHelpFile, _T(""));
????????? return 0;
????? }
??? return 1;? // Nonzero value means CPlApplet failed.
??? }
?
?
??? case CPL_DBLCLK:
??? {
????? // The user has double-clicked the icon for the
????? // dialog box in lParam1 (zero-based).
?????? //RETAILMSG(1, (TEXT("kandi helloworld test 5555\r\n")));
????? PROCESS_INFORMATION pi = {0};
????? if (CreateProcess(_T("\\Windows\\HelloWorld.exe"), NULL, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi))
????? {
??????? CloseHandle(pi.hThread);
??????? CloseHandle(pi.hProcess);
??????? return 0;
????? }
????? return 1;???? // CPlApplet failed.
??? }
?
??? case CPL_STOP:
????? // Called once for each dialog box. Used for cleanup.
?????? //RETAILMSG(1, (TEXT("kandi helloworld test 66666\r\n")));
??? case CPL_EXIT:
????? // Called only once for the application. Used for cleanup.
?????? //RETAILMSG(1, (TEXT("kandi helloworld test 77777\r\n")));
??? default:
????? return 0;
? }
?
? return 1;? // CPlApplet failed.
}? // CPlApple
?
3.4?? 為CPlApplet函數處理CPL_NEWINQUIRE時添加其所需要加載的圖標和字符串
在這里圖標和字符串分別對應ID: IDI_HELLO_CPL、IDS_HELLO_KANDI和IDS_HELLO_SANDI的定義,添加的步驟如下:
1)??? 為CPL工程添加rc資源文件
右擊圖5的HelloCPL->source files,選擇Add->New Item,見下圖:
圖6
點擊Add后,雙擊HelloCPL->source files->HelloCPL.rc,見下圖
圖7
3.5?? 為rc資源文件添加ICO圖標和字符串
右擊圖7的HelloCPL.rc,選擇Add Resource,彈出下面的對話框。
圖8
具體就不描述了。
3.6?? 修改HelloCPL工程配置
1)??? 把HelloCPL.bib文件的內容修改為
MODULES
HelloCPL.cpl? $(_FLATRELEASEDIR)\HelloCPL.cpl?????????????? NK
?
2)??? 右擊HelloCPL工程,選擇Properities,選擇General頁面,在Custom Variable
項中添加變量,變量名字為CPL,值為1,這樣做的目的就是強制生成HelloCPL應用程序的擴展名為.cpl,而不是dll。然后選擇C/C++頁面,確認Additional Macro Definitions的值為$(CDEFINES) -DHelloCPL_EXPORTS。設置DLL Entry Point項為DllMain,因為HelloCPL.cpl的入口函數就是DllMain。在Include Directories項中添加路徑$(_PROJECTROOT)/cesysgen/oak/inc。
?
3)??? 在HelloCPL.def文件中添加下面的內容
LIBRARY?????? HelloCPL
?
EXPORTS
??? CPlApplet
目的是到處接口函數CPlApplet,加入沒有添加這些內容,將無法有效加載HelloCPL.cpl。
?
3.7?? 分別單獨編譯HelloWorld工程和HelloCPL工程,分別生成HelloWorld.exe和
HelloCPL.cpl,然后會生成新的NK.bin,把NK.bin燒錄到WINCE設備中,雙擊控制面板后可以看到下圖:
圖9
雙擊HelloCPL.cpl對應的圖標,可以看到下圖:
圖10
這就是HelloWorld.exe應用程序顯示的界面,是由HelloCPL.cpl的CPlApplet函數在處理雙擊消息的時候調用的。
?
總結
以上是生活随笔為你收集整理的WINCE6.0在控制面板添加控制面板应用程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WINCE6.0下开始菜单的“挂起(su
- 下一篇: ubuntun_11.04安装