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
,