Admin Fondateur
Nombre de messages : 197 Age : 40 Localisation : Tlemcen ( Algérie ) Date d'inscription : 04/12/2006
| Sujet: Comment passer au premier plan une application instanciée un Ven 12 Jan - 6:02 | |
| 1ère méthode : en utilisant le nom de la classe
L'idée est de chercher une fenêtre de même classe que TApplication avec le même titre. Et de mettre en avant plan une telle fenêtre si elle existe. Le code du projet ( .DPR ) devient le suivant : - Code:
-
begin if IsPrevInstance = 0 then begin Application.Initialize; Application.CreateForm(TMDIForm, MDIForm); [...] Application.Run; end else AfficherInstance(IsPrevInstance); end. Les deux fonctions IsPrevInstance et AfficherInstance peuvent être mises directement dans le code du projet ou dans une autre unité. Leur implémentation est la suivante : - Code:
-
function IsPrevInstance: HWND; var ClassName: array[0..255] of char; Title: string; begin Title := Application.Title; Application.Title := ''; { On change le titre, car on trouverait toujours une application lancée, (la notre). } try GetClassName(Application.Handle, ClassName, 255); { Met dans ClassName le nom de la classe de l'application. } Result := FindWindow(ClassName, PChar(Title)); { Renvoie le Handle de la 1ère fenêtre de Class (Type) ClassName, et le titre de l'application. } finally Application.Title := Title; { Restauration du vrai titre. } end; end;
procedure AfficherInstance(InstHandle: HWND); begin { Restaurer l'application si minimisée } ShowWindow(InstHandle, SW_RESTORE); { Mettre la première instance en premier plan : } SetForegroundWindow(InstHandle); { Fin de la deuxième instance } Application.Terminate; end; 2ème méthode : en utilisant la base de registre.La première chose à faire est de tester si l'application est déjà instanciée. Pour ce faire, on utilise les Mutex comme décrits précédemment. Ce test amène donc à 2 cas de figures : L'application n'est pas lancée Si l'application n'est pas instanciée, il faut le faire, pour cela, le déroulement classique du lancement d'une programme suffit. Il faudra tout de même récupérer certaines informations sur l'application. Ces information servirons à faire repasser l'application au premier plan dans le cas d'un second lancement du programme. Pour cela, nous avons besoins de 2 handles : celui du programme lui même et celui de la form principale. Ces 2 valeurs qui devront être accessibles en dehors du programme seront stockées dans la base de registres de Windows sous la clé HKEY_CLASSES_ROOT\software\nom_de_la_clé et sous les noms FirstApplicationHandle et FirstFormHandle. - Code:
-
[/center] Application.Initialize; Application.CreateForm(TForm1, Form1);
Registre := TRegistry.Create; try Registre.RootKey := HKEY_CLASSES_ROOT; Registre.OpenKey('\Software\nom_de_la_clé', True); Registre.WriteInteger('FirstApplicationHandle', Application.Handle); Registre.WriteInteger('FirstFormHandle', Form1.Handle); Registre.CloseKey; Registre.Free; except MessageDlg('Une erreur est survenue lors de l''écriture dans la base de registre.', mtError, [mbOk], 0); Registre.Free; end;
Application.Run;[center] L'application est déjà lancée Si l'application est déjà lancée, rien ne sert de la faire une seconde fois, c'est-à-dire que le chargement de l'application sera tout simplement stoppé. Mais avant de quitter le lancement de l'application, il faut redonner le focus à la première instance du programme. C'est là que les données qu'il aura déposées dans la base de registres seront utiles pour l'identifier. La première chose à faire est donc d'aller chercher les 2 handles voulus dans la base de registre. Une fois que le programme aura le handle de l'application et celui de la fenêtre principale il pourra donner le focus à cette dernière. Cela se fait grâce à 2 fonctions de l'API Windows ShowWindow(hWnd: HWND; nCmdShow: Integer): BOOL et SetForegroundWindow(hWnd: HWND): BOOL.
- Code:
-
Registre := TRegistry.Create; try Registre.RootKey := HKEY_CLASSES_ROOT; Registre.OpenKey('\Software\nom_de_la_clé', True); FirstApplicationHandle := Registre.ReadInteger('FirstApplicationHandle'); FirstFormHandle := Registre.ReadInteger('FirstFormHandle'); ShowWindow(FirstApplicationHandle, SW_NORMAL); SetForegroundWindow(FirstFormHandle); Registre.CloseKey; Registre.Free; except MessageDlg('Une erreur est survenue lors de la lecture dans la base de registre.', mtError, [mbOk], 0); Registre.Free; end; PS: il est préférable de nettoyer la base de registres à la fin de l'exécution du programme. | |
|