C++ BUILDER 消息处理的深入探索

C++Builder 自定义消息 处理 总结 这几天忙着弄一个SSDT HOOK驱动,一环扣一环啊,无奈要去理解一下C++Builder是怎么定义自定义消息的。网上资料很多,看了几篇,觉得有必要总结下。也希望找到这篇文章的同志,可以省点力气...首先,简单讲一下C++Builder的消息机制,BCB的消息处理集成在每个控件类中,首先主窗口有一个最大的消息处理循环函数MainWndProc,这个函数针对一些由BCB特定的消息做处理,其他的则 阅读详情

在本文中我將告訴你如何以C++Builder來處理Windows訊息,並透過此一能力,來達成在一般VCL元件所無法做到的功能。

何謂Window訊息(Message)

 大家都知道 Windows是一套以訊息驅動(Message Driven)的作業系統。然而對於訊息本身卻諱莫如深,只知其然而不知其所以然,雖然C++Builder將某些Windows訊息封裝於事件(Event)系統中,但身為一個Windows程式設計師,實有必要瞭解Windows的訊息系統。

所謂訊息是由Windows作業系統送往程式的事件。它是系統中各個物件溝通的方式,舉例來說,當移動滑鼠、按下滑鼠鍵、改變視窗大小時,Windows都會送出訊息以通知程式。當然,為了要辨別事件的內容,Windows系統中定義了許多的訊息,如WM_PAINT,WM_CHAR等等。

當事件發生時,Windows會判斷該事件必須由那個程式接收,然後將事件以訊息的方式送往程式的視窗中。雖然在Windows系統中包含了數以百計的事件,但是作業系統並沒有為各個事件設計不同的訊息結構,而是以一個一般性的結構來描述訊息,這個結構在C++Builder就稱是TMessage。

當然,隨著事件的不同,對於訊息的解釋也有所不同,在C++Builder中也為各種常用的訊息定義了專屬的結構,你可以直接使用它們來解釋訊息。這些訊息定義在C++Builder目錄下的Include/vcl/messages.hpp中,你可以決定要自行解釋TMessage參數或是直接將其轉換成專屬的結構。很抽象嗎?我舉個例子吧,以WM_NCHITTEST訊息來說,C++Builder為它定義了TWMNCHitTest的專屬結構,所以你可以直接經由它來得到XPos、YPos等值。或者你也可以直接由TMessage的LParam取得其值,端看你使用的方便。仔細觀察TMessage及TWMNCHitTest兩個結構,你會發現它們是等價的,也就是說它們的大小是一致的,因此你可以直接用強制轉型互相轉換(這有點類似union的方法)。

struct TMessage

{

Cardinal Msg;

union

{

struct

{

Word WParamLo;

Word WParamHi;

Word LParamLo;

Word LParamHi;

Word ResultLo;

Word ResultHi;

};

struct

{

long WParam;

long LParam;

long Result;

};

};

};

struct TWMNCHitTest

{

Cardinal Msg;

long Unused;

union

{

struct

{

Windows::TSmallPoint Pos;

long Result;

};

struct

{

short XPos;

short YPos;

};

};

} ;

在收到訊息後,程式必須處理該訊息,若是不處理,則可直接將它交給Windows的內定處理程序來處理之,若是程式需要傳回值,也可以在此時傳回,Windows會將該值傳回給呼叫方。如此就完成了訊息傳遞的程序。

WM_NCHITTEST訊息的奧秘

WM_NCHITTEST訊息是一個很特殊的訊息。它是用來決定目前滑鼠所在位置屬性的訊息,因此我們可以利用此特性,當滑鼠移至指定的位置時,傳回 HTCAPTION,使得系統以為滑鼠目前位於標題棒,如此你就可以移動視窗了。如何?是不是很神奇呢?

由上可知,只要我們適時地攔截WM_NCHITTEST訊息,然後傳回HTCAPTION,就可以順利地欺騙系統,達成在任何位置模擬出標題棒的效果。

C++ Builder的處理訊息的巨集

在C++Builder為了處理訊息的方便,因此定義了三個處理訊息的巨集(Macro)。

BEGIN_MESSAGE_MAP

MESSAGE_HANDLER(WM_NCHITTEST,TMessage,OnNcHitTest)

END_MESSAGE_MAP(TForm)

以上的三個巨集BEGIN_MESSAGE_MAP、MESSAGE_HANDLER及END_MESSAGE就是C++ Builder定義的巨集,其中比較重要的是MESSAGE_HANDLER;它共需要三個參數,第一個參數代表訊息的ID,第二個代表參數型態,最後一個則是訊息事件處理函數。

