admin管理员组

文章数量:1516870

控制面板知多少

控制面板,你了解多少。当你安装了一些应用程序后,是否感觉到你的控制面板增加了一些组件,如安装了 Borland C++ Builder , BDE Administrator ”就会进入你的控制面板,安装了 QuickTime 还会增加“ QuickTime ”组件,这些现象说明了什么,我想它只是说明了一个事实:“控制面板”是可以操纵的,你也可以控制你的控制面板,它并无什么神秘可言,哪到底如何操纵呢 , 这正是我今天要讨论的主题,在这里我将会带领大家有浅入深地来探讨“控制面板”这个鲜为人知的主题。我主要分 3 个部分来阐述:(由于文章大小的限制,我决定将其分成两章来介绍)

1 、控制面板是什么,它在哪里?

2 CPL 文件的真实身份

3 VCL 如何提供对“控制面板”的支持

控制面板是什么,它在哪里?

控制面板是什么,它在哪儿? 以前,我也很困惑,只是偶尔从一些关于“ Windows 系统管理”的书籍朦胧地听到关于“控制面板”的描述:“控制面板的每一项一般都会对应一个 .CPL 文件 , 这些文件存于系统目录下 , 你可以指定控制面板中要显示的项目 , 也可以隐藏等等”关于如何实现 , 可能还会教给你一些通过修改注册表来达到目的,是的,这可以达到目的 , 但我想这只是从一个管理者地角度来看待这个问题的,如果从程序员的角度又如何的,他们的描述能解决你的问题吗?你如何利用程序来达到控制你 控制面板 的目的 , 你想知道吗 , 请听下文分解 .

CPL 文件的真实身份

上面提到了以“ .CPL ”扩展名结尾文件 ,既然又与控制面板有关,哪我就来分析一下 CPL 文件到底是什么吧,随便找一些 CPL 文件,如: main.cpl,access.cpl 等,我用 Dumpbin 测试结果如下:

C:/WINDOWS/system32>dumpbin main.cpl

Microsoft (R) COFF Binary File Dumper Version 6.00.8168

Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

Dump of file main.cpl

File Type: DLL (由 DLL 可以知道它是一个 DLL 文件)

C:/WINDOWS/system32>dumpbin /exports appwiz .cpl

Microsoft (R) COFF Binary File Dumper Version 6.00.8168

Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

Dump of file appwiz.cpl

File Type: DLL

Section contains the following exports for appwiz.dll

ordinal hint RVA name

1 0 00017926 CPlApplet

2 1 00017F05 ConfigStartMenu

......

C:/WINDOWS/system32>dumpbin /exports access.cpl

Microsoft (R) COFF Binary File Dumper Version 6.00.8168

Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

Dump of file access.cpl

File Type: DLL

Section contains the following exports for Access.dll

ordinal hint RVA name

1 0 00004B41 CPlApplet

2 1 00004B33 DebugMain

3 2 00004B30 DllRegisterServer

3 3 00004A27 DllUnregisterServer

从上面的测试结果你看到了什么,我认为至少有两点:

1、 CPL 文件就是一个 DLL 文件

2、 CPL 文件都导出了一个 CPLApplet 函数

这两点揭开了控制面板程序的神秘面纱,你不会再对控制面板程序是什么感到疑惑了,其实,控制面板程序就是一个须导出 CPLApplet 函数的 DLL 文件,只是挂上了 CPL 的后缀名而已。既然都要导出 CPLApplet 函数,可以想象 CPLApplet 这个函数的重要性 , 其实,不光是控制面板,只要是想加载 CPL 文件的其他所有应用程序都必须取得 CPLApplet 函数的地址然后通过调用该函数来完成相应得功能的,以下是我从 MSDN 得来的关于它的声明,详细信息请参考 MSDN.

LONG APIENTRY CPlApplet(
HWND hwndCPl,
UINT uMsg,
LONG lParam1,
LONG lParam2
);
参数的意义
hwndCPl激活控制面板组件应用程序的窗口句柄
uMsg外界传入的控制消息,CPLApplet函数就是通过该消息去完成
              相应的任务的
lParam1消息参数1
lParam2消息参数2

CPLApplet 函数可以接受的控制消息一览表:

消息 描述

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

CPL_INIT CPL 程序收到的第一个消息,在这儿通常完成控制面板组件数据及变量的初始化工作

CPL_GETCOUNT CPLApplet 函数在继 CPL_INIT 消息之后收到的第二个消息,它使得 CPLApplet 函数返回该 CPL 文件所包含的控制面板组件数目

CPL_INQUIRE CPL_INQUIRE 及下一个要介绍的 CPL_NEWINQUIRE 消息是所有控制面板程序的消息中最重要的两个消息,可以这样说控制面板就是利用这两个消息来取得每个组件的名称、描述及图标等信息。 CPL_INQUIRE 会将组件信息填入 TCPLInfo 的结构中, TCPLInfo 结构的声明如下:

typedef struct tagCPLINFO {
intidIcon; 
intidName; 
intidInfo; 
LONG lData; 
} CPLINFO; 
typedef tagCPLINFOTCPLInfo;

