Flash ShowMessage(Pos) или любое другое предопределенное окно в блоке диалогов в Delphi для ОС Post-WInXP

Это подход, который я нашел для Tray...:

http://www.programmersheaven.com/mb/delphikylix/257563/257563/how-can-i-make-a-system-tray-flash/

Работает ли та же техника для диалогов (так как на самом деле это формы с дополнительными параметрами)? Или я могу сделать это с помощью более быстрых методов, таких как получение дескриптора / адреса / интерфейса и перегрузка или перегрузка функции с помощью метода FlashWindow(Ex)?

Я имею в виду - могу ли я сделать, например, ShowMessage(), флэш-окно / диалог, используя метод FlashWindowEx(), и если я могу, можно ли это сделать, используя пример в ссылке выше?

Пожалуйста, укажите лучшее направление или проясните мои сомнения.

Благодарю.

Извините за плохую формулировку вопроса.

2 ответа

Решение

Существует много способов отображения модальной формы или диалога (как VCL, так и встроенного в системе) из программы на Delphi, поэтому вам нужно каким-то образом подключиться к обработке сообщений и перехватить сообщения, которые отправляются при отображении модальной формы или диалога.

Для этого можно установить перехват сообщений с помощью SetWindowsHookEx() API-функция. Поскольку это нужно только в то время, когда приложение неактивно, вы можете установить его в обработчике OnDeactivate событие приложения и сбросьте его в обработчике для OnActivate событие приложения:

var
  gNextHook: HHOOK;

procedure TForm1.AppActivate(Sender: TObject);
begin
  if gNextHook <> 0 then
    UnhookWindowsHookEx(gNextHook);
  gNextHook := 0;
end;

procedure TForm1.AppDeactivate(Sender: TObject);
begin
  gNextHook := SetWindowsHookEx(WH_CALLWNDPROC, @WndProcHook, 0,
    GetCurrentThreadId);
end;

Функция ловушки будет следить за сообщениями, которые отправляются, когда отображается модальное диалоговое окно или форма, и вызывает FlashWindowEx() с правильными параметрами:

function WndProcHook(nCode: integer; AWParam: WPARAM; ALParam: LPARAM): LRESULT; stdcall;
var
  DataPtr: PCWPStruct;
  Fwi: TFlashWInfo;
begin
  DataPtr := PCWPStruct(ALParam);
  if (DataPtr^.message = WM_INITDIALOG)
    or ((DataPtr^.message = CM_ACTIVATE) and (DataPtr^.lParam = 0) and (DataPtr^.wParam = 0))
  then begin
    Fwi.cbSize := SizeOf(TFlashWInfo);
    // flash caption of new modal window
    Fwi.hwnd := DataPtr^.hwnd;
    Fwi.dwFlags := FLASHW_ALL or FLASHW_TIMERNOFG;
    Fwi.uCount := 0;
    Fwi.dwTimeout := 0;
    FlashWindowEx(Fwi);
    // uncomment this to flash task bar button as well
(*
    Fwi.hwnd := Application.MainForm.Handle;
    Fwi.dwFlags := FLASHW_TRAY or FLASHW_TIMERNOFG;
    FlashWindowEx(Fwi);
*)
  end;
  Result := CallNextHookEx(gNextHook, nCode, AWParam, ALParam);
end;

Я выбрал WM_INITDIALOG который отправляется для собственных диалогов, таких как диалоги открытия или сохранения, и CM_ACTIVATE который отправляется, когда форма VCL отображается модально. Таких сообщений может быть больше, которые нужно перехватить. Выше код работает для MessageDlg() функция, Application.MessageBox() функция и TOpenDialog по крайней мере.

Поскольку в этих диалогах нет собственной кнопки панели задач, я добавил (закомментировал) код, чтобы также высветить кнопку панели задач главной формы. Это не оптимально, так как они не синхронизированы.

Протестировано с Delphi 2009 на Windows XP, вся обработка ошибок пропущена, используйте ее только как отправную точку.

Тот же метод применяется к любому окну верхнего уровня, включая диалоговые окна. Если вы можете получить дескриптор окна, вы можете передать его FlashWindowEx,

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