谁能和我说CB中消息的处理和自定义的用法.小弟不是很明白.谢谢大家,进来看一下也好!

nolovedqboy 2003-08-18 06:43:07
CB中有他自己默认的消息,我们也可以自定义消息,如果用他默认的消息是用
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_SYSCOMMAND, TMessage, WMSysCommand);
END_MESSAGE_MAP(TCustomForm)
这个里面是可以更改系统的消息的,好像我在下面消息的触发是在最小化之后我再单击一下还原时才触发的,而我这边不是定义了一最小化就触发吗?
void __fastcall TForm1::WMSysCommand(TMessage &Message)
{
TWinControl::Dispatch(&Message);

// 处理最消化的命令
if (Message.WParam == SC_MINIMIZE)
{
ShowMessage("hello");
}
}
还有当我自己定义一个消息时,应怎么办?
Message.WParam这个里面的WParam,好像还有LParam,这些有什么区别啊?
第二个问题:
const int WM_NC_NOTIFY = (WM_USER + 1);
// 处理自定义通知消息
void __fastcall TForm1::WMNCNotify(TMessage &Message)
{
TWinControl::Dispatch(&Message);

if (Message.Msg == WM_NC_NOTIFY)
{
switch (Message.LParam)
{
case WM_LBUTTONDBLCLK: // 双击左键还原程序
............
break;
case WM_RBUTTONUP: // 松开右键
// 其它处理
break;
}
}
}
这个上面的又是什么意思啊?"Message.Msg",Message中有Msg这个吗?他那个LParam是什么意思呢?我觉得直接捕捉就可以了啊?

请高手指点,万分感激!
...全文
62 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
skydqboy 2003-08-24
  • 打赏
  • 举报
回复
.h
const int WM_NC_NOTIFY = (WM_USER + 1); //自定义消息
const int WM_NC_TRAYID = (WM_USER + 2); //参数
const int WM_NC_TRAYID1 = (WM_USER + 3); //参数
.cpp
void __fastcall TForm1::Button1Click(TObject *Sender)
{
PostMessage(Handle,WM_NC_NOTIFY,WM_NC_TRAYID,0);
ShowMessage("Button1 Show");
}
//----------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
PostMessage(Handle,WM_NC_NOTIFY,WM_NC_TRAYID1,0);
ShowMessage("Button3 Show");
}
//----------------------------------------------------------
// 处理自定义通知消息
void __fastcall TForm1::WMNCNotify(TMessage &Message)
{
switch (Message.WParam) {
case WM_NC_TRAYID : ShowMessage("Button1 SHOW");break;
case WM_NC_TRAYID1 : ShowMessage("Button3 SHOW");break;
}
}

这样好像样可以用的,能显示出这个消息出来,你们帮我看看,这是我杜撰出来的,有没有什么规范什么之类东西的,我上面的有没有什么要改进的,帮我看看呢!
我对这个有一点明白了.
Behard 2003-08-24
  • 打赏
  • 举报
回复
消息编号指的是 PostMessage 函数的第一个参数???
写错了
应该是第二个
Behard 2003-08-24
  • 打赏
  • 举报
回复
1. 使用 BEGIN_MESSAGE_MAP 方式时,PostMessage 触发的函数里不需要判断
if (Message.Msg == WM_NC_NOTIFY)
因为只有这个消息才会进入这个处理函数
2. 使用重载 WndProc 时,是进入了整个 Form 的消息处理函数
这样必须分开处理,也就是你需要拦截哪一个消息来处理
对于不需要处理调用 TForm::WndProc(Message); 即可

TO:sczyq(我又...........) ,消息编号(WParam,LParam)是事先约定好了的.这句话怎么样理解呢?消息什么时候才触发呢?

消息编号指的是 PostMessage 函数的第一个参数,1024(WM_USER) 以下都是系统使用的
WParam,LParam 是消息编号的辅助处理参数,如:
1.输入一个字符,但是需要把具体的字符发送到处理函数,就要使用 WParam 或者 LParam 了
2.处理接受的数据后,放在缓冲区,要把位置消息告诉处理函数时也一样
(总不能都是使用全局变量吧,再说了,使用全局也是可能不安全的【线程】)
sprewellkobe 2003-08-20
  • 打赏
  • 举报
回复
头文件
1. 在类声明中建立消息映射表,把某条消息的处理权交给自定义的消息处理函数。

BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(Windows消息名,TMessage,消息处理函数名)
MESSAGE_HANDLER(...)
END_MESSAGE_MAP(TForm)


实现:
private: // User declarations
void __fastcall 消息处理函数名(TMessage &Message);
在cpp文件内(如Unit1.cpp)



3. 写出消息处理函数,在这里实现你需要的功能。比如

void __fastcall MainForm::OnWMHScroll (TMessage &Message)
{
... // 在此加入你自己的代码
TForm::Dispatch(&Message);
}


