2024年4月17日发(作者:)

C++Builder 自定义消息处理总结

这几天忙着弄一个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);

PMessagepMsg=(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 __fastcallWinProc(TMessage&Msg);

BEGIN_MESSAGE_MAP

MESSAGE_HANDLER(MSG_MY2, TMessage, WinProc)

END_MESSAGE_MAP(TForm)

函数实现:

void __fastcall TForm1::WinProc(TMessage&Msg)

{

if(==MSG_MY)

{

ShowMessage(AnsiString(MSG_MY));

// ShowMessage("Receive!");

}

}

C++Builder中实现自定义消息响应最简单的方法

启动C++builder后,新建一个新的应用程序,在编辑主窗体头文件unit1.h里加入,消息值

#define MY_MSGVALUE WM_APP + 1

而关于消息映射部分,完全不用手工去编写,你可以用代码编辑器中的类浏览器(ClassExplore)来完成。展

开类浏览器中的显示,在Form1上单击鼠标右键,选择"New Method."来加入一个新的方法。加入的方法名

称Method Name为MyMsgHadleMethod,Ddd to Class里选择TForm1,Arguments为

Tmessage&Msg,Method type选择为Function,Function Result选择为void, Visibiliy选择为protected,

Directives 选择为__fastcall,选中 Message Handle,并输入MY_MSGVALUE,点OK

,查看.cpp,.h文件,你会发现新加了消息映射部分,还有消息响应函数,

触发消息的方法有:

PostMessage(Handle,MY_MSGVALUE,0,0);

SendMessage(Handle,MY_MSGVALUE,0.0);

this->Perform(MY_MSGVALUE,0,0);

1,在头文件(.h)中:

#define WM_MYMESSAGE WM_USER+1 //自定义消息名称与消息

号,WM_USER是由系统定义的用户自定义消息可以使用的最小号

2,仍在头文件中:

class TForm1:public TForm

{

private:

//自定义消息响应函数

void __fastcall MyMessage(TMessage &Message);

public:

//建立消息映射关系

BEGIN_MESSAGE_MAP

VCL_MESSAGE_HANDLER(WM_MYMESSAGE, TMessage, MyMessage

);

END_MESSAGE_MAP(TForm);

};

3,在实现文件中,声明自定义消息响应函数:

void __fastcall TForm1::MyMessage(TMessage &Message)

{

....

}

4,发送自定义消息的方法:

{

PostMessage(Form1-> Handle, UM_MYMESSAGE, 0, 0);

}

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

Inprise(Borland) C++Builder中,可以象在Delphi中一样响应消息,只是看起来要稍复杂一点。

对于系统已定义的消息,可以直接响应:

#define WM_MY_OPEN_CMDLINE_FILE (WM_USER+1) //进程间通讯的自定义消息

#define WM_MY_SEARCH_NODE (WM_USER+2) //查找命令的自定义消息

class TSomeForm : public TForm

{

//...类中的其它代码

protected:

//消息的响应过程

void __fastcallOpenCmdLineFile(TMessage Message);

void __fastcallSearchDocumentNode(TMessage Message);

void __fastcallGetWindowMinMaxInfo(TWMGetMinMaxInfo Message);

//以下通过宏定义实现消息的正确响应

BEGIN_MESSAGE_MAP

MESSAGE_HANDLER(WM_MY_OPEN_CMDLINE_FILE, TMessage, OpenCmdLineFile)

MESSAGE_HANDLER(WM_MY_SEARCH_NODE, TMessage, SearchDocumentNode)

MESSAGE_HANDLER(WM_GETMINMAXINFO , TWMGetMinMaxInfo, GetWindowMinMaxInfo)

END_MESSAGE_MAP(TForm)

};//end class

//以下为实现代码

void __fastcallTSomeForm::OpenCmdLineFile(TMessage Message)

{//直接通过消息结构传递参数

LPSTR lpCmdLine=(LPSTR);//从Message中取得参数

this-$#@62;HandleCmdLineFile(lpCmdLine);//处理命令行的参数

return;

}

void __fastcallTSomeForm::SearchDocumentNode(TMessage Message)

{//响应查找消息

//Message中的参数在此处不需要。

this-$#@62;SearchNode();

return;

}

void __fastcallTSomeForm::GetWindowMinMaxInfo(TWMGetMinMaxInfo Message)

{//设置主窗口的最小尺寸

MINMAXINFO *MinMaxInfo=Info;

MinMaxInfo-$#@62;ptMinTrackSize.x=400;

MinMaxInfo-$#@62;ptMinTrackSize.y=300;

return;

}

其中:TMessage和TWMGetMinMaxInfo类型的定义可参见:

C:;其它的消息响应方法与此相同。

另外,可以为自定义的消息也定义一个对应的消息结构(如:TSearchNode_Message),至于如何定义

消息结构, 可以参考:C:Program Fil