有没有一种方法可以检测是否已刷新窗口?

时间:2020-08-07 13:36:32

标签: windows winapi win32gui

使用功能FlashWindowFlashWindowEx,可能会导致窗口闪烁。但是,我似乎找不到任何可以检测到窗口是否已刷新的API。是否存在?

编辑

鉴于FLASHWINFO具有DWORD dwFlags,我猜想该信息将存储在窗口中,并且可以使用GetWindowLongWGetWindowLongPtrW进行访问,但是我在那找不到它。

原因是我需要这样做是为了自动化。

1 个答案:

答案 0 :(得分:1)

根据ShellProc

lParam [in]
类型: 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消息并输出:

enter image description here