繁体   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