I am trying to use an api library with functions that send messages to a server, then receive back messages. One of the function's arguments is a HWND and the library document says the message will be received by it. 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.
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. So is there any way to simply 'extract' the message from HWND and not worry about MFC? If not, what is the simplest way?
More on the API doc
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 MyDlg
inherits CDialog
and has Wrapper m_wrp
as its class member.
LRESULT MyDlg::HandleEvent(WPARAM w, LPARAM l)
is a member function that prints the recieved data and returns TRUE
There's this code in the middle of the cpp file where member functions of MyDlg
are defined. It seems that whatever inputStr
is sent to the server by Wrapper::Func1
, the same message CA_01
is received. CA_01
is a const DWORD defined in another header file. 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
.:
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.
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. 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.
However, when I create a Wrapper
instance, and inside a while loop, try to call Func1
and recieve the message using PeekMessage, nothing happens:
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(...)?
You sure don't need MFC for that. Not even a "Windows" app - a simple console app will work, just keep pumping messages:
#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? Try to add a in instead of the while
loop (see modified code above)