乍看之下,這個巨集似乎和MFC及OWL所使用的巨集有幾分神似,沒錯,不過其機制卻更為簡單及簡潔,我們可以看看C++Builder對於這三個巨集的原始定義:

#define BEGIN_MESSAGE_MAP virtual void __fastcall Dispatch(void *Message) /

{ /

switch (((PMessage)Message)->Msg) /

{

#define MESSAGE_HANDLER(msg,type,meth) /

case msg: /

meth(*((type *)Message)); /

break;

#define END_MESSAGE_MAP(base) default: /

base::Dispatch(Message); /

break; /

} /

}

相較於MFC或 OWL的可怕巨集,它實在是簡單多了,這是因為C++Builder已替你完成了大部份的工作。其實若我們把以上的巨集展開後,可以得到以下的結果:

virtual void __fastcall Dispatch(void *Message)

{

switch (((PMessage)Message)->Msg)

{

case WM_NCHITTEST:

OnNcHitTest(*((TMessage *)Message));

break;

default:

TForm::Dispatch(Message);

break;

}

}

怎麼樣?展開之後是不是有恍然大悟的感覺,要弄清楚這個巨集在賣啥膏藥是很容易的,如果你玩過MFC的訊息處理機制,再看到以上的巨集,相較之下,實在是小兒科,不過也就因其簡單,所以C++Builder的優勢益加彰顯。

我簡單地說明以上的程式:在每個TForm中都定義一個名為Dispatch的虛擬函式,它就是用來處理Windows的訊息的,在大部份情況下,訊息都是呼叫C++Builder所提供的處理函式,因此你不需要修改它。

換句話說,我們只要改寫Dispatch函式,就可以藉以處理指定的訊息了。前面提到的三個巨集只是將這個程序簡化而已,沒什麼大不了。

C++ Builder消息处理过程及应用 C++ Builder作为一种RAD方式的程序开发工具,其全新的可视化编程环境、面向组件的开发模式无疑会大大地提高编程效率。它对繁杂的Windows 消息及API作了较全面的封装,编程者在大多数情况下不需理会Windows消息的细节,只要将心思放在组件的事件处理函数上即可。  然而,毕竟Windows操作系统是一个以消息驱动的系统,运行其上的应用程序,自然无法脱离系统之外,因此掌握并运用消息处 阅读详情

相关推荐

C++ builder消息的运用

一、TApplication的OnMessage事件 OnMessage事件只处理消息队列中的消息,SendMessage()发送的消息不会被截获。 任何窗体接收到一个windows消息,都会触发一次此事件 函数原型: typedef void __fastcall (__closure *TMessageEvent) (tagMSG &Msg,bool &Handled); Msg表示

NickWei的博客 4367

DirectX 9 SDK for Borland C++ Builder简介

DirectX 9 SDK for Borland C++ Builder

C++ builder 自定义控件

在我们开发过程因为软件的需要 很多的系统控件满足不了我们的需求,这个时候就需要我们通过自定义的控件来完成任务 一 自定义控件: 1 新建一个包 File->New->Package 2 再包中点击右键 Add New->Other->C++ builder files 选择Component 如下图所示 3 点击ok ,选择继承的类 4 下一步  其中 cl

u010442009的专栏 3029

