C++Builder 自定义消息 处理 总结
2010-03-22 21:23
477 查看
这几天忙着弄一个SSDT HOOK驱动,一环扣一环啊,无奈要去理解一下C++Builder是怎么定义自定义消息的。网上资料很多,看了几篇,觉得有必要总结下。也希望找到这篇文章的同志,可以省点力气...
首先,简单讲一下C++Builder的消息机制,BCB的消息处理集成在每个控件类中,首先主窗口有一个最大的消息处理循环函数MainWndProc,这个函数针对一些由BCB特定的消息做处理,其他的则交给WINAPI函数WndProc来处理,这个函数是虚拟函数,在子类中可以具体制定相应的处理函数。WndProc函数也只是初步处理消息,最后还是要调用控件类自己定义的Dispatch函数,这个函数也能被重写,这点告诉我们,我们可以重新写一个DisPatch函数来处理我们自定义的消息。这就是以下的第一种方法:
第一种方法:
在TForm1窗体类中的private成员区中加上:
void __fastcall Dispatch(void * Message);//overwrite····
在cpp中的实现为:
void __fastcall TForm1::Dispatch(void * Message)
{
TForm::Dispatch(Message);
PMessage pMsg=(PMessage)Message;
if(pMsg->Msg==(unsigned int)msgnum)
ShowMessage(AnsiString(msgnum)); //接收消息
}
其中msgnum为RegisterWindowMessage("MSG_MY");
有人会问,如果这样重写了,那么系统其他发往本程序或者控件的消息会不会失去处理了呢?答案是否定的,BCB里采用了一套机制来防止这种情况,大概的原理是,先让用户的函数来处理函数,处理完毕后交给它本身所提供的函数来处理。注意可不能为它指定不是自定义消息的处理,也就是if后不能有else,不然BCB为我们定义的其他消息的处理都会被屏蔽掉。
我的理解:
Func(消息msg)//系统对用户代码整合后的代码
{
if(msg可以被用户的代码接受处理)
exe it;//执行
else//用户没有对该msg处理,也就是系统消息
{
原先定义好对系统消息处理的代码;//dispatch
}
}
//具体如何判断某个消息用户定义的代码不能处理,这个我也在考虑,困难的是,这个dispatch是个无返回值的函数;等我知道了,如果我记得的话,我就来添加上....大家有想法的,也可以和我讨论:QQ542561233
第二种方法:
BCB为了方便用户,尤其是一些BCB形式编程的忠实爱好者,特意精心定义了一个宏,来申明一个自定义消息,不过这种方法有局限性,比如你只能处理一个预先自己定义的(如#define MSG_MY (WM_USER+4) 4为自己赋值的值)的消息。方式如下:
#define MSG_MY1 (WM_USER+3)
...
在TForm1窗体类中的private成员区中加上:
void __fastcall WinProc(TMessage&Msg);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(MSG_MY2, TMessage, WinProc)
END_MESSAGE_MAP(TForm)
函数实现:
void __fastcall TForm1::WinProc(TMessage&Msg)
{
if(Msg.Msg==MSG_MY)
{
ShowMessage(AnsiString(MSG_MY));
// ShowMessage("Receive!");
}
}
首先,简单讲一下C++Builder的消息机制,BCB的消息处理集成在每个控件类中,首先主窗口有一个最大的消息处理循环函数MainWndProc,这个函数针对一些由BCB特定的消息做处理,其他的则交给WINAPI函数WndProc来处理,这个函数是虚拟函数,在子类中可以具体制定相应的处理函数。WndProc函数也只是初步处理消息,最后还是要调用控件类自己定义的Dispatch函数,这个函数也能被重写,这点告诉我们,我们可以重新写一个DisPatch函数来处理我们自定义的消息。这就是以下的第一种方法:
第一种方法:
在TForm1窗体类中的private成员区中加上:
void __fastcall Dispatch(void * Message);//overwrite····
在cpp中的实现为:
void __fastcall TForm1::Dispatch(void * Message)
{
TForm::Dispatch(Message);
PMessage pMsg=(PMessage)Message;
if(pMsg->Msg==(unsigned int)msgnum)
ShowMessage(AnsiString(msgnum)); //接收消息
}
其中msgnum为RegisterWindowMessage("MSG_MY");
有人会问,如果这样重写了,那么系统其他发往本程序或者控件的消息会不会失去处理了呢?答案是否定的,BCB里采用了一套机制来防止这种情况,大概的原理是,先让用户的函数来处理函数,处理完毕后交给它本身所提供的函数来处理。注意可不能为它指定不是自定义消息的处理,也就是if后不能有else,不然BCB为我们定义的其他消息的处理都会被屏蔽掉。
我的理解:
Func(消息msg)//系统对用户代码整合后的代码
{
if(msg可以被用户的代码接受处理)
exe it;//执行
else//用户没有对该msg处理,也就是系统消息
{
原先定义好对系统消息处理的代码;//dispatch
}
}
//具体如何判断某个消息用户定义的代码不能处理,这个我也在考虑,困难的是,这个dispatch是个无返回值的函数;等我知道了,如果我记得的话,我就来添加上....大家有想法的,也可以和我讨论:QQ542561233
第二种方法:
BCB为了方便用户,尤其是一些BCB形式编程的忠实爱好者,特意精心定义了一个宏,来申明一个自定义消息,不过这种方法有局限性,比如你只能处理一个预先自己定义的(如#define MSG_MY (WM_USER+4) 4为自己赋值的值)的消息。方式如下:
#define MSG_MY1 (WM_USER+3)
...
在TForm1窗体类中的private成员区中加上:
void __fastcall WinProc(TMessage&Msg);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(MSG_MY2, TMessage, WinProc)
END_MESSAGE_MAP(TForm)
函数实现:
void __fastcall TForm1::WinProc(TMessage&Msg)
{
if(Msg.Msg==MSG_MY)
{
ShowMessage(AnsiString(MSG_MY));
// ShowMessage("Receive!");
}
}
相关文章推荐
- C++Builder 自定义消息 处理
- 总结:发送自定义消息
- Windows消息队列,UI线程,窗口以及消息处理方式总结
- Windows消息队列,UI线程,窗口以及消息处理方式总结 .
- 使用VC如何处理自定义消息
- 在.net(C# or vb.net)中如何用户自定义消息,并在窗体中处理这些消息。
- 为何在自定义消息处理函数中无法利用wParam或lParam传递指针?
- NSNotificationCenter 处理自定义消息
- C# 消息处理机制及自定义过滤方式
- 自定义View想使用Scroller实现滑动效果,但是事件接收出现问题,只收到ACTION_DOWN,而无法收到ACTION_MOVE, ACTION_UP等消息的处理
- 处理自定义消息
- 利用自定义消息处理函数的WPARAM或LPARAM参数传递指针
- 自定义消息处理功能(是小化程序到托盘)
- C# 收发和处理自定义的WINDOWS消息
- c#如何处理自定义消息
- EasyNetQ自定义异常消息处理
- Android自定义View滑动事件处理总结
- VC++如何处理自定义消息
- C++Builder非可视组件的消息处理技巧
- 如何处理窗口叠加时的自定义消息路由