Windows 控制面板编程.docx
- 文档编号:10006351
- 上传时间:2023-02-07
- 格式:DOCX
- 页数:12
- 大小:390.72KB
Windows 控制面板编程.docx
《Windows 控制面板编程.docx》由会员分享,可在线阅读,更多相关《Windows 控制面板编程.docx(12页珍藏版)》请在冰豆网上搜索。
Windows控制面板编程
Windows 控制面板编程
一、 什么是控制面板
打开Windows的控制面板会看到类似的图像
图一
双击其中的一个图标,会显示对话框,让用户来完成相应的软硬件设置工作。
这就是我们看到的控制面板。
那么如何开发控制面板程序呢?
带着疑问在MSDN和google里搜索关键字“ControlPanel”,就会找到相关的技术文章。
这是我工作的方法:
借鉴已有的资源。
但实际情况是那样吗?
我们可以跟着MSDN的讲述来一步一步深入下去。
经过挖掘,发现并不是exe文件(WindowsVista下支持exe的控制面板应用程序,并且微软建议做成exe文件),而是有着cpl后缀名的文件,在windows->system32下可以找到这样的文件。
如果借助工具,DependencyWalkerforWin32(x86) 或dumpbin等就可以看到该文件导出了一些函数。
图二
多观察几个这样的文件,发现导出的函数虽有差异,但其中都有CPLApplet函数被导出。
这些特征与DLL的特征吻合。
去MSDN上查阅CPLApplet函数的说明证明我们的猜测是正确的。
可以说控制面板应该程序就是以CPL为后缀名并且一定要导出CPLApplet函数的dll文件。
对于具体的描述可以参考:
二、 明确几个概念
l 控制面板管理程序:
用于管理控制面板的程序,在桌面windows版本是CONTROL.EXE,在windowsCE版本是CTLPNL.EXE,它们负责管理控制面板里的控制面板条目。
简单的说,我们打开控制面板时,这些管理程序就在运行了。
只不过我们看到的是挂上了Shell外观而已(注:
这是我的猜测,还没有找到依据)。
l 控制面板条目(ControlPanelItem):
在控制面板里看到的每个图标所对应的就是一个控制面板条目。
l 控制面板应用程序(ControlPanelApplication):
就是最终看到的CPL文件,一个控制面板应用程序可以实现几个控制面板条目。
三、 控制面板应用程序的编写
编写控制面板应用程序,就是编写dll文件,在该文件中实现控制所需要的功能。
这就涉及到一个不得不说的函数,没有它就无法完成控制面板程序的实现。
该函数为CPLApplet。
下面就该函数的参数等知识做些介绍。
函数:
LONGCPLApplet(HWND hwndCPl,UINT msg,LPARAM lParam1,LPARAM lParam2)
函数CPLApplet是控制面板应用程序(ControlPanelapplication)的入口点,它被控制面板管理程序(control.exe 或Ctlpnl.exe)自动调用,它是个回调函数(Callback),注意:
CPL文件一定要把函数CPLApplet导出,这样控制面板才能找到程序的入口点。
当启动控制面板时,它会搜索Windows或System32或注册表的相应条目目录下的文件,并把以CPL作为扩展名的文件载入,它调用CPL文件的导出函数CPLApplet(),发送消息给该函数。
所以,控制面板应用程序要处理控制面板发送过来的消息,即在函数CPLApplet中进行处理,该函数没有默认的行为。
如果一个CPL文件中实现了多个控制面板程序,那么只会有一个CPLApplet函数,它负责所有的控制面板应用程序。
参数说明:
hwndCPl:
控制面板管理程序或称为控制面板的窗口句柄,即为control.exe的窗口句柄。
如果控制面板应用程序或其它窗口需要传递父窗口句柄,可以使用该参数。
Msg:
发送到控制面板应用程序的消息,由控制面板管理程序发送。
lParam1:
消息参数
lParam2:
消息参数
函数的返回值依据消息的不同而不同。
应用程序要使用该函数需要包含头文件:
cpl.h
消息名称
描述
CPL_INIT
控制面板应用程序收到的第一个消息,通常在此处理全局初始化和内存分配。
成功返回非0,否则返回0,此时控制面板管理程序终止和该应用程序的通信,并释放相应的CPL文件。
CPL_GETCOUNT
该消息紧接在CPL_INIT消息之后被发送,它返回控制面板管理程序所能看到该CPL文件中所包含的控制面板组件的数目,即该CPL文件可以出现在控制面板中的图标的数目。
CPL_INQUIRE
于CPL_GETCOUNT之后被发送,为指定的控制面板条目提供信息。
CPL_NEWINQUIRE
于CPL_GETCOUNT之后被发送,与消息CPL_INQUIRE完成的功能类似,只不过其实现要求TNewCPLInfo结构指针,所包含的资源不提供缓存,所以控制面板启动的较慢,一般不建议处理该消息,除非特别必要,如要根据一定的条件动态的改变控制面板条目的图标、字符串等。
CPL_DBLCLK
表明用户选定了一个控制面板条目,程序应该显示相应的对话框以便用户完成相应的任务。
成功返回0,否则,返回非0.
CPL_STOP
控制面板管理程序关闭时被发送,控制面板应用程序在此时处理内存释放等动作。
成功处理,返回0.
CPL_SELECT
目前不被使用。
只有Windows95 和MicrosoftWindowsNT4.0之前的系统使用。
CPL_STARTWPARMS
该消息与CPL_DBLCLK类似,但lParam2指向LPCTSTR,该消息在shell32.dllversion5.0 (Windows2000 ,WindowsMillenniumEdition(WindowsMe))及以后版本有效
CPL_EXIT
于CPL_STOP消息之后被发送,这是控制面板应用程序在释放资源的最后机会。
成功处理返回0.
CPL_INQUIRE:
lParam1是以0为起点的整数,它是该CPL文件中所包含的控制面板条目的索引,lParam2参数要求一个CPLINFO结构的指针,用来填充所需的图标、字符串等信息。
如果成功处理了该消息,应该返回0。
CPL_NEWINQUIRE:
该消息与CPL_INQUIRE都是CPL_GETCOUNT之后被发送的消息,但并没有明确的先后顺序。
所以程序里不要依赖它们的顺序来处理不同的事务。
编写控制面板应用程序的步骤:
1 选择适当的开发工具(如:
VisualStudio2008),建立DLL项目;
2 导出函数CPLApplet;
3 在函数CPLApplet的消息处理过程中完成你需要的工作;
一个简单的例子
开发工具:
MicrosoftVisualStudio2008
操作系统:
WindowsXPSP2
步骤:
1 新建Win32Project,工程名为CPLTest;
2 应用程序类型选择DLL(CPL文件本质上是DLL);
3 在项目中新增或导入一个图标文件和两个字符串资源,用于在控制面板管理程序中显示图标和提示;
在ResourceFiles 上右键选择Add->Resource,然后选择Icon或StringTable
以下为resource.h 的部分内容
#define IDI_ICON1 101//图标标识
#define IDS_STRING102 102//字符串tom
#define IDS_STRING103 103//字符串cui
4 在dllmain.cpp文件中增加函数的导出CPLApplet;
extern "C" __declspec(dllexport) LONG APIENTRY CPlApplet(HWND hwndCPL, UINT uMsg, LPARAM lParam1,LPARAM lParam2);
原则上可以按照上面的方式导出就可以了,但是请注意CPlApplet的调用方式是APIENTRY,通过这样方式导出的函数会被改名,通过多次实验也不可行。
你可能会上去掉APIENTRY,但这样编出来的CPL文件无法运行,查阅了相关文档,在WindowsMobileVersion5.0SDK的文档里指明了该函数的调用方式,windowsCE5.0 和WindowsShellandControls没有指明这种调用方式。
所以,只有加上APIENTRY。
现在的问题是如何导出该函数?
看来要通过DEF文件了,如果你的项目里没有产生DEF文件,可以通过Project->Properties->Linker->ModuleDefinitionFile来指定或自己用记事本建立这样的文件,输入如下内容。
;CPLTest.def:
DeclaresthemoduleparametersfortheDLL.
LIBRARY "CPLTest"
EXPORTS
;Explicitexportscangohere
CPlApplet
5 在dllmain.cpp文件中增加函数CPLApplet的消息处理函数来完成指定的功能;
在dllmain.cpp中包含以上两个头文件
#include"resource.h"//资源标识
#include
我的例子完成显示一个MessageBox的功能。
dllmain.cpp的完整代码:
//dllmain.cpp:
DefinestheentrypointfortheDLLapplication.
#include "stdafx.h"
#include "resource.h"
#include
LONG APIENTRY CPlApplet(HWND hwndCPL, UINT uMsg, LPARAM lParam1, LPARAM lParam2);
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call,LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
LONG APIENTRY CPlApplet(HWND hwndCPL, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
{
int i;
LPCPLINFO lpCPlInfo;
i =(int) lParam1;
switch (uMsg){
case CPL_INIT:
//firstmessage,sentonce
return TRUE;
case CPL_GETCOUNT:
//secondmessage,sentonce
return 1;
break;
case CPL_INQUIRE:
//thirdmessage,sentonceperapplication
lpCPlInfo =(LPCPLINFO) lParam2;
lpCPlInfo->lData =0;
lpCPlInfo->idIcon = IDI_ICON1;
lpCPlInfo->idName = IDS_STRING102;
lpCPlInfo->idInfo = IDS_STRING103;
break;
case CPL_DBLCLK:
//applicationicondouble-clicked
MessageBox(NULL, TEXT("Tom66"), TEXT("Cuei666"), MB_OK);
break;
case CPL_STOP:
//sentonceperapplicationbefore CPL_EXIT
break;
case CPL_EXIT:
//sentoncebeforeFreeLibraryiscalled
break;
default:
break;
}
return 0;
}
6 编译
Project->Properties->Linker->OutputFile修改输出文件的后缀名为CPL,也可以不修改,到最后把dll改为cpl也可以的。
四、 控制面板应用程序的安装与运行
l 将cpl文件拷贝到Windows(WindowsCE)或Windows/system32(桌面版本Windows),可以在这里双击运行,也可以打开控制面板就可以看到该CPL文件所包含的控制面板条目,图标和文件就是你在CPLApplet里指定的,双击也可运行。
2在命令行下运行rundll32shell32.dll,Control_RunDLLCPLTest.cpl(CPL文件名)@1(数字指定运行第几个控制面板条目,一个CPL文件可以包含几个控制面板条目)。
在windowsCE下,在命令行输入ctlpnl.exe/windows/cplmain.cpl,5,与桌面版本有些差异。
3 在windows的注册表[HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/ControlPanel/Cpls] 下新建字符串,并指定cpl所在的完整路径,然后就可以在控制面板里看到新增加的控制面板条目。
通过写注册表的方式,是一些应用软件惯用的方式,安装时可以通过InstallShield等安装制作工具将其添加到注册表,卸载时,删除注册表中相关的项。
4 通过拷贝的方式,直接删除相应的CPL文件就可以了。
至于有没有更好的方式,我还没有发现。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Windows 控制面板编程 控制 面板 编程