Jeanvi, Xue

导航

windows控制面板消息处理流程

前言


在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.

posted on 2011-05-23 20:38  Jeanvi, Xue  阅读(380)  评论(0编辑  收藏  举报