当前位置导航:炫浪网>>网络学院>>编程开发>>C++教程>>Visual C++教程

利用VC++编写Windows95的CPL组件

    控制面板是Windows 95 的控制中心,通过它可以完成添加新硬件设备、改变桌面设置、配置网络协议等多项工作。在Windows 95 中,控制面板通常有20 多个组件,我们只要用鼠标双击任一组件的图标,就会弹出一个对话框,对话框包含有设置一些系统参数的选项,这些参数的绝大多数都存放在Windows 95 的注册表中。


---- 控制面板的主程序是CONTROL.EXE,它在启动时自动Winndows\System 目录下查找并调入文件扩展名为CPL 的控制面板组件。控制面板组件是可以扩充的,一些软件在安装过程中会自动加入新的控制面板组件。按照Windows 用户界面设计原则的规定,凡是影响到系统的整体行为和界面风格的各项参数都应该通过控制面板来设置,因此掌握控制面板组件的编程方法是很有必要的。

控制面板组件的工作原理---- 控制面板的各个组件都是一些特殊的动态链接库,只不过它们的扩展名不是DLL,而是CPL,即Control Panel 的缩写。
---- CONTROL.EXE 启动后会依次调入在系统目录下查找到的CPL 库。一般来说,一个CPL 库只负责管理某一方面的设置,对应着控制面板中的一个组件( 即一个图标),但也有少数CPL 库支持多个组件。

---- 每个CPL 库必须输出一个叫CPlApplet() 的函数供CONTROL.EXE 调用,CPlApplet() 具有以下原型:

                    typedef LONG (APIENTRY *APPLET_PROC)(HWND hwndCpl, UINT msg,
                                        LONG lParam1,LONG lParam2);
---- 容易看出,CPlApplet() 与普通窗口处理函数的形式很相似,事实上,控制面板正是以发送消息的方式与CPL 库进行通信。参数hwndCpl 为控制面板的窗口句柄,msg 为消息标识,lParam1 和lParam2 为附加的两个参数,具体的意义视msg 的值而定。

---- 控制面板用LoadLibrary() 函数把CPL 库调入内存以后,立刻向CPlApplet() 发送一条CPL_INIT 消息,指示CPL 库作初始化工作。

---- 因为这是唯一允许返回失败信息的消息,所以CPL 库此时应该分配运行过程中需要的所有内存和资源,如果因为内存不够或者其它原因不能继续,就返回零值,控制面板将不再处理这个CPL 库,并自动卸下它。

---- 所有CPL 库初始化完毕后,控制面板再向每个CPL 库的CPlApplet() 函数发送一条CPL_GETCOUNT 消息,此时CPL 库返回它所支持的组件数。接下来,控制面板再针对每一个组件向CPlApplet() 函数发送多条CPL_NEWINQUIRE 消息,目的是取得每个组件对应的图标、名称和提示信息,CPL 库可以在处理这条消息时依次初始化各个组件的对话框。在Windows 3.x 中,控制面板发送的是CPL_INQUIRE 消息,考虑到兼容性的问题,这条消息在Windows 95 中被保留下来了,但是基于WIN 32 的CPL 库只需处理新的CPL_NEWINQUIRE 消息。

---- 进行到这一步后,控制面板显示出所有组件的图标,并开始接受用户的选择。当用户双击某个组件的图标时,控制面板向该组件所在的CPL 库发送一条CPL_DBLCLK 消息,并指明用户选择的是该CPL 库中的第几个组件,CPL 库在接到这条消息后从INI 文件或Windows 95 的注册表中读出要处理的系统参数的原始值,并启动相应的对话框,允许用户改变设置。当用户在修改过程中按下应用(Apply) 按钮后,CPL 库保存新的参数并返回到控制面板中;如果用户取消了所作修改,CPL 库只需返回即可。

---- 控制面板在被关闭时会对每个组件发送一条CPL_STOP 消息,接着对每个CPL 库发送一条CPL_EXIT 消息,此时CPL 库释放在CPL_INIT 消息中分配的内存和资源。最后控制面板依次卸下各个CPL 库并退出。

---- 上面叙述的就是控制面板组件的工作原理,其中各条消息的具体参数定义请参考WIN 32 SDK。

利用VC++ 编写控制面板组件---- 编写控制面板组件实际上是编写DLL,利用Visual C++ 这个强大的可视化编程工具可以很方便地完成这项工作。MFC 基本类库为我们封装了DLL 的基本框架,我们只需编写处理消息的CPlApplet() 函数和各个组件的对话框即可。遗憾的是,MFC 类库中没有现成的关于控制面板组件的类,为了充分利用C++ 语言可继承性的优点,本文后面的程序给出了一个控制面板组件的基类CControlPanel,它的成员函数提供了处理各种CPL 消息的缺省代码,我们只要从这个基类派生出新的子类,并为需要处理的消息重载相应的代码,就可以迅速建立一个控制面板组件。
---- 利用Visual C++ 中编写控制面板组件的步骤如下:

调用AppWizard 建立一个新的项目,将应用程序类型为设使用MFC 的DLL,并把MFC 类库作为静态库连接,按下Finish 按钮,让AppWizard 自动生成框架文件。

把本文后面的CtrlPan.CPP 加入到项目中,把CPlApplet 添加到DEF 文件的输出名表中,然后选择Build 菜单的Settings,修改输出文件的扩展名为CPL。

从CControlPanel 中派生出新的子类,并重载部分消息代码。多数情况下只需要重载处理CPL_NEWINQUIRE 和CPL_DBLCLK 消息的函数就行了,如下所示:
                    #include "ctrlpan.h"
                    class CNewCPL : public CControlPanel
                    {
                    public:
virtual LONG OnInquire(UINT uAppNum, NEWCPLINFO* pInfo);
virtual LONG OnDblClk(HWND hwndCPl, UINT uAppNum, LONG lData);
                    };
---- 如果要在一个CPL 库中支持多个组件,那么至少还要重载OnGetCount() 函数。

编写消息处理代码,OnInquire() 函数负责返回组件的各种信息,可参考基类中该函数的实现代码,OnDblClk() 函数负责读取和保存各个参数,并调用对话框让用户选择。

设计对话框,用ClassWizard 生成对话框的处理代码,并修改这些代码使之符合要求。

源代码编写完毕后,编译连接,把生成的CPL 文件拷则到SYSTEM 目录下,运行控制面板进行调试。

调试正确后,重新建立CPL 库的Release 版。
// CtrlPan.h:类CControlPanel 的声明
#ifndef _CTRLPAN_H_
#define _CTRLPAN_H_
#include      //VC 提供的头文件
class CControlPanel
{
public:
    CControlPanel();
    virtual ~CControlPanel();
    // 可重载的消息处理函数
    virtual LONG OnDblClk(HWND hwndCPl, UINT uAppNum, LONG lData);
    virtual LONG OnExit();
    virtual LONG OnGetCount();
    virtual LONG OnInit();
    virtual LONG OnInquire(UINT uAppNum, NEWCPLINFO* pInfo);
    virtual LONG OnSelect(UINT uAppNum, LONG lData);
    virtual LONG OnStop(UINT uAppNum, LONG lData);
                    virtual LONG OnExit();
    // CPL 库的输出函数
    static LONG APIENTRY CPlApplet(HWND hwndCPl, UINT  uMsg,
                                   LONG lParam1, LONG lParam2);
    static CControlPanel* m_pThis;
};
#endif // _CTRLPAN_H_


 

共2页 首页 上一页 1 2 下一页 尾页 跳转到
相关内容
赞助商链接