[英]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::Func1
将inputStr
发送到服务器,都会收到相同的消息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_01
的MSG
,则调用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.