控 制 系 统 菜 单
河 南 省 信 阳 师 范 学 院 计 算 机 系 董 建 军
---- WINDOWS 附 带 的 时 钟 程 序 有 这 样 一 个 特 点: 它 的"Always on top" 选 项 是 加 在 系
统 菜 单 中 的, 这 一 技 巧 为 该 程 序 增 色 不 少, 同 时 也 增 加 了 其 神 秘 感。 我 们
在 程 序 设 计 时 能 否 把 自 己 的 菜 单 项 加 入 系 统 菜 单 呢 ? 回 答 是 肯 定 的, 笔 者
用Delphi 方 便 的 实 现 了 这 一 功 能。
---- 为 实 现 这 一 功 能, 需 要 解 决 两 个 问 题: ①、 如 何 把 用 户 菜 单 项 加 入 系 统
菜 单, ②、 如 何 才 能 响 应 这 一 菜 单 项。
---- 要 解 决 第 一 个 问 题, 就 需 要 获 取 系 统 菜 单 的 句 柄, 这 一 点 可 用 API 函 数
getsystemmenu() 来 获 取(getmenu() 只 能 获 取 用 户 菜 单 句 柄), 有 了 系 统 菜 单 句 柄, 便
可 以 用 API 函 数appendmenu() 向 系 统 菜 单 中 加 入 用 户 菜 单 选 项 了。
---- 要 解 决 第 二 个 问 题, 需 要 重 载 WM_SYSCOMMAND 或WM_MENUSELECT 消 息。 我 们
知 道, 当 用 户 从 菜 单 中 选 一 项 时, 系 统 便 会 发 出 WM_COMMMAND 消 息, 而 对
于 系 统 菜 单, 则 会 发 出 WM_SYSCOMMAND 消 息, 重 载 这 个 消 息, 并 判 断 选 中 菜
单 的 ID 值 是 否 为 用 户 设 定 值 便 可 以 了。Delphi 为 我 们 提 供 了 这 方 面 的 机 制, 使
我 们 能 方 便 的 实 现 这 一 功 能。 当 然, 为 实 现 这 一 功 能 我 们 还 可 以 利 用 子 类
或 为 系 统 加 消 息 钩 子 的 方 法 来 解 决。
---- 为 了 便 于 实 现, 在 这 里, 我 们 采 用 重 载 WM_SYSCOMMAND 消 息 和 填 写
WM_MENUSELECT 消 息 结 构 的 方 法 来 实 现 这 一 功 能。
---- 下 面 为 笔 者 为 实 现 这 一 功 能 而 开 发 的 实 例。
---- 程 序 在Delphi ver 1.0 下 调 试 通 过。
program Psysmenu;
uses
Forms,
Sysmenu in '\SYSMENU.PAS' {Form1};
{$R *.RES}
begin
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
unit Sysmenu;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes,
Graphics, Controls,Forms, Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
procedure user_sysmenu(var msg:twmmenuselect);
message wm_syscommand;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.user_sysmenu(var msg:TWMMENUSELECT);
begin
if msg.iditem=100 then
showmessage(' 响应系统菜单!')
{ 也 可 以setwindowpos()来实现处于最前端功能}
else
inherited; { 作缺省处理,必须调用这一过程}
end;
procedure TForm1.FormCreate(Sender: TObject);
var hmenu:integer;
begin
hmenu:=getsystemmenu(handle,false);
{获取系统菜单句柄}
appendmenu(hmenu,MF_SEPARATOR,0,nil);
appendmenu(hmenu,MF_STRING,100,'加入系统菜单');
{加入用户菜单}
end;
end.