Как зарегистрировать WndProc в консольном приложении

Когда я создаю новое приложение Win32, я замечаю функцию:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

получит сообщение, когда где-нибудь вызовет функцию PostMessage или SendMessage, и я замечу, что функция WndProc может получать сообщение, потому что есть функция, которая регистрирует его:

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, MAKEINTRESOURCE(IDI_SCREENCAPTURE));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_SCREENCAPTURE);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassEx(&wcex);
}

Обратите внимание: wcex.lpfnWndProc = WndProc;

Я хочу понять механизм PostMessage() и как его получить, поэтому я создал консольное приложение C++, чтобы посмотреть, смогу ли я зарегистрировать функцию WndProc, вот мой попыточный код:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int a = 1;//Break point here to see if it's call
    return 0;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.lpfnWndProc = WndProc;
    wcex.hInstance = hInstance;


    return RegisterClassEx(&wcex);
}

void main()
{
    MyRegisterClass(GetModuleHandle(NULL));//(HINSTANCE)GetConsoleWindow()

    PostMessage(GetConsoleWindow(), 132, 0, 0);

    SYSTEMTIME st;

    while (true)
    {
        GetSystemTime(&st);
        printf("I'm wanting and waiting and waiting :(, The time is %I64u \n", st.wMilliseconds);
    }

}

1 ответ

Решение

Оконная процедура не может получать сообщения, если она не связана с окном. Все, что вы сделали, это создали класс окна. Вам все еще нужно создать окно этого класса для вашей оконной процедуры (WndProc) для получения сообщений.

В зависимости от типа сообщения, которое вы хотите, чтобы ваша процедура Windows получала, вы можете создать скрытое окно, которое не отображается на экране. Если вам нужно обрабатывать определенные сообщения, такие как события клавиатуры и мыши, направленные в окно консоли, вы можете вместо этого использовать SetConsoleMode и ReadConsoleInput для получения этих событий. Также есть SetConsoleCtrlHandler, который позволяет вам обрабатывать события WM_QUERYENDSESSION.

У Microsoft есть пример на MSDN, который показывает, как использовать ReadConsoleInput для обработки определенных событий ввода с консоли.

Другие вопросы по тегам