从 HWND 读取 MFC 消息的最简单方法?
Simplest way to read MFC messages from HWND?
我正在尝试使用一个 api 库,它具有将消息发送到服务器然后接收回消息的功能。该函数的参数之一是 HWND 并且库文档说消息将由它接收。为了读取收到的消息,我研究了一些 MFC 文档,创建了一个 class 继承了 CDialog 的函数来处理消息,并尝试使用消息映射。
但是当我不想创建工作对话框 window 时,这些努力似乎有点太麻烦了,而只是想要消息本身,这样我就可以让它出现在控制台中或使用它在我的代码的其他部分。那么有什么方法可以简单地 'extract' 来自 HWND 的消息而不用担心 MFC 吗?如果没有,最简单的方法是什么?
有关 API 文档的更多信息
Class Wrapper
将dll库文件包装成成员函数,我正在尝试使用函数BOOL Wrapper::Func1(HWND hWnd, DWORD msg, const char* inputStr)
Class MyDlg
继承了 CDialog
并拥有 Wrapper m_wrp
作为它的 class 成员。
LRESULT MyDlg::HandleEvent(WPARAM w, LPARAM l)
是一个成员函数,打印接收到的数据,returnsTRUE
cpp文件中间有这段代码,定义了MyDlg
的成员函数。似乎 Wrapper::Func1
将 inputStr
发送到服务器的任何内容,都会收到相同的消息 CA_01
。 CA_01
是另一个头文件中定义的 const DWORD。经过一番搜索后,我相信这是不断检查消息的部分,如果收到 MSG
和 msg = CA_01
,则调用 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
循环(参见上面修改后的代码)
我正在尝试使用一个 api 库,它具有将消息发送到服务器然后接收回消息的功能。该函数的参数之一是 HWND 并且库文档说消息将由它接收。为了读取收到的消息,我研究了一些 MFC 文档,创建了一个 class 继承了 CDialog 的函数来处理消息,并尝试使用消息映射。
但是当我不想创建工作对话框 window 时,这些努力似乎有点太麻烦了,而只是想要消息本身,这样我就可以让它出现在控制台中或使用它在我的代码的其他部分。那么有什么方法可以简单地 'extract' 来自 HWND 的消息而不用担心 MFC 吗?如果没有,最简单的方法是什么?
有关 API 文档的更多信息
Class Wrapper
将dll库文件包装成成员函数,我正在尝试使用函数BOOL Wrapper::Func1(HWND hWnd, DWORD msg, const char* inputStr)
Class MyDlg
继承了 CDialog
并拥有 Wrapper m_wrp
作为它的 class 成员。
LRESULT MyDlg::HandleEvent(WPARAM w, LPARAM l)
是一个成员函数,打印接收到的数据,returnsTRUE
cpp文件中间有这段代码,定义了MyDlg
的成员函数。似乎 Wrapper::Func1
将 inputStr
发送到服务器的任何内容,都会收到相同的消息 CA_01
。 CA_01
是另一个头文件中定义的 const DWORD。经过一番搜索后,我相信这是不断检查消息的部分,如果收到 MSG
和 msg = CA_01
,则调用 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
循环(参见上面修改后的代码)