对发给Application.Handle消息的三次执行(拦截)消息的过程

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, 0, 0);
end;

procedure TMainForm.PostBtnClick(Sender: TObject);
begin
  PostMessage(Application.Handle, WM_USER, 0, 0);
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发送到消息不经过消息泵,因此直接调用过程函数(先执行新的过程函数,再继续传递给旧的)

时间: 2025-01-05 14:50:03

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

runtime第三部分方法和消息

接上一篇http://www.cnblogs.com/ddavidXu/p/5924049.html 转载来源http://www.jianshu.com/p/6b905584f536 http://southpeak.github.io/2014/10/30/objective-c-runtime-2/ 方法和消息  OC中对象调用方法,实际是给对象发送消息 SEL又叫选择器,是表示一个方法的selector的指针,其定义如下: typedef struct objc_selector *SE

基于Netty的聊天系统(三)协议定制----消息篇

今天我们继续来讨论协议,今天基本就把一对一聊天的协议定制完毕了,上一篇我们讲述了登录的过程,那么登录完毕就是聊天了,首先我们还是以A和B为例子,A发送消息给B,那么这条消息的的协议如下 发送消息协议: {"id":"xxxx","#":"msg","text":"内容","to":"接收用户ID","type":0,"

RocketMQ(三)分布式开放消息系统(RocketMQ)的原理与实践

备注: 1.如果您此前未接触过RocketMQ,请先阅读附录部分,以便了解RocketMQ的整体架构和相关术语 2.文中的MQServer与Broker表示同一概念 分布式消息系统作为实现分布式系统可扩展.可伸缩性的关键组件,需要具有高吞吐量.高可用等特点.而谈到消息系统的设计,就回避不了两个问题: 消息的顺序问题 消息的重复问题 RocketMQ作为阿里开源的一款高性能.高吞吐量的消息中间件,它是怎样来解决这两个问题的?RocketMQ 有哪些关键特性?其实现原理是怎样的? 关键特性以及其实现

进程-IPC 共享内存和消息队列 (三)

详见:https://github.com/ZhangzheBJUT/linux/blob/master/IPC(%E4%B8%89).md 五 共享内存 5.1. 共享内存简介 共享内存指多个进程共享同一块物理内存,它只能用于同一台机器上的两个进程之间的通信.在进程的逻辑地址空间中有一段地址范围是用来进行内存映射使用的,该段逻辑地址空间可以映射到共享的物理内存地址上(进程空间介绍:http://blog.csdn.net/zhangzhebjut/article/details/3906025

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

上篇说完了如何接入微信公众号,本文说一下微信公众号的最基本功能:普通消息的接收和回复.说到普通消息,那么什么是微信公众号所定义的普通消息呢,微信开发者文档中提到的接收的普通消息包括如下几类: 1.文本消息2.图片消息3.语音消息4.视频消息5.小视频消息6.地理位置消息7.链接消息(被动回复的消息) 被动回复的普通消息包括: 1.回复文本消息2.回复图片消息3.回复语音消息4.回复视频消息5.回复音乐消息6.回复图文消息 其实接收消息和被动回复消息这两个动作是不分家的,这本来就是一个交互场景,一

关于MQ的几件小事(三)如何保证消息不重复消费

1.幂等性 幂等(idempotent.idempotence)是一个数学与计算机学概念,常见于抽象代数中. 在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同.幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数.这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变.例如,"setTrue()"函数就是一个幂等函数,无论多次执行,其结果都是一样的.更复杂的操作幂等保证是利用唯一交易号(流水号)实现. 简单来说,幂等性就是一个数据

Oozie 生成JMS消息并向 JMS Provider发送消息过程分析

一,涉及到的工程 从官网下载源码,mvn 编译成 Eclipse工程文件: 对于JMS消息这一块,主要涉及到两个工程: oozie-core工程有问题的原因是还需要一些其他的依赖工程未导入: 二,Oozie 生成 JMS消息 主要涉及到的一些类 oozie-core 工程中的: oozie-client工程中的: 三,相关代码: 对于Oozie Server而言,它是消息的生产者.在oozie-default.xml/oozie-site.xml里面配置好连接参数,消息服务器....Oozie就

JMS消息服务器(二)——点对点消息传送模型

一.点对点模型概览 当你只需要将消息发布送给唯一的一个消息消费者是,就应该使用点对点模型.虽然可能或有多个消费者在队列中侦听统一消息,但是,只有一个且仅有一个消费者线程会接受到该消息. 在p2p模型中,生产者称为发送者,而消费者则称为接受者.点对点模型最重要的特性如下: 消息通过称为队列的一个虚拟通道来进行交换.队列是生产者发送消息的目的地和接受者消费消息的消息源. 每条消息通仅会传送给一个接受者.可能会有多个接受者在一个队列中侦听,但是每个队列中的消息只能被队列中的一个接受者消费. 消息存在先

IPC消息从发送者传递到接收者的过程

以Render进程向Browser进程发送IPC消息的情景为例,IPC::Sender即为RenderThreadImpl,而IPC::Listener即为RenderProcessHostImpl.IPC::Sender既可以通过ChannelProxy发送IPC消息,也可以通过SyncChannel发送IPC消息.两者的区别在于后者可以发送同步IPC消息.所谓同步IPC消息就是发送者将IPC消息发送给接收者之后,会等待接收者回复一个IPC消息.虽然原则上我们建议使用异步IPC消息,但是某些情