QT c++ 中使用PostMessage/SendMessage (Windows API)

接收的时候,使用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来向顶层窗口发送消息

  1. HWND m_wnd = ::FindWindowA(("ClientMainWindow"), NULL);//通过主窗口类名寻找主窗口句柄

  2. WId wid = this->winId(); //这个窗口的winid

  3. if (NULL != m_wnd)

  4. {

  5. std::thread th([=](){ //单独启动一个线程进行数据传递

  6. QString command = QString("Command=ChangeCode=%1\r\n").arg(code);//传递的内容

  7. std::string param = command.toStdString();

  8. COPYDATASTRUCT data; //使用COPYDATA的方式进行数据传递

  9. data.dwData = 0;

  10. data.cbData = param.length();

  11. data.lpData = &param[0];

  12. ::SendMessage(m_wnd, WM_COPYDATA, (WPARAM)wid, (LPARAM)&data);

  13. });

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

  16. }

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

  1. bool EmbededWidget::nativeEvent(const QByteArray &eventType, void *message, long *result)

  2. {

  3. if (eventType == "windows_generic_MSG") //windows平台

  4. {

  5. MSG* msg = reinterpret_cast<MSG*>(message); //

  6.  
  7. if(msg->message == WM_COPYDATA)//消息类型

  8. {

  9. COPYDATASTRUCT *data = reinterpret_cast<COPYDATASTRUCT*>(msg->lParam);

  10. QTextCodec *gbk = QTextCodec::codecForName("GB18030");

  11. QString recevice = gbk->toUnicode((char *)(data->lpData));//转码

  12.  
  13. if(recevice.contains("Command="))

  14. {

  15. return true;//消息不再进行传递,不再处理

  16. }

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

  19.  
  20. }

  21. }

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

  24. }

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是使用C++/CLI封装Windows ApiSendMessage()方法,并在VB.NET调用的示例代码。 首先,在C++/CLI封装SendMessage()方法,可以使用以下代码: ```cpp #pragma once #include "windows.h" namespace MyNamespace { public ref class MyWindowsApiWrapper { public: static LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { return ::SendMessage(hWnd, Msg, wParam, lParam); } }; } ``` 其SendMessage()方法的四个参数分别为:要发送消息的窗口句柄、消息类型、wParam参数(根据不同消息类型而有所不同)、lParam参数(根据不同消息类型而有所不同)。 然后,在VB.NET调用SendMessage()方法,可以使用以下代码: ```vb.net Imports System.Runtime.InteropServices Imports MyNamespace Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim hWnd As IntPtr = Process.GetProcessesByName("notepad")(0).MainWindowHandle Dim WM_SETTEXT As Integer = &HC Dim lpText As String = "Hello World!" MyWindowsApiWrapper.SendMessage(hWnd, WM_SETTEXT, 0, lpText) End Sub End Class ``` 这里使用SendMessage()方法给Notepad应用程序的主窗口发送WM_SETTEXT消息,将文本框的内容设置为"Hello World!"。 值得注意的是,SendMessage()方法的返回值类型为LRESULT,在VB.NET需要使用Marshal.GetLastWin32Error()方法获取错误代码,以判断是否发送成功。 以上代码可以在VB.NET点击按钮后,将Notepad的文本框内容修改为"Hello World!"。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值