QT c++ 中使用PostMessage/SendMessage实例

36 篇文章 13 订阅
27 篇文章 19 订阅

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。
 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C#SendMessagePostMessage的参数传递 在C#可以使用Window API提供的SendMessagePostMessage来传递参数。两者的区别简单介绍下:返回值的不同,我们先看一下 MSDN 里的声明: LRESULT SendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ); BOOL PostMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ); 其 4 个参数的意义是一样的,返回值类型不同(其实从数据上看他们一样是一个 32 位的数,只是意义不一样),LRESULT 表示的是消息被处理后的返回值,BOOL 表示的是消息是不是 Post 成功。 2、PostMessage 是异步的,SendMessage 是同步的。 PostMessage 只把消息放入队列,不管消息是否被处理就返回,消息可能不被处理;而 SendMessage 等待消息被处理完了之后才返回,如果消息不被处理,发送消息的线程将一直被阻塞。 3、如果在同一个线程内,SendMessage 发送消息时,由 USER32.DLL 模块调用目标窗口的消息处理程序,并将结果返回。SendMessage 在同一线程发送消息并不入线程消息队列。PostMessage 发送消息时,消息要先放入线程的消息队列,然后通过消息循环分派到目标窗口(DispatchMessage)。 如果在不同线程内,SendMessage 发送消息到目标窗口所属线程的消息队列,然后发送消息的线程在 USER32.DLL 模块内监视和等待消息处理,直到目标窗口处理完返回。SendMessage 在返回前还做了很多工作,比如,响应别的线程向它 SendMessage。Post 到别的线程时,最好用 PostThreadMessage 代替 PostMessagePostMessage 的 hWnd 参数可以是 NULL,等效于 PostThreadMessage + GetCurrentThreadId。Post WM_QUIT 时,应使用 PostQuitMessage 代替。 4、系统只整编(marshal)系统消息(0 到 WM_USER 之间的消息),发送用户消息(WM_USER 以上)到别的进程时,需要自己做整编。 用 PostMessage、SendNotifyMessage、SendMessageCallback 等异步函数发送系统消息时,参数里不可以使用指针,因为发送者并不等待消息的处理就返回,接受者还没处理指针就已经被释放了。 5、在 Windows 2000/XP 里,每个消息队列最多只能存放 10,000 个 Post 的消息,超过的还没被处理的将不会被处理,直接丢掉。这个值可以改得更大:[HKEY_LOCAL_MACHINE/SOFTWARE/ Microsoft/Windows NT/CurrentVersion/Windows] USERPostMessageLimit,最小可以是 4000。 PostMessage只负责将消息放到消息队列,不确定何时及是否处理 SendMessage要等到受到消息处理的返回码(DWord类型)后才继续 PostMessage执行后马上返回 SendMessage必须等到消息被处理后才会返回。
### 回答1: PostMessageSendMessage 都是 JavaScript 用来在不同窗口或框架之间进行通信的方法。 PostMessage 方法允许开发人员在两个不同域之间发送消息,而 SendMessage 方法则是在同一域之间发送消息。 这两种方法都可以在父窗口和子窗口之间进行通信,也可以在不同页面之间进行通信。 ### 回答2: postmessagesendmessage都是Windows API的函数,用于在不同的应用程序之间发送消息。它们之间有一些区别。 postmessage函数是异步的,它会将消息放入目标窗口的消息队列,并立即返回。这意味着,发送消息的线程不会等待目标窗口处理消息,而是继续执行自己的代码。这种异步的消息传递方式适用于需要快速发送消息并不需要等待结果的情况。 而sendmessage函数是同步的,它会直接调用目标窗口的消息处理函数,并等待这个函数返回后继续执行。这意味着,发送消息的线程会阻塞在sendmessage函数的调用上,直到目标窗口处理完消息并返回结果。这种同步的消息传递方式适用于需要及时获取结果的情况。 由于postmessage是异步的,所以在发送完消息后不能立即获得目标窗口的处理结果。如果需要知道消息处理的结果,可以使用sendmessage。但由于sendmessage是同步的,如果目标窗口的消息处理函数需要花费很长时间,那么发送消息的线程也会被阻塞同样长的时间。 在实际应用,通常优先考虑使用postmessage,因为它具有较高的执行效率。只有在确实需要及时获取目标窗口的处理结果时,才使用sendmessage。另外,需要注意的是,对于跨进程的消息传递,只有sendmessage函数可以实现,而postmessage只能用于同一进程内的消息传递。 ### 回答3: postmessagesendmessage都是Windows API的函数,用于在不同的窗口之间发送消息。 postmessage函数是发送异步消息的函数,它会将消息放入接收窗口的消息队列,然后立即返回。该函数不会等待接收窗口处理完消息,而是继续执行后续的代码。这意味着发送的消息不会影响到发送窗口的执行流程。因此,postmessage适用于不需要立即得到响应的情况,比如向其他应用程序发送消息。 sendmessage函数则是发送同步消息的函数,它会将消息发送给接收窗口,并且会一直等待接收窗口处理完该消息后才会返回。这意味着发送消息的窗口必须等待接收消息的窗口处理完消息后才能继续执行后续的代码。因此,sendmessage适用于需要立即得到响应或需要对消息的处理结果进行判断的情况,比如向同一应用程序的其他窗口发送消息。 总结来说,postmessage是异步地发送消息,不等待接收窗口处理消息;sendmessage是同步地发送消息,等待接收窗口处理消息后才返回。选择使用哪个函数要根据具体的需求来决定。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值