Определить мигание иконки на панели задач - PullRequest
2 голосов
/ 16 февраля 2012

Я хочу создать скрипт, который определяет, когда мигает значок на панели задач, и активирует программу.Я хотел бы использовать AutoIt или Windows API.

Как определить, когда значок на панели задач программы начинает мигать?

Ответы [ 2 ]

4 голосов
/ 13 мая 2012

Используйте API RegisterShellHookWindow и прослушивайте сообщения HSHELL_FLASH.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx

2 голосов
/ 16 февраля 2012

Чтобы ответить на ваш вопрос напрямую, не существует простого (документированного и надежного) способа обнаружить мигание окна .Это происходит в результате FlashWindow / FlashWindowEx .Очень навязчивым и жестким вариантом является глобальная перехват обоих API.Вы могли бы сделать это, внедрив DLL в каждое приложение пользовательского режима и выполнив локальный перехват / обход, который уведомляет некоторый центральный исполняемый файл, которым вы владеете.

Однако существует большая проблема с тем, что вы предлагаете, что делает егокрайне нежелательно.Представьте себе приложение, которое постоянно мигает, когда у него нет фокуса.Ваше приложение установит его на передний план.Что бы произошло, если бы было двух таких приложений ?


Использование WH_SHELL ловушки, как предполагает Рэймонд, не слишком сложно и выполняется путем вызова SetWindowsHookEx так:

SetWindowsHookEx(WH_SHELL, hook_proc, NULL, dwPID);

Устанавливает хук оболочки с HOOKPROC, так как hook_proc и dwPID - это нить, с которой мы хотим связать хук.Поскольку вы упоминаете, что уже знаете, на какую программу вы хотите установить таргетинг, я предполагаю, что у вас уже есть HWND для этого окна.Вам необходимо сгенерировать dwPID, что можно сделать следующим образом:

DWORD dwID = GetWindowThreadProcessId(hwnd, NULL)

Это заполнит dwPID соответствующим PID HWND.На следующем шаге я предполагаю, что процедура подключения находится в текущем исполняемом файле, а не в DLL.Процедура перехвата может выглядеть примерно так:

LRESULT CALLBACK hook_proc(int nCode, WPARAM wParam, LPARAM lParam) {
  if (nCode == HSHELL_REDRAW && lParam){
    SetForegroundWindow(hwnd); // assumed hwnd is a global
  }
  return CallNextHookEx(NULL, nCode, wParam, lParam);
}

Приведенный выше код не был протестирован и может содержать ошибки, но он должен дать вам общее представление о том, что делать.

Одна важная вещьСледует отметить, что с помощью оконных хуков SetWindowHookEx должен вызываться из программы с той же разрядностью, что и цель.т. е. если ваша цель 64-битная, то абонент SetWindowHookEx также должен быть 64-битным.Кроме того, после того, как вы закончите, вы должны очистить, удалив хук с помощью UnhookWindowsHookEx .

...