C Builder中如何利用消息

规范的BCB过程利用Application->Run()进去消息循环,在Application的ProcessMessage措施中,利用PeekMessage措施从消息队列中提取消息,并将此消息从消息队列中移除。然后ProcessMessage措施察看是否存在Application->OnMessage措施。存在则转入此措施处理消息。尔后再将处理过的消息发放给过程中的各个对象。至此,WndProc措施收到消息,并举行处理。万一有无法处理的交给重载的Dispatch措施来处理。要是还不能处理的话,再交给父类的Dispatch措施处理。最后Dispatch措施切实上将消息转入DefaultHandler措施来处理。(嘿嘿,切实上,你一样能够重载DefaultHandler措施来处理消息,然而太晚了一点,我想未曾人甘心最后一个处理消息吧)。

1.TApplication的OnMessage事件的利用
在C++Builder开发的利用过程中,任何窗体接收到一个Windows消息都会引发顺次OnMessage事件,因而,能够穿越相应TApplication对象的OnMessage事件来捉拿任何发送给本过程的Windows消息。


OnMessage的事件的处理函数原型如下:
typedef void __fastcall (__closure *TMessageEvent ) (tagMsg &Msg,bool &Handled );
这个处理函数有两个参数,其中参数Msg表示的是被截获的消息,而参数Handled则用来指示本消息是否曾经处理告终。在过程中能够穿越设置参数Handled为true,以避免后续的过程处理这个消息,反之把Handled设为false则批准后继过程继续处理这个消息。
必需当心的是,OnMessage事件仅仅接受发送到消息队列的消息,而直接穿越API函数SendMessage()发送给窗口函数的消息将不会被截获。另外,当过程运行的时候,OnMessage事件被引发的频率有可能极其高,因而这个事件的处理函数代码厉行工夫将直接波及到全副过程的运行效率。

2.利用消息照射截获消息
C++Builder的VCL供给了对大多数Windows消息的处理机制,对于等闲的利用过程是足够了。然而,VCL也不是森罗万象的。有的情形下,过程必需处理那些VCL处理未曾处理的Windows消息,可能过程必需屏障某些特定的消息时,则就必需过程员自己捉拿Windows消息。
为此C++Builder供给了一种消息照射机制,穿越消息照射过程能将特定的Windows消息与对应的处理函数联系起来,当窗口捉拿到这个消息时就会积极调用对应的处理函数。
利用消息照射有一下几个环节:
(1) 消息照射表,把某些消息的处理权交给自定义的消息处理函数。
这么的消息照射列表该当位于一个组件类的定义中,它以一个未曾参数的BEGIN_MESSAGE_MAP 宏开始,以END_MESSAGE_MAP宏告终。END_MESSAGE_MAP宏的单一参数该当是组件的父类的名字。通常情形下,这个所谓的父类指的即便TForm。在宏BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间插入一个可能是多个MESSAGE_HANDLER 宏。
MESSAGE_HANDLER宏将一个消息句柄和一个消息处理函数联系在同时。
MESSAGE_HANDLER宏有三个参数:Windows消息名、消息构造体名和对应的消息处理函数名。其中,消息构造体名既能够是通用的消息构造体TMessage,也能够是特定的消息构造体,例如TWMMouse。
在利用消息照射的时候要当心以下两点:
a.一个窗口类定义中只能有一个消息照射表。
b.消息照射定然位于它所引用的所有消息处理函数声明的后面。
(2) 在窗口类中声明消息处理函数
这里的消息处理函数名和参数都定然和对应的MESSAGE_HANDLER宏统一。
一个标兵的消息处理函数的声明如下:
void __fastcall 消息处理函数名(消息构造体名 &Message);
例如:
void __fastcall WMNchitTest(TMessage &message);
(3) 告终消息处理函数
消息处理函数的编制和等闲的函数没什么太大的差异,单一不同的是,等闲在此函数的最后要加上一条语句 TForm::Dispatch(&Message),以告终VCL对于消息的默认处理。万一未曾这一句,消息将会被全面堵截;在某些情形下,VCL可能会因为得不到消息而无法工作。