然后你的程序就可以利用 LoadString,LoadIcon( 这个 API

函数已被 LoadImage 函数取代,不过你还是可以用 ) API

函数来取得相应的信息

CPL_NEWINQUIRE

CPL_NEWINQUIRE CPL_INQUIRE 消息所完成的功能差不多,但它会将组件信息填入 TNewCPLInfo 结构而不是 TCPLInfo 结构中,一看名称就知 CPL_NEWINQUIRE CPL_INQUIRE 后出来,按照常规的思维一般应优先选择后出来得的即使用 CPL_NEWINQUIRE ,但这是一个例外, TNewCPLInfo 结构虽较 TCPLInfo 更为完整,但它所包含的资料无法缓存,所以使用 TNewCPLInfo 会使开启控制面板的速度减慢,这也是微软文件上注明着 除非必要 , 否则请尽量以 CPL_INQUIRE 消息来传递组件信息 的原因

CPL_DBLCLK 当用户双击控制面板中组件的图标时就会触发 CPL_DBLCLK 消息来相应用户的操作,一般是开启一个对话框来供用户进行调整设定,如: ”Internet 选项 就会显示一个有关 IE 设置的对话框,你可以在该对话框中设置 IE 的一些属性

CPL_STOP 这个消息主要是提供机会给你进行善后工作的 , 如释放与组件相关的内存 .

CPL_EXIT 这个消息是你进行善后工作的最后机会,即在应用程序调用 FreeLibray 函数之前时你可以进行一些善后工作,如:释放内存等

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

提示 : 上表所列出的消息顺序也正是 CPL 程序收到的消息的顺序 , CPL 程序是按照 CPL_INIT, CPL_GETCOUNT CPL_EXIT 来完成相应的任务的 .

如果你对上面的描述还感到抽象的话 , 下面我就已一个实际的例子来说明到底是如何建立控制面板的应用程序。

操作步骤如下:

1 :建立资源文件以便在程序中使用,下图是用 Borland Resoure Workshop 制作 ctrl.rc 的情形。

1-1 编辑资源文件

提示: 1 2 表示字符串与图标资源的代号,你也可以去别的名称做好后你可以利用 brcc32.exe 将其编译为 res 资源文件命令如下:

brc32 ctrl.rc

这样将的到 ctrl.res 编译后的资源文件,当然你也可以直接利用 Borland Resoure Workshop 建立 Res 格式的文件,省去编译这一环节

2 :打开你的 BCB ,通过 DLL Wizard 建立一个 DLL 工程(因为 CPL 程序就是 DLL 文件)

3 :导出 CPLApplet 函数,这是最重要的,其它的操作和别的程序没有区别

4 :从菜单中选取 ”Project / Options” 选项,在“ Project Options ”选项对话框中将 Application 页面的“ Target file extension ”改为“ cpl

提示:

由于该程序不是可执行文件,所以不能按 F9 运行,必须通过控制面板或 rundll32.exe 来运行,首先将其 CPL 文件 Copy 到系统目录下,然后利用控制面板来运行或者 rundll32.exe 来运行,命令如下: rundll32 shell32.dll Control_RunDLL *.cpl

源程序如下:

#include <vcl.h>

#include <windows.h>

#pragma hdrstop

// 导入控制面板程序相关的头文件

#include <cpl.h>

#pragma resource "ctrl.RES"

// 导出 CPlApplet 函数

extern "C" __declspec(dllexport) LONG _stdcall CPlApplet(

HWND hwndCPl,

UINT uMsg,

LONG lParam1,

LONG lParam2

);

// 实现 CPlApplet 函数

LONG _stdcall CPlApplet(HWND hwndCPl,UINT uMsg,LONG lParam1,LONG lParam2)

{

LPCPLINFO ptCPLInfo;

switch (uMsg)

{

case CPL_INIT:

ShowMessage(" 初始化数据或变量 !");

return 1;

case CPL_GETCOUNT:

ShowMessage(" 只有一个组件! ");

return 1;

case CPL_INQUIRE:

ShowMessage(" 设置控制面板组件资源信息 !");

ptCPLInfo=(LPCPLINFO)lParam2;

// 将信息填入 TCPLInfo 的结构中

ptCPLInfo->idName=1;

ptCPLInfo->idInfo=1;

ptCPLInfo->idIcon=2;

ptCPLInfo->lData=0;

break;

case CPL_DBLCLK:

ShowMessage(" 很高兴看到你 !");

return 0;

case CPL_EXIT:

ShowMessage(" 退出控制面板程序 !");

return 0;

}

return 0;

}

#pragma argsused

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)

{

return 1;

}

DllEntryPoint 函数是所有 DLL 文件的入口函数,相当于可执行文件的 WinMain 函数, #include <cpl.h> 语句导入 Borland C++ Builder 所提供的关于控制面板的相关声明,语句 extern "C" __declspec(dllexport) LONG _stdcall CPlApplet(……) 导出 CPLApplet 函数

提示:VCL 如何提供对“控制面板”的支持这一节将在“控制面板知多少(续篇)”介绍

本文标签: 函数控制面板系统