Un formulaire modal ou une boîte de dialogue (VCL ou natif du système) peut être affiché à partir d'un programme Delphi de nombreuses manières. Vous devez donc vous connecter au traitement des messages et récupérer les messages envoyés en mode modal ou la boîte de dialogue est affichée.
Pour cela, un message hook peut être défini à l'aide de la fonction API SetWindowsHookEx()
. Puisque vous avez besoin de ce que lorsque l'application est inactive, vous pouvez le mettre dans le gestionnaire de l'événement d'application OnDeactivate
, et remettre dans le gestionnaire pour l'événement d'application 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;
La fonction crochet regarderait pour les messages sont envoyés lorsqu'une boîte de dialogue modale ou formulaire est affiché, et appelez FlashWindowEx()
avec les paramètres appropriés:
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;
j'ai choisi WM_INITDIALOG
qui est envoyé pour les boîtes de dialogue natives comme ouvrir ou enregistrer des boîtes de dialogue et CM_ACTIVATE
qui est envoyé lorsqu'un VCL la forme est sho wn modalement. Il peut y avoir plus de messages de ce type qui doivent être interceptés. Au-dessus du code fonctionne pour la fonction MessageDlg()
, la fonction Application.MessageBox()
et TOpenDialog
au moins. Comme ces boîtes de dialogue n'ont pas leur propre bouton de la barre des tâches, j'ai ajouté (mis en commentaire) du code pour faire clignoter le bouton de la barre des tâches du formulaire principal. Ce n'est pas optimal, car ils sont désynchronisés.
Testé avec Delphi 2009 sous Windows XP, toutes les erreurs de gestion omises, utilisez-le uniquement comme point de départ.
La question est de savoir comment faire clignoter les boutons de la barre des tâches des boîtes de dialogue comme TOpenDialog? –
Oui - TOpenDialogs, ShowMessage(), MessageDlg(), etc ... –