简体   繁体   中英

How to get Windows Message in background by C++

I need to get Windows Message in background. I tried to use Message-Only Window, but it doesn't work. I only found it works when Window is "visable" and "focus" status. Please help me, thank you very much!

Windows Message example

#define WM_KEYFIRST                     0x0100
#define WM_KEYDOWN                      0x0100
#define WM_KEYUP                        0x0101
#define WM_CHAR                         0x0102
#define WM_DEADCHAR                     0x0103
#define WM_SYSKEYDOWN                   0x0104
#define WM_SYSKEYUP                     0x0105
#define WM_SYSCHAR                      0x0106
#define WM_SYSDEADCHAR                  0x0107

codes for message-only window

#include <iostream>
#include <Windows.h>

using namespace std;

namespace {
    LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {

        std::cout << "INFO: " << __func__ << ": WndProc: message= 0x" << std::hex << uMsg << ", wParam = 0x" << std::hex << wParam << "\n";
        if (uMsg == WM_COPYDATA)
            std::cout << "Got a message!" << std::endl;
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
}

int main()
{
    WNDCLASS windowClass = {};
    windowClass.lpfnWndProc = WindowProcedure;
    LPCWSTR windowClassName = L"FoobarMessageOnlyWindow";
    windowClass.lpszClassName = windowClassName;

    if (!RegisterClass(&windowClass)) {
        std::cout << "Failed to register window class" << std::endl;
        return 1;
    }

    HWND messageWindow = CreateWindowEx(0, windowClassName, 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, 0);
    //HWND messageWindow = GetDesktopWindow();
    cout << "INFO: " << __func__ << " CreateWindow messageWindow=" << messageWindow << "\n";
    if (!messageWindow) {
        std::cout << "Failed to create message-only window" << std::endl;
        return 1;
    }

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0) > 0) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

logs:

INFO: WindowProcedure: WndProc: message= 0x24, wParam = 0x0
INFO: WindowProcedure: WndProc: message= 0x81, wParam = 0x0
INFO: WindowProcedure: WndProc: message= 0x83, wParam = 0x0
INFO: WindowProcedure: WndProc: message= 0x1, wParam = 0x0
INFO: main CreateWindow messageWindow=00000000005B0E42

I tried to use Message-Only Window, but it doesn't work.

You need to understand the real use of message-only window.

From Message-Only Windows ,

A message-only window enables you to send and receive messages. It is not visible, has no z-order, cannot be enumerated, and does not receive broadcast messages. The window simply dispatches messages.

In other words, you can send messages ( PostMessage and SendMessage ) to it.

Like this,

SendMessage(messageWindow,WM_CHAR, (WPARAM)0x41, (LPARAM)0);

then,

在此处输入图像描述

Benefits of using a message only window,

  • Free queue for messages.

If your system is message based from some sort of external IO say, and you are in need of a queuing facility, then your application can use PostMessage to post messages to the hidden window. These messages will be queued in the normal Windows message queue.

  • Inter/intra process communication

Another part of your application (or an external application) can handle the arrival of these messages.

If you want to monitor Windows Message in background(Third-party GUI Application), you can follow @Remy's suggestions.

Thanks for your advices, finally, I found we could use CreateWindowEx() and just keep Window invisible to get Window Message I need in background. About getting key event in backgroud, we could use RegisterHotKey().

#include <iostream>
#include <Windows.h>
#include <atlstr.h>

using namespace std;

#define MAX_LOADSTRING 100

TCHAR szTitle[MAX_LOADSTRING] = TEXT("TEST TITLE");
TCHAR szWindowClass[MAX_LOADSTRING] = TEXT("TEST WindowClass");

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    std::cout << "INFO: " << __func__ << ": WndProc: message= 0x" << std::hex << message << ", wParam = 0x" << std::hex << wParam << "\n";

    return DefWindowProc(hWnd, message, wParam, lParam);
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(hInstance, NULL);
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm = LoadIcon(wcex.hInstance, NULL);

    ATOM ret = RegisterClassEx(&wcex);

    return ret;
}

BOOL InitInstance(HINSTANCE hInstance)
{
    HWND hWnd;

    hWnd = CreateWindowEx(0, szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    if (!hWnd)
    {
        return FALSE;
    }

    return TRUE;
}

int main()
{
    MSG msg;
    HINSTANCE hInstance = GetModuleHandleA(NULL);

    MyRegisterClass(hInstance);

    if (!InitInstance(hInstance))
    {
        return FALSE;
    }

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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