【发布时间】:2020-08-07 13:36:32
【问题描述】:
使用函数FlashWindow 和FlashWindowEx,可以使窗口闪烁。但是,我似乎找不到任何可以检测窗口是否已闪烁的 API。有吗?
编辑
鉴于FLASHWINFO 具有DWORD dwFlags,我猜想此信息将存储在窗口中,并且可以使用GetWindowLongW 或GetWindowLongPtrW 访问,但我无法在那里找到它。
我需要这个的原因是为了自动化。
【问题讨论】:
使用函数FlashWindow 和FlashWindowEx,可以使窗口闪烁。但是,我似乎找不到任何可以检测窗口是否已闪烁的 API。有吗?
鉴于FLASHWINFO 具有DWORD dwFlags,我猜想此信息将存储在窗口中,并且可以使用GetWindowLongW 或GetWindowLongPtrW 访问,但我无法在那里找到它。
我需要这个的原因是为了自动化。
【问题讨论】:
根据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消息并输出:
【讨论】: