前言
在windows操作系统中,常用的设置功能都是放在控制面板中,当然,除了微软自己的应用外,还会有第三方公司的设置程序,比较显示驱动等产商也会加入一些自己的设定程序。如果我们自己也想加入这个功能的话,是否可行,该如何来做呢?
原理剖析
当我们打开控制面板的链接时,windows会给系统目录下的*.cpl文件发生消息以进行确认,当*.cpl文件返回相应的结果时,控制面板会将这些cpl以链接的形式加入到控制面板上。
控制面板的WINDOWS消息
CPL_INIT: WINDOWS送的第一个消息,cpl如果给于处理的话,返值值不为0,则发送下一消息。
CPL_GETCOUNT:系统会于确认该cpl所实现控制面板组件数目,若为0,则不进行显示
CPL_INQUIRE: 获取在控制面板中显示的一些属性,如显示名称,图标,描述,注意返回的数值,具体的内容要去资源文件中获取。若cpl返回回去的值有0(代表动态的),即控制面板会以CPL_NEWINQUIRE得到的值为准。若均为非0值,则系统会将这些内容进行缓存。
CPL_NEWINQUIRE: 功能同CPL_INQUIRE,但结果不会缓存。
CPL_DBLCLK:双击控制面板中显示的图标时发出。也就是CPL所实现的功能操作部分
CPL_STOP:CPL_DBLCLK执行结束后送出。一般可以做一些资源的清理工作。
CPL_EXIT:CPL_STOP送出,可以做一些资源的清理工作。
消息的发送解析
在CP_INQUIRE返加的结构均为非零的时候,因系统会进行缓存,所以执行的流程如下
初次打开控制面板CPL_INIT -> CPL_GETCOUNT->CPL_INQUIRE->CPL_NEWINQUIRE-> 初次离开控制面板 CPL_STOP->CPL_EXIT
因为缓存的关系,后续再打开控制面板,就不会进行这些消息的发送了。
双击控制面板图标时的消息发送
CPL_INIT->CPL_GETCOUNT->CPL_INQUIRE->CPL_NEWINQUIRE->CPL_DBLCLK->CPL_STOP->CPL_EXIT
测试代码
library CPLTestNative;
uses
SysUtils, windows,
Classes,
CPL;
procedure MsgBox(sMsg:string);
begin
MessageBox(0, PChar(sMsg), 'Hello, control panel', MB_ICONINFORMATION);
end;
{$R CPLNative.res}
function CPlApplet(hwndCPL: HWND; uMsg: UINT; lParam1: LPARAM;
lParam2: LPARAM): LongInt; stdcall;
var
pInfo: PCPLInfo;
begin
case uMsg of
CPL_INIT:
begin
MsgBox('get CPL_INIT');
Result := 1;
end;
CPL_GETCOUNT:
begin
MsgBox('get CPL_GETCOUNT');
Result :=1 ;
end;
CPL_INQUIRE:
begin
Msgbox('get CPL_INQIRE');
pInfo := PCPLInfo(lParam2);
with pInfo^ do
begin
idName := 1;
idInfo := 2;
idIcon := 5;
lData := 0;
end;
Result := 0;
end;
CPL_NEWINQUIRE:
begin
MsgBox('get NEWINQUIRE');
Result := 0;
end;
CPL_DBLCLK:
begin
MsgBox('get CPL_DBLCLK');
MsgBox('I''m the smallest applet application');
Result := 0;
end;
CPL_STOP:
begin
MsgBox('get CPL_STOP');
Result := 0;
end;
CPL_EXIT:
begin
MsgBox('get CPL_EXIT');
Result := 0;
end;
end;
end;
exports
CPlApplet;
begin
end.