社区
Delphi
帖子详情
delphi里的消息机制是什么东东啊?有没有相关资料?
chenlh
2000-08-13 12:21:00
...全文
92
2
打赏
收藏
delphi里的消息机制是什么东东啊?有没有相关资料?
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
2 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
Firing_Sky
2000-08-13
打赏
举报
回复
BBS水木清华站∶精华区
发信人: strayli (stray), 信区: Delphi
标 题: DELPHI 中 的 消 息 处 理 机 制 (转)
发信站: BBS 水木清华站 (Sun Oct 4 18:29:01 1998)
DELPHI 中 的 消 息 处 理 机 制
( 南 京 理 工 大 学 自 控 系 研96 马 勇
邮 编:210094 电 话:025-4315309 )
Delphi 是Borland 公 司 提 供 的 一 种 全 新 的WINDOWS 编 程 开 发 工 具. 由 于 它 采 用 了 具 有 弹 性 的 和 可 重 用 的 面 向 对 象Pascal(object-oriented pascal) 语 言, 并 有 强 大 的 数 据 库 引 擎(BDE), 快 速 的 代 码 编 译 器, 同 时 又 提 供
了
众 多 出 色 的 构 件. 受 到 广 大 编 程 人 员 的 青 睐. 在 众 多 的 编 程 语 言( 如VB,PowerBuilder,Powerpoint 等) 中 脱 颖 而 出.
其 中 一 个DELPHI 强 于 其 他 编 程 语 言( 如VB4.0) 的 地 方 就 是 在DELPHI 中 可 自 定 义 消 息, 并 可 直 接 处 理 消 息. 这 对 于 那 些 希 望 编 写 自 己 的 构 件(Component), 或 者 希 望 截 获. 过 滤 消 息 的 用 户 来 说 是 必 不 可 少 的. 因 为
编 写 构 件 一 般 要 对 相 应 的 消 息 进 行 处 理. 下 面 就 对Delphi 中 消 息 处 理 机 制 进 行 一 下 介 绍。
一.DELPHI VCL 中 消 息 的 传 递
Delphi 中 每 一 个VCL(Visual Component Library) 构 件( 如Tbutton,Tedit 等) 都 有 一 内 在 的 消 息 处 理 机 制, 其 基 本 点 就 是 构 件 类 接 收 到 某 些 消 息 并 把 它 们 发 送 给 适 当 的 处 理 方 法, 如 果 没 有 特 定 的 处 理 方 法, 则 调 用
缺 省 的 消 息 处 理 句 柄。
其 中mainwndproc 是 定 义 在Twincontrol 类 中 的 一 个 静 态 方 法, 不 能 被 重 载(Override)。 它 不 直 接 处 理 消 息, 而 是 交 由wndproc 方 法 处 理, 并 为wndproc 方 法 提 供 一 个 异 常 处 理 模 块。Mainwndproc 方 法 声 明 如 下:
procedure MainWndProc(var Message: TMessage);
Wndproc 是 在Tcontrol 类 中 定 义 的 一 个 虚 拟 方 法, 由 它 调 用dispatch 方 法 来 进 行 消 息 的 分 配, wndproc 方 法 声 明 如 下:
procedure WndProc(var Message: TMessage); virtual;
dispatch 方 法 是 在Tobject 根 类 中 定 义 的, 其 声 明 如 下:
procedure Tobject.dispatch(var Message); 传 递 给dispatch 的 消 息 参 数 必 须 是 一 个 记 录 类 型, 且 这 个 记 录 中 第 一 个 入 点 必 须 是 一 个cardinal 类 型 的 域(field), 它 包 含 了 要 分 配 的 消 息 的 消 息 号 码. 例 如:
type
Tmessage=record
Msg:cardinal;
wparam:word;
lparam:longint; .
result:longint;
end;
而Dispatch 方 法 会 根 据 消 息 号 码 调 用 构 件 的 最 后 代 类 中 处 理 此 消 息 的 句 柄 方 法. 如 果 此 构 件 和 它 的 祖 先 类 中 都 没 有 对 应 此 消 息 的 处 理 句 柄,Dispatch 方 法 便 会 调 用Defaulthandler 方 法.Defaulthandler 方 法 是 定
义 于Tobject 中 的 虚 拟 方 法, 其 声 明 如 下:
procedure Defaulthandler(var Message);virtual;
Tobject 类 中 的Defaulthandler 方 法 只 是 实 现 简 单 的 返 回 而 不 对 消 息 进 行 任 何 的 处 理. 我 们 可 以 通 过 对 此 虚 拟 方 法 的 重 载, 在 子 类 中 实 现 对 消 息 的 缺 省 处 理. 对 于VCL 中 的 构 件 而 言, 其Defaulthandler 方 法 会 启
动 windows API 函 数Defwindowproc 对 消 息 进 行 处 理.
二.DELPHI 中 的 消 息 处 理 句 柄
在DELPHI 中 用 户 可 以 自 定 义 消 息 及 消 息 处 理 句 柄. 消 息 处 理 句 柄 的 定 义 有 如 下 几 个 原 则:
1.消 息 处 理 句 柄 方 法 必 须 是 一 个 过 程, 且 只 能 传 递 一 个Tmessage 型 变 量 参 数. 2.方 法 声 明 后 要 有 一 个message 命 令, 后 接 一 个 在0 到32767 之 间 的 消 息 标 号( 整 型 常 数). 3.消 息 处 理 句 柄 方 法 不 需 要 用override 命 令 来
显 式 指 明 重 载 祖 先 的 一 个 消 息 处 理 句 柄, 另 外 它 一 般 声 明 在 构 件 的protected 或private 区. 4.在 消 息 处 理 句 柄 中 一 般 先 是 用 户 自 己 对 消 息 的 处 理, 最 后 用inherited 命 令 调 用 祖 先 类 中 对 应 此 消 息 的 处 理 句 柄(
有 些 情 况 下 可 能 正 相 反). 由 于 可 能 对 祖 先 类 中 对 此 消 息 的 处 理 句 柄 的 名 字 和 参 数 类 型 不 清 楚, 而 调 用 命 令inherited 可 以 避 免 此 麻 烦, 同 样 如 果 祖 先 类 中 没 有 对 应 此 消 息 的 处 理 句 柄,inherited 就 会 自 动 调
用Defaulthandler 方 法.( 当 然 如 果 要 屏 蔽 掉 此 消 息, 就 不 用inherited 命 令 了)。
消 息 处 理 句 柄 方 法 声 明 为:
procedure Mymsgmethod(var message:Tmessage); message Msgtype;
同 样 用 户 也 可 以 定 义 自 己 的 消 息, 用 户 自 定 义 消 息 应 从WM_USER 开 始.
自 定 义 消 息 及 消 息 处 理 句 柄 举 例 如 下:
const my_paint=Wm_user+1;
type
Tmypaint=record
msgid:cardinal;
msize:word;
mcolor:longint;
msgresult:longint;
end;
type
Tmycontrol=class(TCustomControl)
protected
procedure change(var message:Tmypaint); message my_paint;
.....
end;
......
procedure Tmycontrol.change(var message:Tmypaint);
begin
size:=message.msize; { 设 置Tmybutton 尺 寸 属 性}
color:=message.mcolor; { 设 置Tmybutton 颜 色 属 性}
{do something else}
inherited; { 交 由Tcustomcontrol 处 理}
end;
三. 过 滤 消 息
过 滤 消 息 又 称 消 息 陷 阱。 在 一 定 情 况 下, 用 户 可 能 需 要 屏 蔽 某 些 消 息. 或 者 截 获 某 些 消 息 进 行 处 理。 由 以 上 介 绍 可 以 看 出 过 滤 消 息 一 般 有 三 种 途 径:(1). 重 载 构 件 继 承 的 虚 拟 方 法wndproc. (2). 针 对 某
消 息 编 写 消 息 处 理 句 柄. (3). 重 载 构 件 继 承 的 虚 拟 方 法Defhandler, 在 其 中 对 消 息 进 行 处 理。 其 中 常 用 的 方 法 是 方 法(2), 在 上 节 中 已 介 绍 过 了, 方 法(1) 与 方 法(3) 相 似, 这 里 只 简 单 介 绍 一 下 方 法(1)。
重 载 虚 拟 方 法wndproc 的 一 般 过 程 如 下:
procedure Tmyobject.wndproc(var message:Tmessage);
begin
{... 判 断 此 消 息 是 否 该 处 理..}
inherited wndproc(message);
{ 未 处 理 的 消 息 交 由 父 辈wndproc 方 法 处 理}
end;
由 此 可 以 看 出 在wndproc 方 法 中 处 理 消 息 的 优 势 是 可 以 过 滤 整 个 范 围 内 的 消 息, 而 不 必 为 每 个 消 息 指 定 一 个 处 理 句 柄, 事 实 上Tcontrol 构 件 中 就 是 利 用 它 来 过 滤 并 处 理 所 有 的 鼠 标 消 息 的(
从WM_mousefirst 到WM_mouselast, 如 下 代 码 示). 同 样 利 用 它 也 可 以 阻 止 某 些 消 息 被 发 送 给 处 理 句 柄。
procedure TControl.WndProc(var Message: TMessage);
begin
if (Message.Msg>=WM_MOUSEFIRST) and
(Message.Msg <= WM_MOUSELAST)
then
if Dragging then { 处 理 拖 曳 事 件}
DragMouseMsg(TWMMouse(Message))
else
... { 处 理 其 他 鼠 标 消 息}
end;
Dispatch(Message);
{ 否 则 正 常 发 送 消 息}
end;
下 例 为 一 简 单 的 自 定 义 构 件 例 子 :
Tmyedit 类 是 从Tedit 类 派 生 出 的 一 个 新 类, 它 的 特 点 是 在 运 行 中 不 能 获 得 焦 点, 不 能 由 键 盘 输 入( 有 点 类 似Tlabel 构 件). 我 们 可 在 其wndproc 方 法 中 过 滤 出WM_setfocus,WM_mousemove 消 息 并 进 行 处 理 来 达 到 上 述
要 求, 源 程 序 如 下:
unit myedit;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs,
StdCtrls;
type
Tmyedit = class(TEdit)
private
{ Private declarations }
protected
{ Protected declarations }
{ other fields and methods}
procedure wndproc(var message:Tmessage);override;
public
{ Public declarations }
published
{ Published declarations }
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [Tmyedit]);
end;
procedure Tmyedit.wndproc(var message:tmessage);
begin
if message.msg=wm_mousemove then
begin
cursor:=crarrow;
{ 设 置 光 标 为crarrow, 而 不 是 缺 省 的crBeam 光 标}
exit;
end;
if message.msg=wm_SetFocus then exit;
{屏蔽掉WM_setfocus消息,不让Tmyedit控件获得输入焦点}
inherited wndproc(message);
{其他消息交父辈wndproc处理}
end;
end.
您 可 以 将Tmyedit 加 到Component Palette 中 检 验 其 性 能。
由 以 上 介 绍 可 以 看 出, 只 有 清 楚 了Delphi VCL 中 的 消 息 处 理 机
制, 掌 握 好 处 理 各 种 消 息 的 方 法 和 时 机( 必 要 时 要 借 助 各 种 工
具, 如winsight32,spy 等), 并 结 合OOP 语 言 的 特 点, 我 们 才 可 能 编
出 高 质 量 的 构 件。 这 当 然 要 靠 读 者 在 实 践 中 不 断 摸 索, 积 累 经
验。
--
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: gps.auto.ustc.e]
BBS水木清华站∶精华区
Firing_Sky
2000-08-13
打赏
举报
回复
???
Delphi的消息机制不就是Windows得消息机制吗?
编程新手真言......
任何语言都是有门槛的 14 什么是语言级和语言外要学习的(数据结构与代码结构) 15 什么是语言级要学习的 17 编程学习方法 18 计算机学生专业课程本质讲解 18 用C++开发要学到什么程度 20 本书目录安排 21 第二部分 ...
JNDI 是个什么
东东
?
JNDI 是个什么
东东
? JNDI是 Java 命名与目录接口(Java Naming and Directory Interface),在J2EE规范中是重要的规范之一,不少专家认为,没有透彻理解JNDI的意义和作用,就没有真正掌握J2EE特别是EJB的知识。那么...
Delphi
XE10零基础实战快速入门
通过课堂上一个一个的实战例子,演示
Delphi
XE10的用法,最后通过一个完整的通讯录程序,让学员初步掌握软件开发的全部流程 让零基础学员快速入门
Delphi
编程,快速掌握
Delphi
的使用方法,并能够制作出自己的软件来。...
关于
Delphi
:
Delphi
自定义控件开发
有人说过“不会开发控件的
Delphi
程序员不是真正的程序员”。
Delphi
正是由于高度的可扩展性和大量的第三方控件的支持才能吸引无数程序员挑剔的目光。即使是由于工作需要使用其他开发工具的开发者也常常怀念和
Delphi
...
Delphi
5,391
社区成员
262,735
社区内容
发帖
与我相关
我的任务
Delphi
Delphi 开发及应用
复制链接
扫一扫
分享
社区描述
Delphi 开发及应用
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章