簡體   English   中英

從 HWND 讀取 MFC 消息的最簡單方法?

[英]Simplest way to read MFC messages from HWND?

我正在嘗試使用 api 庫,該庫具有將消息發送到服務器然后接收回消息的功能。 該函數的 arguments 之一是一個 HWND,庫文件說消息將被它接收。 為了閱讀收到的消息,我研究了一些 MFC 文檔,創建了一個繼承 CDialog 的 class 和一個 function 來處理消息,並嘗試處理消息 map。

但是當我不想創建一個工作對話框 window 時,這些努力似乎有點太麻煩了,而只是想要消息本身,這樣我就可以讓它出現在控制台中或在我的代碼的其他部分中使用它。 那么有什么方法可以簡單地從 HWND 中“提取”消息而不用擔心 MFC? 如果沒有,最簡單的方法是什么?


有關 API 文檔的更多信息

Class Wrapper將 dll 庫文件包裝成成員函數,我正在嘗試使用 function BOOL Wrapper::Func1(HWND hWnd, DWORD msg, const char* inputStr)

Class MyDlg繼承CDialog並擁有Wrapper m_wrp作為它的class 成員。

LRESULT MyDlg::HandleEvent(WPARAM w, LPARAM l)是成員 function 打印收到的數據並返回TRUE

在 cpp 文件的中間有這段代碼,其中定義了MyDlg的成員函數。 似乎無論 wrapper Wrapper::Func1inputStr發送到服務器,都會收到相同的消息CA_01 CA_01是在另一個 header 文件中定義的 const DWORD。 經過一番搜索后,我相信這是不斷檢查消息的部分,如果收到帶有msg = CA_01MSG ,則調用HandleEvent 。:

BEGIN_MESSAGE_MAP(MyDlg, CDialog)
    ON_MESSAGE(CA_01, HandleEvent)
END_MESSAGE_MAP()

MyDlg創建了一個按鈕,當按下它時,將讀取輸入文本,調用void MyDlg::OnSend()並調用m_wrp.Func1(...)

void MyDlg::OnSend(){
    CString strData;
    m_editData.GetWindowText(strData);
    m_wrp.Func1(GetSafeHwnd(), CA_01, strData);
}

我已經從 api 文檔中測試了這個示例代碼,它工作正常。 出現帶有可編輯文本框和按鈕的 window,我輸入一些文本,按下按鈕,幾秒鍾后顯示收到的消息。

但是,當我創建一個Wrapper實例並在 while 循環內嘗試調用Func1並使用 PeekMessage 接收消息時,沒有任何反應:

HWND hWnd = CreateWindowW(L"static", L"", 0, 0, 0, 0, 0, HWND_MESSAGE, nullptr, nullptr, nullptr);
MSG msg;
Wrapper m_wrp;
CString inputStr = "test";

while (true){
    m_wrp.Func1(hWnd, CA_01, inputStr);
    if (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE)) {
        std::cout << "Got message: " << msg.message << std::endl;
    }
    else {
        std::cout << "No messages, sleep" << std::endl;
        Sleep(2000);
    }
}

這是因為 ON_MESSAGE(...) 和 PeekMessage(...) 之間的差異嗎?

你肯定不需要 MFC。 甚至不是“Windows”應用程序 - 一個簡單的控制台應用程序就可以工作,只需繼續發送消息即可:

#include <iostream>
#include <windows.h>

int main() {
    HWND hWnd = CreateWindowW(L"static", L"", 0,
        0, 0, 0, 0, HWND_MESSAGE, nullptr, nullptr, nullptr);

    MSG msg;
    while (true) {
        if(PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE)) {
            std::cout << "Got message: " << msg.message << std::endl;
        }
        else {
            std::cout << "No messages, posting '7' and sleep" << std::endl;
            PostMessage(hWnd, 7, 0, 0);
            Sleep(2'000);
        }
    }
}

更新:

上面的代碼僅適用於發布的消息。 為了也處理發送的消息,這個最小的示例將起作用:

#include <iostream>
#include <windows.h>

const DWORD CA_01 = WM_USER + 1;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    if (message == CA_01)
        std::cout << "Got message: " << message << std::endl;
    return DefWindowProc(hWnd, message, wParam, lParam);
}

ATOM MyRegisterClass()
{
    WNDCLASSEXW wcex{ sizeof(WNDCLASSEX) };
    wcex.lpfnWndProc = WndProc;
    wcex.hInstance = ::GetModuleHandle(NULL);
    wcex.lpszClassName = L"x";
    return RegisterClassExW(&wcex);
}

int main() {
    HWND hWnd = CreateWindowW((LPCWSTR)MyRegisterClass(), L"", 0,
        0, 0, 0, 0, HWND_MESSAGE, nullptr, nullptr, nullptr);

    std::cout << "Sending `CA_01`" << std::endl;
    LRESULT lr = SendMessageW(hWnd, CA_01, 0, 0);
    MSG msg;
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        DispatchMessage(&msg);
    }
}

可能是您應用程序中用於發送 windows 消息的庫? 嘗試添加一個 in 而不是while循環(參見上面修改后的代碼)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM