1. 程式人生 > >Qt 之程序間通訊(Windows 訊息)

Qt 之程序間通訊(Windows 訊息)

簡述

通過上一節的瞭解,我們可以看出程序通訊的方式很多,今天分享下如何利用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>(&copydata)); } }

接收訊息

設定標題

這一步很重要,必須與上一步的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);
}

更多參考