簡體   English   中英

如何通過 C++ 在后台獲取 Windows 消息

[英]How to get Windows Message in background by C++

我需要在后台獲取 Windows 消息。 我嘗試使用僅消息 Window,但它不起作用。 我只發現它在 Window 處於“可見”和“焦點”狀態時才有效。 請幫幫我,非常感謝!

Windows 消息示例

#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

僅消息 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;
}

日志:

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

我嘗試使用僅消息 Window,但它不起作用。

您需要了解純消息window的真正用途。

僅消息 Windows

僅消息 window 使您能夠發送和接收消息。 它不可見,沒有 z 順序,無法枚舉,並且不接收廣播消息。 window 只是發送消息。

換句話說,您可以向它發送消息( PostMessageSendMessage )。

像這樣,

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

然后,

在此處輸入圖像描述

僅使用消息的好處 window,

  • 消息的免費隊列。

如果您的系統是基於某種外部 IO 的消息,並且您需要排隊功能,那么您的應用程序可以使用 PostMessage 將消息發布到隱藏的 window。 這些消息將在正常的 Windows 消息隊列中排隊。

  • 進程間/進程內通信

您的應用程序(或外部應用程序)的另一部分可以處理這些消息的到達。

如果您想在后台監控 Windows 消息(第三方 GUI 應用程序),您可以按照 @Remy 的建議進行操作。

感謝您的建議,最后,我發現我們可以使用 CreateWindowEx() 並保持 Window 不可見以在后台獲取我需要的 Window 消息。 關於獲取背景中的關鍵事件,我們可以使用 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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM