簡述
通過上一節的了解,我們可以看出進程通信的方式很多,今天分享下如何利用Windows消息機制來進行不同進程間的通信。
效果

發送消息
自定義類型與接收窗體
包含所需庫,定義發送的自定義類型、接收消息的窗體標題。自定義類型可以處理消息過多情況下,對消息的區分,如果不需要也可以去掉。
#ifdef Q_OS_WIN
#pragma comment(lib, "user32.lib")
#include <qt_windows.h>
#endif
const ULONG_PTR CUSTOM_TYPE = 10000;
const QString c_strTitle = "ReceiveMessage";
發送數據
點擊按鈕,進行消息發送。里面的do{…}while用來忽略本窗口,當然自身也可以接受自身的消息。
void onSendMessage()
{
HWND hwnd = NULL;
//do
//{
LPWSTR path = (LPWSTR)c_strTitle.utf16(); //path = L"SendMessage"
hwnd = ::FindWindowW(NULL, path);
//} while (hwnd == (HWND)effectiveWinId()); // 忽略自己
if (::IsWindow(hwnd))
{
QString filename = QStringLiteral("進程通信-Windows消息");
QByteArray data = filename.toUtf8();
COPYDATASTRUCT copydata;
copydata.dwData = CUSTOM_TYPE; // 用戶定義數據
copydata.lpData = data.data(); //數據大小
copydata.cbData = data.size(); // 指向數據的指針
HWND sender = (HWND)effectiveWinId();
::SendMessage(hwnd, WM_COPYDATA, reinterpret_cast<WPARAM>(sender), reinterpret_cast<LPARAM>(©data));
}
}
接收消息
設置標題
這一步很重要,必須與上一步的c_strTitle保持一致,否則會找不到窗體。自定義類型CUSTOM_TYPE也必須保持一致,進行過濾。
setWindowTitle("ReceiveMessage");
重寫nativeEvent
bool nativeEvent(const QByteArray &eventType, void *message, long *result)
{
MSG *param = static_cast<MSG *>(message);
switch (param->message)
{
case WM_COPYDATA:
{
COPYDATASTRUCT *cds = reinterpret_cast<COPYDATASTRUCT*>(param->lParam);
if (cds->dwData == CUSTOM_TYPE)
{
QString strMessage = QString::fromUtf8(reinterpret_cast<char*>(cds->lpData), cds->cbData);
QMessageBox::information(this, QStringLiteral("提示"), strMessage);
*result = 1;
return true;
}
}
}
return QWidget::nativeEvent(eventType, message, result);
}
原文作者:一去丶二三里
作者博客:去作者博客空間
