利用Delphi编写Windows控制面板组件及实例_信息技术论文
张 建 军(中国人民解放军合肥炮兵学院研究生系97级)
韩 莹 (中保财险安徽省铜陵市分公司计财部)
关键词: |
在windows95/nt/98操作系统中,控制面板(control panel)提供了定制windows的操作方法,通过它可以完成设置打印机、显示、网络、添加新硬件等功能。通常控制面板包含20多个组件(*.cpl),分别负责系统某一方面的设置。鼠标双击任一组件图标,控制面板调用相应程序,弹出对话框,允许设置系统参数。确认修改后系统参数保存在windows注册表或某一配置文件(*.ini)中。 一、控制面板组件基础知识 控制面板是一个windows应用程序c:\windows\control.exe,其配置文件是c:\windows\control.ini。控制面板组件是一些动态链接库,其扩展名不是dll,而是cpl。通常,控制面板组件保存在c:\windows\system\目录下。在control.ini中有一个[mmcpl]节,该节可指定由control.exe调用的动态链接库,其格式一般为: ... [mmcpl] uniquename=d:\project1.dll(这里假设project1为用户编写的控制面板组板文件 名,其访问路径可由读者自行确定) ... 采用此方法,project1.dll不必存放在c:\windows\system\目录下,扩展名不必改为cpl。control.exe运行后按以下顺序调用这些动态链接库:
因此,编写控制面板组件近似于编写普通dll。通常一个cpl支持控制面板中的一个组件(即一个图标),也可支持多个组件。本文介绍利用delphi编写cpl、扩充控制面板组件(一个cpl支持一个或多个组件)的方法。 二、控制面板组件工作流程 1、每个cpl文件必须输出一个cplapplet函数,与control.exe之间传递、处理消息。cplapplet函数的原形是: type tcplapplet = function (hwndcpl: thandle; umsg: dword; lparam1, lparam2: longint): longint; stdcall; 其中,hwndcpl是控制面板窗口句柄,umsg是消息标识,lparam1、lparam2是两个附加参数,具体意义视umsg的值而定。 2、当control.exe把各cpl(或dll)调入内存时,control.exe立刻向cplapplet发送一条cpl_init消息,要求cpl执行全局初始化并分配内存。cpl_init是唯一可以返回调用失败的消息。如果初始化成功,cpl返回非零,否则返回零。如果cpl返回零,控制面板终止与cpl通信并卸载此cpl(或dll)。 3、cpl_init消息处理结束后,control.exe立刻向cplapplet发送一条cpl_getcount消息,cpl返回支持的组件数。 4、cpl_getcount消息处理结束后,control.exe立刻向cplapplet发送一条cpl_newinquire消息,cpl_newinquire每次发送一条,以取得每个组件的图标、名称、提示内容(显示在控制面板的状态栏)等。lparam1是指定对话框的数值,该值应在0到(cpl_getcount - 1)之间。如果cpl_newinquire处理成功,返回0。 说明: ◆在windows3.x系统中,control.exe发送的是cpl_inquire消息。为向下兼容,该消息被保留。基于win32的cpl应使用cpl_newinquire。 ◆通过判断lparam1的值,可对一个cpl支持的多个组件的图标、名称、提示内容等进行控制。 5、控制面板显示所有查找到的组件图标。鼠标双击任一组件图标,控制面板向其cpl发送一条cpl_dblclk消息,cpl显示相应对话框,供用户改变系统设置。 说明: ◆通过检测lparam1的值,可判断用户双击的是一个cpl支持的多个组件中的哪个图标,并运行相应程序。 6、控制面板关闭时,向每个组件发送一条cpl_stop消息,然后对每个cpl发送一条cpl_exit消息,cpl释放内存并卸载。 三、控制面板组件编写实例 1、编程步骤:
②在project1中添加如图所示form1、form2……,根据需要设计窗体界面。为简略起见,本文仅以form1为例。 ③form1主要代码:(为编写基于win32的cpl,本文以读写windows注册表为例)
var form1: tform1; keyhandle : hkey; valsize : longint; option1 : integer; option2 : integer;
procedure tform1.formactivate(sender: tobject); begin regopenkeyex(hkey_current_config, 'software\microsoft\windows\currentversion\', 0, key_all_access, keyhandle); valsize := sizeof(option1); regqueryvalueex(keyhandle,'wina', nil, nil, @option1, @valsize); valsize := sizeof(option2); regqueryvalueex(keyhandle,'winb', nil, nil, @option2, @valsize); with form1 do begin case option1 of 0: radiogroup1.itemindex:=0; 1: radiogroup1.itemindex:=1; 2: radiogroup1.itemindex:=2; 3: radiogroup1.itemindex:=3; end; case option2 of 0: radiogroup2.itemindex:=0; 1: radiogroup2.itemindex:=1; 2: radiogroup2.itemindex:=2; 3: radiogroup2.itemindex:=3; end; end; end;
procedure tform1.cancelclick(sender: tobject); begin close; end;
procedure tform1.applyclick(sender: tobject); begin with form1 do begin option1:=radiogroup1.itemindex; option2:=radiogroup2.itemindex; end; regsetvalueex(keyhandle,'wina', 0, reg_binary, @option1, sizeof(option1)); regsetvalueex(keyhandle,'winb', 0, reg_binary, @option2, sizeof(option2)); end;
procedure tform1.formclose(sender: tobject; var action: tcloseaction); begin regclosekey(keyhandle); end; ④修改project1代码如下: library project1;
uses cpl, windows, forms, unit1 in 'unit1.pas' {form1}, unit2 in 'unit2.pas' {form2};
{$r *.res}
procedure executeapp; {$e dll} begin application.initialize; application.createform(tform1, form1); application.run; end;
procedure executeapp2; {$e dll} begin application.initialize; application.createform(tform2, form2); application.run; end;
function cplapplet(hwndcpl: thandle; umsg: dword; lparam1, lparam2: longint):longint;stdcall; var newcplinfo:pnewcplinfo; begin result:=0; case umsg of cpl_init: result:=1; cpl_getcount: result:=2; cpl_newinquire: begin newcplinfo:=pnewcplinfo(lparam2); with newcplinfo^ do begin dwsize:=sizeof(tnewcplinfo); dwflags:=0; dwhelpcontext:=0; ldata:=0; if lparam1=0 then begin szname:='新的控制面板组件'; hicon:=loadicon(hinstance,'icon'); szinfo:='这是一个尝试'; end else begin szname:='新的控制面板组件2'; hicon:=loadicon(hinstance,'icon2'); szinfo:='这是一个尝试2'; end; szhelpfile:=''; end; end; cpl_dblclk: begin if lparam1=0 then executeapp else executeapp2; end; else result:=0; end; end;
exports cplapplet;
begin end. ⑤选取菜单project桹ptions桝pplication,在target file extension中输入:dll。在load icon中选择dll图标。 ⑥选取菜单run桺arameters,在host application中选择一主程序。例如:d:\program files\borland\delphi3\help\tools\hcw.exe. ⑦按f9运行程序,生成project1.dll。 ⑧将project1.dll改名为project1.cpl,存入c:\windows\system\目录下。或者,在control.ini的[mmcpl]中添加: uniquename=d:\project1.dll(具体视dll所在路径而定) ⑨启动控制面板,可以看到③中指定的图标(一个或多个)已出现在控制面板中,鼠标双击图标,弹出相应的form1、form2……。 说明:
◆本文所述编写dll方法同样适用于vc、bc、c++builder等开发工具,但应注意语法、变量、函数原型等不同要求。 以上程序在delphi3.0/4.0、简体中文windows 95/nt/98环境中调试通过。 一九九九年五月十日
作者通信地址:(230031)安徽省合肥市炮兵学院研究生系97级 张建军(收) 作者电话: 0551-5560324(张建军宿舍) 0551-5562566转68750、68210(研究生系值班室) 作者email: davidhy@263.net |