------ 解释
1. 关于TMessage
TMessage是VCL预定义的结构,定义如下:
struct TMessage
{
unsigned int Msg; //消息
int WParam; //字参数
int LParam; //长字参数
int Result; //消息结果
};


2. 关于TForm::Dispatch(&Message)
  自定义的消息处理函数末尾最好加一句TForm::Dispatch(&Message),这一句的作用是让消息继续传递下去。如果没有这一句,消息将被完全拦截,VCL类可能由于得不到消息而无法实现正常功能。

windlyzhang 2003-08-20
  • 打赏
  • 举报
回复
当你自己定义好自己的消息时,利用SendMessage(),获PostMessage()发送消息!
也可以定义自己的消息结构,但消息结构必须是16个字节,并且要保留Msg; //消息
int Result; //消息结果 ,这两个参数,呵呵。。。其实也就是说,你只可以改变
wparam,和lparam,在这8个字节内改动!接受消息时,可以利用appliaction->onmessage
捕获,或者重载wndproc函数截获。
nolovedqboy 2003-08-19
  • 打赏
  • 举报
回复
怎么没有一个人解答一下啊??
nolovedqboy 2003-08-19
  • 打赏
  • 举报
回复
TO:sczyq(我又...........) ,消息编号(WParam,LParam)是事先约定好了的.这句话怎么样理解呢?消息什么时候才触发呢?
像我上面的:
TWinControl::Dispatch(&Message);

if (Message.Msg == WM_NC_NOTIFY)
{

这个怎么样来判断呢?WM_NC_NOTIFY这个只不过是我自己定义的一个消息(只不过是一个常量而已啊!),但我不知道他是什么东西,就这样就能触发吗?有人给我写一个最简单的消息吗?
nolovedqboy 2003-08-19
  • 打赏
  • 举报
回复
TO:sczyq(我又...........) ,消息编号(WParam,LParam)是事先约定好了的.这句话怎么样理解呢?消息什么时候才触发呢?
像我上面的:
TWinControl::Dispatch(&Message);

if (Message.Msg == WM_NC_NOTIFY)
{

这个怎么样来判断呢?WM_NC_NOTIFY这个只不过是我自己定义的一个消息(只不过是一个常量而已啊!),但我不知道他是什么东西,就这样就能触发吗?
sczyq 2003-08-19
  • 打赏
  • 举报
回复
一般编程序时,用于不同项目之间的通讯,当然,消息编号(WParam,LParam)是事先约定好了的。

我用过,那是主窗口与DLL的Child子窗口,关闭Child子窗口时,通知主窗口释放DLL内存,

PostMessage(mainHandle,WM_USER,200001,1);


主窗口通知自己关闭,
PostMessage(Handle,WM_USER,(long)Handle,0);


以下是主窗口收到消息,处理
//---------------------------------------------------------------------------
void __fastcall TMainForm::WndProc(Messages::TMessage &Message)
{
if (Message.Msg == WM_USER && Message.WParam>0)
if (Message.WParam == (long)Handle && Message.LParam == 0)
{
// 关闭主窗口
Close();
}
else
{
// 释放动态装入的DLL
// ..... 这里根据Message.WParam判断是释放那个DLL
FreeLibrary(Installed);
break;
}
}
else TForm::WndProc(Message);
}

总之, Message.Msg, Message.WParam, Message.LParam 用来定制消息,一般情况下只要有WParam就够了,参数不够,再用LParam, 数据类型是long 可以将(void *)转换为long
niuzhenjun 2003-08-19
  • 打赏
  • 举报
回复
拦截Windows消息需要以下几步:
在表单头文件内(如Unit1.h)
1. 在类声明中建立消息映射表,把某条消息的处理权交给自定义的消息处理函数。

BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(Windows消息名,TMessage,消息处理函数名)
MESSAGE_HANDLER(...)
END_MESSAGE_MAP(TForm)



2. 在类声明的private区内声明消息处理函数。

private: // User declarations
void __fastcall 消息处理函数名(TMessage &Message);
在表单文件内(如Unit1.cpp)



3. 写出消息处理函数,在这里实现你需要的功能。比如

void __fastcall MainForm::OnWMHScroll (TMessage &Message)
{
... // 在此加入你自己的代码
TForm::Dispatch(&Message);
}


------ 解释
1. 关于TMessage
TMessage是VCL预定义的结构,定义如下:
struct TMessage
{
unsigned int Msg; //消息
int WParam; //字参数
int LParam; //长字参数
int Result; //消息结果
};


2. 关于TForm::Dispatch(&Message)
  自定义的消息处理函数末尾最好加一句TForm::Dispatch(&Message),这一句的作用是让消息继续传递下去。如果没有这一句,消息将被完全拦截,VCL类可能由于得不到消息而无法实现正常功能。

604

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder VCL组件使用和开发
社区管理员
  • VCL组件使用和开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