3.重载WndProc()函数
在某些情形下,过程必需捉拿可能屏障某些特定的消息,这时能够用前面推荐的消息照射的措施。当然,这种措施也不是单一的,也能够穿越重载窗口函数WndProc()来告终。因为系统将在调用函数Dispatch()派发消息之前调用窗口函数WndProc(),因而,能够穿越重载函数WndProc()获得一个在分配消息之前过滤消息的时机。
这个消息处理的窗口函数的原型如下:
virtual void __fastcall WndProc(TMessage &Message);
例如:(翔实请看NowCane452.com的例子)
void __fastcall TForm1::WndProc(TMessage &Message)
{
PCOPYDATASTRUCT pMyCDS;
if(Message.Msg==g_MyMsg)
{
ShowMessage("收到登记消息,wParam="+IntToStr(Message.WParam)+" lParam="+IntToStr(Message.LParam));
Message.Result=0;//消息处理的收获,当然在本例中没故含义。
}
else if(Message.Msg==g_MyMsg1)
{
Application->MessageBoxA((char *)Message.LParam,"收到发送方的字符串",MB_OK);
}
else if(Message.Msg==WM_COPYDATA)
{
pMyCDS = (PCOPYDATASTRUCT)Message.LParam;
Application->MessageBoxA((char *)pMyCDS->lpData,"收到发送方的字符串",MB_OK);
}

TForm::WndProc(Message);//其他的消息继续递交下去
}
乍看起来,这和重载Dispatch措施好象差不多。但切实上还是有差异的。差异就在前后次序上,消息是先交给WndProc来处理,最后才调用Dispatch措施的。这么,重载WndProc措施能够比重载Dispatch措施更早一点点获得消息并处理消息。

4.Application->HookMainWindow措施
万一您计划利用Application->OnMessage来捉拿所有发送至您的利用过程的消息的话,您可能要绝望了。它无法捉拿利用SendMessage直接发送给窗口的消息,因为这不穿越消息队列。您可能会说我能够直接重载TApplication的WndProc措施。呵呵,不能够。因为TApplication的WndProc措施被Borland声明为静态的,从而无法重载。显而易见,这么做的起因很可能是Borland担心其所带来的副作用。那该如何是好呢?察看TApplication的WndProc的pascal源码能够看到:
procedure TApplication.WndProc(var Message: TMessage);
... // 节俭篇幅,这里与主题无关代码略去
begin
try
Message.Result := 0;
for I := 0 to FWindowHooks.Count - 1 do
if TWindowHook(FWindowHooks[I]^)(Message) then Exit;
... // 节俭篇幅,这里与主题无关代码略去
WndProc措施一开始先调用HookMainWindow挂钩的自定义消息处理措施,然后再调用缺省过程处理消息。这么利用HookMainWindow就能够在WndProc其中接加入自己的消息处理措施。利用这个措施响应SendMessage发送来的消息很管用。最后提醒一下,利用HookMainWindow挂钩尔后定然要对应的调用UnhookMainWindow卸载钩子过程。给个例子:

void __fastcall TForm1::FormCreate(TObject *Sender)
{
Application->HookMainWindow(AppHookFunc);
}
//---------------------------------------------------------------------------
bool __fastcall TForm1::AppHookFunc(TMessage &Message)
{
bool Handled ;
switch (Message.Msg)
{
case WM_CLOSE:
mrYes==MessageDlg(xg.sy-xghg.com"Really Close??", mtWarning, TMsgDlgButtons() << mbYes <
Handled = false : Handled = true ;
break;
}
return Handled;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
Application->UnhookMainWindow(AppHookFunc);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
SendMessage(Application->Handle,WM_CLOSE,0,0);
}
//---------------------------------------------------------------------------

5.自己发送消息
利用过程也能够像Windows系统一样在窗口可能是组件之间发送消息。C++Builder为此供给了几种门径:利用函数TControl::Perform()可能API函数SendMessage()和PostMessage()向特定的窗体发送消息,可能是利用函数TWinControl::Broadcast()和API函数BroadcastSystemMessage()广播消息。


Perform()函数的作用即便将指定的消息递交给TControl的WndProc过程,实用于所有由TControl类派生的对象,Perform()原型如下:
int __fastcall Perform(unsigned Msg, int WParam, int LParam);
要等到消息处理尔后才归来。


在统一个利用过程的不同学体和控件之间利用函数Perform()是极其方便的。然而这个函数是TControl类的成员函数。也即便说,利用它时,过程定然懂得这个接受消息的控件的实例。而在众多情形下过程并不懂得这个接受消息的窗体的实例而只是懂得这个窗体的句柄,例如,在不同利用过程的窗体之间发送消息就属于这种情形。这时,函数Perform()显明无法利用,取而代之的该当是函数SendMessage()和PostMessage()。


函数SendMessage()和PostMessage()的功能大约上一样,它们都能够用来向一个特定的窗口句柄发送消息。重要的差异是,函数SendMessage()直接把一个消息发送给窗口函数,等消息被处理尔后才归来;而函数PostMessage()则只是把消息发送到消息队列,然后就即刻归来。
这两个函数的原型声明离别如下:
LRESULT SendMessage(HWND hWnd,UINRT Msg,WPARAM,wParam,LPARAM,lParam);
BOOL PostMessage(HWND hWnd,UINT Msg,WPARAM,wParam,LPARAM,lParam);
能够看到,这两个函数参数同函数Perform()极其相仿,只是添置了一个hWnd参数用以表示目标窗口的句柄。


Broadcast()和BroadcastSystemMessage()
函数Broadcast()实用于所有由TWinControl类派生的对象,它能够向窗体上的所有子控件广播消息。其函数原型如下:
void __fastcall Broadcast(void *Message);
能够看到,这个函数只有一个Message参数,它指向被广播的TMessage种类的消息构造体。
函数Broadcast()只能向C++Builder利用过程中的指定窗体上的所有子控件广播消息,万一要向系统中其他利用过程可能窗体广播消息,函数Broadcast()就无能为力了。这时能够利用API函数BroadcastSystemMessage(),这个函数能够向任意的利用过程可能组件广播消息。其函数原型如下:
long BroadcastSystemMessage(
DWORD dwFlags,
LPWORD lpdwRecipients,
UINT uiMessage,
WPAREM wParam,
LPARAM lParam
);

转载于:https://www.cnblogs.com/hanny/p/7782935.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/487319.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android自定义adapter怎么优化,Android必学-BaseAdapter的使用与优化

数据适配器——BaseAdapter可以自定义View或者利用参数中的convertView一、逗比式没有任何优化处理&#xff0c;每次都创建新的View&#xff0c;设置控件&#xff0c;效率极其低下 Overridepublic View getView(int position, View convertView, ViewGroup parent) {//逗比式(没…

Hinton最新演讲透露下一代神经网络模型的构想 | SIGIR 2020

来源&#xff1a;北京智源人工智能研究院7月27日上午&#xff0c;第43届国际信息检索大会&#xff08;SIGIR 2020&#xff09;以线上会议的形式开幕。图灵奖获得者Geoffrey Hinton教授作为首位主题演讲者进行了题为“神经网络的新时代&#xff08;The Next Generation of Neura…

从社会数据到社会智慧的社会计算:新技术、新哲学、新文科

来源&#xff1a;中国指挥与控制学会从社会数据到社会智慧的社会计算&#xff1a;新技术、新哲学、新文科——王飞跃研究员在中国社会科学院大学举办的“计算与人文社科融合创新高端论坛”暨“计算社会科学研究中心”成立大会上的主题报告观点人物介绍王飞跃研究员&#xff0c;…

2017-2018-1 20155338 《信息安全系统设计基础》第七周学习总结

2017-2018-1 20155338 《信息安全系统设计基础》第七周学习总结 教材学习内容总结 Y86-64指令集体系结构 程序员可见状态 概念&#xff1a;Y86程序中的每条指令会读取或修改处理器状态的某些部分&#xff0c;这些称之为处理器的可见状态。 Y86处理器状态可以访问和修改程序寄存…

android动态加home,Android 解决监听home键的几种方法

Android 解决监听home键的几种方法前言&#xff1a;以下两种方法可以完美解决监听back键&#xff0c;home键&#xff0c;多任务键(最近任务键)。一、使用注册广播监听home键、多任务键演示图创建一个广播代码如下&#xff1a;class InnerRecevier extends BroadcastReceiver {f…

英特尔大地震!解雇首席工程官,7纳米延期,或面临集体诉讼……

物联网智库 整理发布转载请注明来源和出处2020年的世界很不太平。纵观全球&#xff0c;疫情、洪水、蝗灾……尽管各种天灾人祸频繁上演&#xff0c;美股却一路向好&#xff0c;苹果、特斯拉等股价飙升。但有人欢喜有人愁&#xff0c;英特尔迎来自己的黑色星期五——上周五股价暴…

开源项目解读 —— Self-Operating Computer Framework # 长期主义 # 价值

价值&#xff1a;生成主函数业务逻辑函数思维导图&#xff0c;帮助理解&#xff0c;PR到开源项目&#xff0c;希望帮助大家理解IPA工作原理&#xff0c;国内没有好的开源项目&#xff0c;我就来翻译分析解读&#xff0c;给大家抛砖引玉。思维导图用文心一言配合其思维导图插件实…

对表格内容进行筛选!

<!DOCTYPE html><head> <meta http-equiv"Content-Type" content"text/html; charsetutf-8" /> <title>Test js</title> </head> <script type"text/javascript"> function onSearch(obj){//js函数开…

android 提供的方法,Android编程之创建自己的内容提供器实现方法

本文实例讲述了Android编程之创建自己的内容提供器实现方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;我们学习了如何在自己的程序中访问其他应用程序的数据。总体来说思 路还是非常简单的&#xff0c;只需要获取到该应用程序的内容 URI&#xff0c;然后借助 Con…

两个几何世界

文章来源&#xff1a;原理━━━━多年前&#xff0c;物理学家在试图弄清楚弦理论的一些细节的过程中&#xff0c;观察到了一种奇异的对应关系&#xff1a;从一种几何世界出现的数字与来自截然不同的几何世界中的极为不同的数字完全匹配。对于物理学家而言&#xff0c;这种对应…

Git 教程学习--第三篇

一、远程仓库 1.先自行注册GitHub账号。由于你本地Git仓库和GitHub仓库之间的传输是通过SSH加密的&#xff0c;所以&#xff0c;需要一点设置 第一步&#xff1a;创建SSH Key。 在用户主目录下&#xff0c;看看有没有.SSH目录&#xff0c;如果有&#xff0c;再看看这个目录下有…

android动态居中布局,Android动态添加布局的两种方式

释放双眼&#xff0c;带上耳机&#xff0c;听听看~&#xff01;前言大多数时候我们布局都是用xml来布局的&#xff0c;但有些时候也是会用到动态布局的&#xff0c;尤其是在一些大项目中&#xff0c;动态布局更是体现的淋漓尽致。所以今天我们就来学习一些动态加添布局的两种方…

看了 72 位图灵奖得主成就,才发现我对计算机一无所知

来源&#xff1a;人工智能AI技术今天是计算机科学之父、人工智能之父 艾伦麦席森图灵 诞辰 108 周年。作为“图灵意志”的传承者&#xff0c;依照惯例&#xff0c;在今日纪念这位伟人。从“图灵机”到“图灵测试”&#xff0c;从破译德军的 Enigma 到自杀之谜&#xff0c;图灵一…

android 怎么改变字体颜色,安卓系统字体颜色修改教程

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼反编辑framework-res.apk1.修改内容如下&#xff1a;打开res/values/colors.xml找到 回编辑后需要把你在apk中的改过的xml文件替换到原版apk中&#xff0c;修改了带value字样文件夹下的xml要替换apk中resources.arsc这个文件#ffc8c…

prop attr 到底哪里不一样?

好吧 首先承认错误 说好的每天进行一次只是总结 但是我没坚持住 准确的来说 我并没有每天会学到了东西 但是 我一直在持续努力着 以后应该不会每天都写 但是自己觉得有用的 或者想加强记忆的 可能会写出来 我前段时间 看书的时候 注意到prop() 但是一直没用到过 今天就探…

【深度学习】解析深度神经网络背后的数学原理

来源&#xff1a;产业智能官解析深度网络背后的数学如今&#xff0c;已有许多像 Keras, TensorFlow, PyTorch 这样高水平的专门的库和框架&#xff0c;我们就不用总担心矩阵的权重太多&#xff0c;或是对使用的激活函数求导时存储计算的规模太大这些问题了。基于这些框架&#…

unity android 分包,Unity以分包(obb)形式集成到安卓原生 我慢慢填坑

Unity以分包(obb)形式集成到安卓原生 我慢慢填坑Unity以分包(obb)形式集成到安卓原生 我慢慢填坑工作中有需要将unity项目集成到安卓原生中&#xff0c;随着工作推进需要分包去发布到google &#xff0c;那么这时候就需要在unity出包时进行分包(android project obb)。使用方法…

73岁Hinton老爷子构思下一代神经网络:属于无监督对比学习

机器之心报道编辑&#xff1a;魔王、杜伟在近期举行的第 43 届国际信息检索年会 (ACM SIGIR2020) 上&#xff0c;Geoffrey Hinton 做了主题为《The Next Generation of Neural Networks》的报告。Geoffrey Hinton 是谷歌副总裁、工程研究员&#xff0c;也是 Vector Institute 的…

面向对象引子

描述两个角色: 1 def hum(name,age,job):2 """这是代表一个人"""3 data {4 name:name,5 age:age,6 job:job7 }8 9 return data 10 11 def dog(name,type): 12 """这是代表一条旺财…

下一个十年的C位:物联网产业全景解析

来源&#xff1a;北京物联网智能技术应用协会导语&#xff1a;庄子曰&#xff1a;“天地与我并生&#xff0c;而万物与我为一”庄子将天地万物与人平等对待&#xff0c;打破了“以人类为中心”的桎梏。如果说互联网是以“人的需求”为中心构建的&#xff0c;那么物联网&#xf…