接收的时候,使用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 = ¶m[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处理
-
}