技术开发 频道

Windows Mobile控制面板程序

 【IT168技术文档】

 什么是控制面板程序?看到下图就一目了然了。控制面板应用程序是一个以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代表调用about

 info.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 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;

 }

 更详细的代码请见例子\Samples\PocketPC\CPP\win32\myBackLight。

查看原文地址

 

0
相关文章