简体   繁体   English

从 HWND 读取 MFC 消息的最简单方法?

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

I am trying to use an api library with functions that send messages to a server, then receive back messages.我正在尝试使用 api 库,该库具有将消息发送到服务器然后接收回消息的功能。 One of the function's arguments is a HWND and the library document says the message will be received by it.该函数的 arguments 之一是一个 HWND,库文件说消息将被它接收。 To read the received message I studied a few MFC documents, created a class that inherits CDialog with a function to handle the message and tried to work with the message map.为了阅读收到的消息,我研究了一些 MFC 文档,创建了一个继承 CDialog 的 class 和一个 function 来处理消息,并尝试处理消息 map。

But these efforts seemed like a bit too much trouble when I don't want to create a working dialog window, but just want the message itself so I can make it appear in a console or use it in other parts of my code.但是当我不想创建一个工作对话框 window 时,这些努力似乎有点太麻烦了,而只是想要消息本身,这样我就可以让它出现在控制台中或在我的代码的其他部分中使用它。 So is there any way to simply 'extract' the message from HWND and not worry about MFC?那么有什么方法可以简单地从 HWND 中“提取”消息而不用担心 MFC? If not, what is the simplest way?如果没有,最简单的方法是什么?


More on the API doc有关 API 文档的更多信息

Class Wrapper wraps the dll library file into member functions, I'm trying to use the function BOOL Wrapper::Func1(HWND hWnd, DWORD msg, const char* inputStr) Class Wrapper将 dll 库文件包装成成员函数,我正在尝试使用 function BOOL Wrapper::Func1(HWND hWnd, DWORD msg, const char* inputStr)

Class MyDlg inherits CDialog and has Wrapper m_wrp as its class member. Class MyDlg继承CDialog并拥有Wrapper m_wrp作为它的class 成员。

LRESULT MyDlg::HandleEvent(WPARAM w, LPARAM l) is a member function that prints the recieved data and returns TRUE LRESULT MyDlg::HandleEvent(WPARAM w, LPARAM l)是成员 function 打印收到的数据并返回TRUE

There's this code in the middle of the cpp file where member functions of MyDlg are defined.在 cpp 文件的中间有这段代码,其中定义了MyDlg的成员函数。 It seems that whatever inputStr is sent to the server by Wrapper::Func1 , the same message CA_01 is received.似乎无论 wrapper Wrapper::Func1inputStr发送到服务器,都会收到相同的消息CA_01 CA_01 is a const DWORD defined in another header file. CA_01是在另一个 header 文件中定义的 const DWORD。 After some searching I believe this is the part that continuously checks for messages and if MSG with msg = CA_01 is received, calls HandleEvent .:经过一番搜索后,我相信这是不断检查消息的部分,如果收到带有msg = CA_01MSG ,则调用HandleEvent 。:

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

There is a button MyDlg creates, and when it is pressed, input text is read, void MyDlg::OnSend() is called and m_wrp.Func1(...) is called. MyDlg创建了一个按钮,当按下它时,将读取输入文本,调用void MyDlg::OnSend()并调用m_wrp.Func1(...)

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

I have tested this sample code from the api document, and it works fine.我已经从 api 文档中测试了这个示例代码,它工作正常。 A window with a editable text box and a button appears, I enter some text, press the button, and after a few seconds the received message is shown.出现带有可编辑文本框和按钮的 window,我输入一些文本,按下按钮,几秒钟后显示收到的消息。

However, when I create a Wrapper instance, and inside a while loop, try to call Func1 and recieve the message using PeekMessage, nothing happens:但是,当我创建一个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);
    }
}

Is this because of a difference between ON_MESSAGE(...) and PeekMessage(...)?这是因为 ON_MESSAGE(...) 和 PeekMessage(...) 之间的差异吗?

You sure don't need MFC for that.你肯定不需要 MFC。 Not even a "Windows" app - a simple console app will work, just keep pumping messages:甚至不是“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);
        }
    }
}

UPDATE:更新:

The code above works only for posted messages.上面的代码仅适用于发布的消息。 To also process sent messages, this minimal sample will work:为了也处理发送的消息,这个最小的示例将起作用:

#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);
    }
}

May be that library on your app to pump windows messages?可能是您应用程序中用于发送 windows 消息的库? Try to add a in instead of the while loop (see modified code above)尝试添加一个 in 而不是while循环(参见上面修改后的代码)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM