unit Main;

interface

uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls; type
TMainForm = class(TForm)
SendBtn: TButton;
PostBtn: TButton;
procedure SendBtnClick(Sender: TObject);
procedure PostBtnClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
OldWndProc: Pointer;
WndProcPtr: Pointer;
procedure WndMethod(var Msg: TMessage);
procedure HandleAppMessage(var Msg: TMsg; var Handled: Boolean);
end; var
MainForm: TMainForm; implementation {$R *.DFM} uses ScWndPrc; procedure TMainForm.SendBtnClick(Sender: TObject);
begin
SendMessage(Application.Handle, WM_USER, , );
end; procedure TMainForm.PostBtnClick(Sender: TObject);
begin
PostMessage(Application.Handle, WM_USER, , );
end; procedure TMainForm.HandleAppMessage(var Msg: TMsg; var Handled: Boolean);
begin
if Msg.Message = WM_USER then
ShowMessage(Format('Message seen by OnMessage! Value is: $%x', [Msg.Message]));
end; procedure TMainForm.WndMethod(var Msg: TMessage);
begin
if Msg.Msg = WM_USER then // 第二处处理(新的过程函数)
ShowMessage(Format('Message seen by WndMethod! Value is: $%x', [Msg.Msg]));
with Msg do
Result := CallWindowProc(OldWndProc, Application.Handle, Msg, wParam, lParam); // 第三处处理(旧的过程函数)
end; procedure TMainForm.FormCreate(Sender: TObject);
begin
Application.OnMessage := HandleAppMessage; // 第一处处理(先过OnMessage这关)
WndProcPtr := MakeObjectInstance(WndMethod); // make window proc
{ Set window procedure of application window. }
OldWndProc := Pointer(SetWindowLong(Application.Handle, GWL_WNDPROC, Integer(WndProcPtr)));
end; procedure TMainForm.FormDestroy(Sender: TObject);
begin
{ Restore old window procedure for Application window }
SetWindowLong(Application.Handle, GWL_WNDPROC, Longint(OldWndProc));
{ Free our user-created window procedure }
FreeObjectInstance(WndProcPtr);
end; end. unit Scwndprc; interface uses Forms, Messages; implementation uses Windows, SysUtils, Dialogs; var
WProc: Pointer; function NewWndProc(Handle: hWnd; Msg, wParam, lParam: Longint): Longint;
stdcall;
{ This is a Win32 API-level window procedure. It handles the messages }
{ received by the Application window. }
begin
if Msg = WM_USER then
{ If it's our user-defined message, then alert the user. }
ShowMessage(Format('Message seen by WndProc! Value is: $%x', [Msg]));
{ Pass message on to old window procedure }
Result := CallWindowProc(WProc, Handle, Msg, wParam, lParam);
end; initialization
{ Set window procedure of Application window. }
WProc := Pointer(SetWindowLong(Application.Handle, gwl_WndProc,
Integer(@NewWndProc)));
end.

对发给Application.Handle消息的总结:
1. 先过Application.OnMessage这关
2. 过新的过程函数这关
3. 还可继续传递给旧的过程函数
其中SendMessage发送到消息不经过消息泵,因此直接调用过程函数(先执行新的过程函数,再继续传递给旧的)

对发给Application.Handle消息的三次执行(拦截)消息的过程的更多相关文章

  1. runtime第三部分方法和消息

    接上一篇http://www.cnblogs.com/ddavidXu/p/5924049.html 转载来源http://www.jianshu.com/p/6b905584f536 http:// ...

  2. Windows程序设计(第五版)学习:第三章 窗口与消息

        第三章 窗口与消息 1,windows窗口过程:应用程序所创建的每一个窗口都有一个与之关联的窗口过程,用于处理传递给窗口的消息. 2,窗口依据窗口类来创建.窗口类标识了用于处理传递给窗口的消息 ...

  3. Delphi中Message消息的三种使用方法(覆盖WndProc,覆盖消息函数,改写WMCommand)

    实例1 unit Unit1; interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Fo ...

  4. Windows程序设计--(三)窗口与消息

    3.1 窗口的创建 3.1.1 系统结构概述 所谓「Windows给程序发送消息」,是指Windows呼叫程序中的一个函数,该函数的参数描述了这个特定消息.这种位于Windows程序中的函数称为「窗口 ...

  5. Mina、Netty、Twisted一起学(三):TCP消息固定大小的前缀(Header)

    在上一篇博文中,有介绍到用换行符分割消息的方法.但是这种方法有个小问题,如果消息中本身就包含换行符,那将会将这条消息分割成两条,结果就不对了. 本文介绍另外一种消息分割方式,即上一篇博文中讲的第2条: ...

  6. 三.RabbitMQ之异步消息队列(Work Queue)

    上一篇文章简要介绍了RabbitMQ的基本知识点,并且写了一个简单的发送和接收消息的demo.这一篇文章继续介绍关于Work Queue(工作队列)方面的知识点,用于实现多个工作进程的分发式任务. 一 ...

  7. Kafka生产者发送消息的三种方式

    Kafka是一种分布式的基于发布/订阅的消息系统,它的高吞吐量.灵活的offset是其它消息系统所没有的. Kafka发送消息主要有三种方式: 1.发送并忘记 2.同步发送 3.异步发送+回调函数 下 ...

  8. RocketMQ(6)---发送普通消息(三种方式)

    发送普通消息(三种方式) RocketMQ 发送普通消息有三种实现方式:可靠同步发送.可靠异步发送.单向(Oneway)发送. 注意 :顺序消息只支持可靠同步发送. GitHub地址: https:/ ...

  9. 用java开发微信公众号:接收和被动回复普通消息(三)

    上篇说完了如何接入微信公众号,本文说一下微信公众号的最基本功能:普通消息的接收和回复.说到普通消息,那么什么是微信公众号所定义的普通消息呢,微信开发者文档中提到的接收的普通消息包括如下几类: 1.文本 ...

随机推荐

  1. 统计维护<第四篇>

    SQL Server允许用户手工地控制单独数据库中的统计维护.SQL Server的4个主要的控制紫铜统计的维护的配置如下: 在无索引的列上新建统计(自动创建统计): 更新现有统计(自动更新统计): ...

  2. 五子棋AI

    下面是一些参考资料,打算看看: http://www.cnblogs.com/Blog_SivenZhang/archive/2010/06/13/1757677.html http://blog.c ...

  3. 导入旧数据需要 使用date插件

    "@version" => "1", "@timestamp" => "2016-09-12T08:31:06.630 ...

  4. Struts2源代码解读之Action调用

    对于Struts2源代码的分析已经有些时日了,虽然网上有很多解读代码,不过自己还是写一个放上来,供大家参考一下. 解读过程: 直接在action类中打断点(包括构造函数和待执行方法)进行debug调试 ...

  5. ASP.NET MVC3 系列教程 – 新的Layout布局系统

    原文地址:http://www.cnblogs.com/highend/archive/2011/04/18/asp_net_mvc3_layout.html I:回忆MVC2当中MasterPage ...

  6. 12 个 Linux 进程管理命令介绍

    执行中的程序在称作进程.当程序以可执行文件存放在存储中,并且运行的时候,每个进程会被动态得分配系统资源.内存.安全属性和与之相关的状态.可以有多个进程关联到同一个程序,并同时执行不会互相干扰.操作系统 ...

  7. 45 个非常有用的 Oracle 查询语句(转)

    这里我们介绍的是 40+ 个非常有用的 Oracle 查询语句,主要涵盖了日期操作,获取服务器信息,获取执行状态,计算数据库大小等等方面的查询.这些是所有 Oracle 开发者都必备的技能,所以快快收 ...

  8. 虚拟机IOS开发环境搭建教程

    来源:http://www.cnblogs.com/xiaoyaoju/archive/2013/05/21/3091171.html 安装条件: 硬件:一台拥有支持虚拟技术的64位双核处理器和2GB ...

  9. Android UI布局之FrameLayout

    一个FrameLayout对象就好比一块屏幕上提前预定好的空白区域.然后能够填充一些元素到里边.例如说一张图片等.须要注意的是,全部的元素都被放置在FrameLayout区域最左边上的区域.并且无法为 ...

  10. swift中的传值

    光阴似箭,日月如梭,转眼间学习的旅途已经过了一大半了,忘着自己所敲过的成批的代码,看着自己付出和努力,默默地为自己这几个月的奋斗感到欣慰,不论学习的路途再怎么的艰辛,但是自己还是坚持过来了,回想着以往 ...