学海荡舟手机网

主页 > 实用文摘 > 教育文摘_18 > > 详细内容

利用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运行后按以下顺序调用这些动态链接库:

  1. 在c:\windows\system\目录下调用main.ini。
  2. 已加载并输出cplapplet()函数的可安装驱动程序。
  3. 在control.ini[mmcpl]节中指定的dll。
  4. 在c:\windows\system\目录下调用cpl。

    因此,编写控制面板组件近似于编写普通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、编程步骤:

  1. 在delphi ide中选取菜单file-new-dll-ok。

    ②在project1中添加如图所示form1、form2……,根据需要设计窗体界面。为简略起见,本文仅以form1为例。

    ③form1主要代码:(为编写基于win32的cpl,本文以读写windows注册表为例)

  • 在uses子句添加:registry。//引用注册表单元
  • 在type部分声明变量:

var

form1: tform1;

keyhandle : hkey;

valsize : longint;

option1 : integer;

option2 : integer;

  • tform1.formactivate代码://打开windows注册表,读取某特定键值

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;

  • tform1.cancelclick代码://关闭form1,返回控制面板

procedure tform1.cancelclick(sender: tobject);

begin

close;

end;

  • tform1.applyclick代码://设置注册表键值

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;

  • tform1.formclose代码://关闭注册表

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……。

说明:

  • 编程时也可将有关参数存放在某一ini文件中,操作方法不再赘述。
  • 其它应用程序可通过操作ini文件或windows注册表得到所需参数。

    ◆本文所述编写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