QT c++ 中使用PostMessage/SendMessage

本文详细解释了Windows API中的PostMessage和SendMessage函数的区别,PostMessage采用异步方式将消息放入消息队列,而SendMessage则同步等待消息处理。文章通过具体示例展示了如何使用这两种函数,并在Qt环境中重写nativeEvent函数来接收和处理这些消息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

PostMessage是Windows API(应用程序接口) 中的一个常用函数,用于将一条消息放入到消息队列中。并且不会等待响应的线程处理消息,而是直接返回。(简单的理解就是异步)。

SendMessage作用一样,但是会等待结果返回(同步

我们先来看PostMessage函数的原型:

BOOL WINAPI PostMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

hWnd:其窗口程序接收消息的窗口的句柄。可取有特定含义的两个值:

HWND_BROADCAST:消息被寄送到系统的所有顶层窗口,包括无效或不可见的非自身拥有的窗口、 被覆盖的窗口和弹出式窗口。消息不被寄送到子窗口

NULL:此函数的操作和调用参数dwThread设置为当前线程的标识符PostThreadMessage函数一样

Msg:指定被寄送的消息。

wParam:指定附加的消息特定的信息。

LParam:指定附加的消息特定的信息。

返回值:如果函数调用成功,返回非零,否则函数调用返回值为零


接收的时候,使用QT5中的方法是 在接收的类中,重新实现 nativeEvent函数(Qt4的时候使用的是winEvent,从Qt5开始,就使用nativeEvent),这个方法既可以拦截系统消息,也可以拦截通过postMessage,sendMessage发送的自定义消息。

[virtual protected] bool QWidget::nativeEvent(const QByteArray &eventType, void *message, long *result);

其中:

eventType: windows平台的值就是“windows_generic_MSG”;

message: 类型为MSG*, 存储的就是PostMessage中的Msg。

Result:类型为LRESULT,返回的值。

如果返回ture:表示停止这个消息。如果返回false:这个消息就继续传递给Qt,Qt会将这个消息转变为Qt event并将它发送给响应的控件。


我们用Qt环境下来举个栗子:

先是使用SendMessage来向顶层窗口发送消息

    HWND m_wnd = ::FindWindowA(("ClientMainWindow"), NULL);//通过主窗口类名寻找主窗口句柄
    WId wid = this->winId(); //这个窗口的winid
    if (NULL != m_wnd)
    {
        std::thread th([=](){ //单独启动一个线程进行数据传递
            QString command = QString("Command=ChangeCode=%1\r\n").arg(code);//传递的内容
            std::string param = command.toStdString();
            COPYDATASTRUCT data;    //使用COPYDATA的方式进行数据传递
            data.dwData = 0;
            data.cbData = param.length();
            data.lpData = &param[0];
            ::SendMessage(m_wnd, WM_COPYDATA, (WPARAM)wid, (LPARAM)&data);
        });

        th.detach();//传递结束后,进行关闭线程
    }

同时,在接收的顶层窗口中,重写nativeEvent函数

bool EmbededWidget::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
	if (eventType == "windows_generic_MSG") //windows平台
	{
		MSG* msg = reinterpret_cast<MSG*>(message); //

		if(msg->message == WM_COPYDATA)//消息类型
		{
			COPYDATASTRUCT *data = reinterpret_cast<COPYDATASTRUCT*>(msg->lParam);
			QTextCodec *gbk = QTextCodec::codecForName("GB18030");
			QString recevice = gbk->toUnicode((char *)(data->lpData));//转码

			if(recevice.contains("Command="))
			{
			   return true;//消息不再进行传递,不再处理
			}

			m_wnd = reinterpret_cast<HWND>(msg->wParam);//高地址的参数

		}
	}

	return QWidget::nativeEvent(eventType, message, result);//交给Qt处理
}

使用PostMessage发送消息用法完全一样。无论使用SendMessage还是使用PostMessage发送消息,接收函数都是nativeEvent。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值