Есть ли способ определить, было ли перепрошено окно? - PullRequest
0 голосов
/ 07 августа

Используя функции FlashWindow и FlashWindowEx , можно заставить окно мигать sh. Однако я не могу найти какой-либо API, который обнаруживал бы, было ли мигнуто окно. Существует ли он?

Изменить

Учитывая, что FLASHWINFO имеет DWORD dwFlags, я бы предположил, что эта информация будет храниться в окне и будет доступна с помощью любого GetWindowLongW или GetWindowLongPtrW , но я не могу его там найти.

Причина, по которой мне это нужно - для автоматизации.

1 Ответ

1 голос
/ 10 августа

Согласно ShellProc:

lParam [дюйм] Введите: LPARAM HSHELL_REDRAW Значение: TRUE , если окно мигает, или FALSE в противном случае.

Поэтому нам просто нужно добавить SetWindowsHookExA функция для перехвата сообщения WH_SHELL.

Вот пример:

#include <Windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK procShell(int, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
    HHOOK hook = SetWindowsHookEx(WH_SHELL, procShell, NULL,GetCurrentThreadId());
    int e = GetLastError();
    static TCHAR szAppName[] = TEXT("Test Flashing");
    HWND hwnd;
    MSG msg;
    WNDCLASS wndclass;
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    if (!RegisterClass(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
    }

    hwnd = CreateWindow(szAppName,
        szAppName,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL);
    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);
    while (GetMessageW(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessageW(&msg);
    }
    UnhookWindowsHookEx(hook);
    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    case WM_LBUTTONDOWN:
        FlashWindow(hwnd, TRUE);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}
LRESULT CALLBACK procShell(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode == HSHELL_REDRAW) {
        if (lParam)
        {
            OutputDebugString(L"Window is flashing\n");
        }
    }
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

Если мы нажмем левую кнопку, появится FlashWindow будет называться. Затем функция перехвата получит сообщение HSHELL_REDRAW и выведет:

введите описание изображения здесь

...