C++ Builder处理Windows 讯息(Message

C++ Builder处理Windows 讯息(Message)前言虽然C++Builder为一RAD式的程式发展工具,程式设计师在大多数情况下不需理会Windows讯息的细节,只要将心思放在软体元件的事件处理函式即可。然而由於Windows作业系统终究是一个以讯息驱动的系统,因此架构其上的的应用程式自然无法自外於系统之外,在遭遇到C++Builder没有定义的事件时,Windows讯息

近山者仁 1497

VS2010/MFC编程入门之五(MFC消息映射机制概述)

原文:http://www.jizhuomi.com/software/147.html 前面已经说过,Windows应用程序是消息驱动的。在MFC软件开发中,界面操作或者线程之间通信都会经常用到消息,通过对消息的处理实现相应的操作。比较典型的过程是,用户操作窗口,然后有消息产生,送给窗口的消息处理函数处理,对用户的操作做出响应。        什么是消息        窗口消息

白话机器学习 1569

C++Builder中如何应用消息(转)

标准的BCB程序使用Application->Run()进入消息循环,在Application的ProcessMessage方法中,使用PeekMessage方法从消息队列中提取消息,并将此消息从消息队列中移除。然后ProcessMessage方法检查是否存在Application->OnMessage方法。存在则转入此方法处理消息。之后再将处理过的消息分发给程序中的各个对象。至此,WndProc

闪电侠的家园 4813

C++ builder 控件消息重载

最近在工作需要写一个功能就是把在P

明明先生的专栏 1216

C++ BUILDER 消息处理的深入探索

C++ BUILDER 消息处理的深入探索 在本文中我將告訴你如何以C++Builder來處理Windows訊息,並透過此一能力,來達成在一般VCL元件所無法做到的功能。 何謂Window訊息(Message)  大家都知道 Windows是一套以訊息驅動(Message Driven)的作業系統。然而對於訊息本身卻諱莫如深,只知其然而不知其所以然,雖然C++Builder將某些W

diligentcat的专栏 822

C++ BUILDER 消息处理的深入探索 (转)

C++ BUILDER 消息处理的深入探索 (转)[@more@]在本文中我將告訴你如何以C++Builder來處理windows訊息,並透過此一能力,來達成在一般VCL元件所無法做到的功能。 何謂Window訊息(Mess...

csobhtdx34120的博客 90

C++Builder 资料库

1.怎样在C++Builder中创建使用DLL 2.用C++Bulider在WIN.INI中保存信息 3.如何在C++Builder中检测硬件 4.C++Builder如何响应消息及自定义消息 5.利用C++ Builder开发动画DLL 6.用C++ Builder 3制作屏幕保护程序 7.TCP/IP头格式 8.UDP 9.判断windows的Desktop及其它目录 10用C++Builde

chiengod(钱神爷)的专栏 2万+

C++ Builder中消息机制的研究与应用技巧

     C++ Builder作为一种RAD方式的程序开发工具,提供了功能强大的集成开发环境。C++ Builder提供的VCL组件,封装了Windows的底层API和具体实现细节,也提供了对组件消息机制的良好封装。比如,可以对按钮控件(TButton)的单击、按下、拖动等事件消息设置相应的处理函数,并在对应的函数体中实现对该消息的处理与响应。虽然C++ Builder对VCL组件的消息

xjq2003的专栏 1631

Android c++层 Handler分析和使用

文章目录1. C++层的Looper分析1. C++层的Handler: MessageHandler2. C++ Messagehandler的使用3. Looper::sendMessage 流程4. addFd函数2. 总结: 1. C++层的Looper分析 文件: platform/system/core/include/utils/Looper.h platform/system/c...

Nothing_Blog 4210

C++ builder 关于MessageDlg的用法

if(MessageDlg("要删除当前记录码?",mtConfirmation,TMsgButtons()<<mbYes<<mbNo,0)==mrYes) { ADOTable1->Delete(); }

lzksword的专栏 895

深入C++ Builder之编写自己的元件-深入分析VCL继承、消息机制(1)

这篇文章提及内容可能大家已经在很多地方看到过了,作者也是如此,只不过还看了很多VCL源代码,加上自己实际编写元件的经验,拼凑了这么一篇文章。所以所有言论都是个人观点、经验的描述,仅供参考。你可转载,拷贝,但必须加入作者署名Aweay,如果用于商业目的,必须经过作者同意。系统要求如果你想一起跟着做的话,那么你应该看看这里,否则你可以直接跳过。C++ Builder6 + updata4 

Siney的BlOG http://www.sineysoft.com 2612

C++Builder如何响应消息及自定义消息

C++Builder如何响应消息及自定义消息     Inprise(Borland) C++Builder中,可以象在Delphi中一样响应消息,只是看起来要稍 复杂一点。     对于系统已定义的消息,可以直接响应:   #define WM_MY_OPEN_CMDLINE_FILE (WM_USER+1) //进程间通讯的自定义消息 #define WM_MY_

diligentcat的专栏 1784

C++Builder消息运用

一、TApplication的OnMessage事件  OnMessage事件只处理消息队列中的消息,SendMessage()发送的消息不会被截获。  任何窗体接收到一个windows消息,都会触发一次此事件  函数原型:  typedef void __fastcall (__closure *TMessageEvent) (tagMSG &Msg,bool &Handled)

tbwork 1592
上一篇: Viewing Assembly Permissions
下一篇: Another Way to Drag a Window
peachblossom
博客等级 码龄25年 1粉丝 7原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值