分享
 
 
 

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

王朝厨房·作者佚名  2007-01-04
窄屏简体版  字體: |||超大  

王 琰

控 制 面 板 是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_

// CtrlPan.cpp, 定 义 了 类CControlPanel 的 缺 省 处 理 函 数

#include "stdafx.h"

#include "ctrlpan.h"

CControlPanel* CControlPanel::m_pThis = NULL;

CControlPanel::CControlPanel()

{ m_pThis = this; }

CControlPanel::~CControlPanel()

{ }

// CPL 库 的 输 出 函 数

LONG APIENTRY CControlPanel::CPlApplet(HWND hwndCPl, UINT uMsg,

LONG lParam1, LONG lParam2)

{

CControlPanel* pCtrl = m_pThis;

ASSERT(pCtrl); // 检 查pCtrl 的 有 效 性

switch (uMsg) {

case CPL_DBLCLK:

return pCtrl->OnDblClk(hwndCPl, lParam1, lParam2);

case CPL_EXIT:

return pCtrl->OnExit();

case CPL_GETCOUNT:

return pCtrl->OnGetCount();

case CPL_INIT:

return pCtrl->OnInit();

case CPL_NEWINQUIRE:

return pCtrl->OnInquire(lParam1, (NEWCPLINFO*)lParam2);

case CPL_INQUIRE:

return 0; // 基 于WIN32 的CPL 库 不 处 理 这 条 消 息

case CPL_SELECT:

return pCtrl->OnSelect(lParam1, lParam2);

case CPL_STOP:

return pCtrl->OnStop(lParam1, lParam2);

case CPL_EXIT:

retrun pCtrl->OnExit();

default: break;

}

return 1;

}

// 缺 省 的 消 息 处 理 函 数

LONG CControlPanel::OnDblClk(HWND hwndCPl, UINT uAppNum, LONG lData)

{ return 0; }

LONG CControlPanel::OnExit()

{ return 0; }

LONG CControlPanel::OnGetCount()

{ return 1; } // 缺 省 为 一 个 组 件

LONG CControlPanel::OnInit()

{ return 1; }

LONG CControlPanel::OnInquire(UINT uAppNum, NEWCPLINFO* pInfo)

{

// 填 充NEWCPLINFO 结 构, 结 构 的 定 义 请 参 考VC 的 联 机 帮 助

pInfo->dwSize = sizeof(NEWCPLINFO);

pInfo->dwFlags = 0;

pInfo->dwHelpContext = 0;

pInfo->lData = 0;

pInfo->hIcon = ::LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(1));

strcpy(pInfo->szName, "Applet");

strcpy(pInfo->szInfo, "Default Control Panel Applet");

strcpy(pInfo->szHelpFile, "");

return 0;

}

LONG CControlPanel::OnSelect(UINT uAppNum, LONG lData)

{ return 1; }

LONG CControlPanel::OnStop(UINT uAppNum, LONG lData)

{ return 1; }

LONG CControlPanel::OnExit()

{ return 1; }

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有