Maximiser une appli a partir de mon progamme D5

Signaler
Messages postés
10
Date d'inscription
jeudi 31 décembre 2009
Statut
Membre
Dernière intervention
14 avril 2019
-
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
-
Salut tous le monde,

Je cheche la fonction qui permettra a un programme Delphi (5 Pro en l'occurence) de maximiser un AUTRE programme en train de s'executer.

Mes recherches ont abouties en ces deux methodes, mais aucune ne fonctionne:

function TForm1.MaxiApp(const sCapt: PChar) : boolean;
  var AppHandle:THandle;
  i : integer;
begin
  AppHandle:=FindWindow(Nil, sCapt) ;
 // SOIT: 
    Result:= PostMessage(AppHandle,WM_SIZE,SIZE_MAXIMIZED,0);
 // SOIT:
    SendMessage(AppHandle, SC_SIZE, SIZE_MAXIMIZED, 0);
End;
// A Appeler par:
 S :='iGO Zoomer - www.cybersuricate.com';
 if not MaxiApp(s) then ShowMessage('App pas Maximisée') else ShowMessage('Maximisée OK');


Par contre, l'arrêt du programme fonctionne bien ainsi:

function TForm1.KillApp(const sCapt: PChar) : boolean;
  var AppHandle:THandle;
begin
  AppHandle:=FindWindow(Nil, sCapt) ;
  Result:=PostMessage(AppHandle, WM_QUIT, 0, 0) ;
end;

// A Appeler par:
 S :='iGO Zoomer - www.cybersuricate.com';
 if not KillApp(pchar(s)) then ShowMessage('App pas fermée') else ShowMessage('fermée OK');


Merci d'avance a tous,

Eitan Gilboa.

URL: ttp://perso.wanadoo.fr/eitang

14 réponses

Messages postés
3825
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
1 février 2021
38
Salut,

j'ai pas testé mais ... essayes avec :
PostMessage(AppHandle, WM_SYSCOMMAND, SC_MAXIMIZE, 0);



[hr]@+Cirec
[hr]
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
13
Bienvenue,

ShowWindow est là pour ça.

function TForm1.MaxiApp(const sCapt: PChar): Boolean;
var
  hWinHandle: THandle;
begin
  hWinHandle:= FindWindow(nil, sCapt);
  ShowWindow(hWinHandle, SW_MAXIMIZE);
  Result:= True;
End;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MaxiApp('Sans titre - Bloc-notes');
end;
Messages postés
10
Date d'inscription
jeudi 31 décembre 2009
Statut
Membre
Dernière intervention
14 avril 2019

Cirec,

Merci, mais ça n'a pas marché ici.

rt15,

MERCI !!!

>> ShowWindow(hWinHandle, SW_MAXIMIZE);

Du premier coup !!! Formidable. Merci mille fois !

Maintenant je dois trouver (je ne demande pas encore <g>) comment savoir que
l'application a agrandir est DEJA prète a recevoir ce message... Elle est
longue a se lancer. (Je la lance avec ShellExecute). Je connais le WAIT
attendant la FIN du programme, mais ce n'est pas ce que je cherche...

Eitan Gilboa.

URL: ttp://perso.wanadoo.fr/eitang
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
13
Je ne réponds pas encore !

WaitForInputIdle
Messages postés
3825
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
1 février 2021
38
ah bon !!!

j'ai donc testé et ça fonctionne ... et du premier coup
[hr]procedure TForm1.Button2Click(Sender: TObject);

[b]begin
  /bMaxiApp('Sans titre - Bloc-notes');
end;
function TForm1.MaxiApp(const sCapt: PChar): Boolean;
[b]var
  /bhWinHandle: THandle;
[b]begin
  /bhWinHandle:=  FindWindow( nil , sCapt);
  PostMessage(hWinHandle, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
  Result: = True;
end;[hr]



[hr]@+Cirec
[hr]
Messages postés
10
Date d'inscription
jeudi 31 décembre 2009
Statut
Membre
Dernière intervention
14 avril 2019

Cirec,

Merci d'avoir essayé encore! OUI,ça marche très bien. Grand Pardon pour mon message d'hier. J'ai du mal ecrirla commande.

Bizarre que mon code, trouvé a plusieurs endroits sur internet:
PostMessage(AppHandle,WM_SIZE,SIZE_MAXIMIZED,0);

ne marche pas et le votre oui... Ils se "ressemblent" beaucoup <g>
PostMessage(hWinHandle, WM_SYSCOMMAND, SC_MAXIMIZE, 0);


rt15,

Grand merci a nouveau. Voici les lignes de mon programme:

   ShellExecute(Handle,
                 nil,
                 pchar(d), // d = chemin d'accès à l'executable
                 nil,nil,cmdshow);

  sCapt := PChar('iGO Zoomer - www.cybersuricate.com');
  AppHandle:=FindWindow(Nil, sCapt) ;

  WaitForInputIdle(AppHandle, INFINITE); // ne marche pas
  WaitForInputIdle(AppHandle, 20000);  // ne marche pas non plus. (10 secondes sont suffisantes)
  ShowWindow(AppHandle, SW_MAXIMIZE); 


Ne fais rien chez moi.

Explication de la fonction:
The time-out interval, in milliseconds. If dwMilliseconds is INFINITE,
the function does not return until the process is idle.

Merci beaucoup pour vos efforts.

J'ai utilisé un timer pour le delai et un autre pour afficher le tems restant et le problem est résolu...

Eitan Gilboa.

URL: ttp://perso.wanadoo.fr/eitang
Messages postés
10
Date d'inscription
jeudi 31 décembre 2009
Statut
Membre
Dernière intervention
14 avril 2019

rt15,

>> Bah oui forcément, quand on se sert mal de de WaitForInputIdle, ça marche moins bien !

Comme c'est la première fois que je vois cette fonction, c'est normal que je ne m'en serve pas parfaitement... Vu ton explication qui suit, je pense rester avec mes timers et ShellExecute qui fonctionnent très bien <g>

Grand merci, et a bientôt pour le prochain problème!

Eitan.
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
13
Arf, j'ai pas été très diplomate sur ce coup. Voilà le code, même si ça va pas me faire pardonner.

procedure TForm1.Button1Click(Sender: TObject);
var
  processInfo: TProcessInformation;
  startupInfo: TStartupInfo;
  nTime : Cardinal;
begin
  ZeroMemory(@startupInfo, SizeOf(TStartupInfo));
  startupInfo.cb:= SizeOf(TStartupInfo);
  startupInfo.dwFlags:= STARTF_USESHOWWINDOW;
  startupInfo.wShowWindow:= SW_SHOW;

  if not CreateProcess(nil, 'C:\Program Files\Microsoft Office\OFFICE11\winword.exe',
                       nil, nil, False, 0, nil, nil,
                       startupInfo, processInfo) then RaiseLastOSError;
  nTime:= GetTickCount;

  WaitForInputIdle(processInfo.hProcess, INFINITE);
  ShowMessage('Appli initalisée (' + IntToStr(GetTickCount - nTime) + ' millisecondes)');

  CloseHandle(processInfo.hProcess);
  CloseHandle(processInfo.hThread);
end;
Messages postés
10
Date d'inscription
jeudi 31 décembre 2009
Statut
Membre
Dernière intervention
14 avril 2019

rt15,

>> j'ai pas été très diplomate sur ce coup.

<LOL> On n'est pas à la cour suprème, ni en réunion de consuls chez Sarko <g> Ce n'est pas un problème de diplomacie, mais il est évident que si je pose cette question je ne connais pqs la réponse, voilà tout. Je ne suis pas vexé et mes remerciements sont preuve du pardon (non pas qu'il y ai eu besoin de pardonner)

>> Voilà le code, même si ça va pas me faire pardonner

Formidable. re-re-re-merci. J'essayerai.

Eitan.
Messages postés
10
Date d'inscription
jeudi 31 décembre 2009
Statut
Membre
Dernière intervention
14 avril 2019

rt15,

Oui, ça marche à merveille !!! Merci.

Finalement, le code est devenu très très simple... Je ne comprends pas tout, en particulier TStartupInfo ainsi que la différence entre Process et Thread....

Function TForm1.MaxiApp(const sCapt: PChar) : boolean;
  var AppHandle:THandle;
  i : integer;
begin
  AppHandle:=FindWindow(Nil, sCapt) ;
  PostMessage(AppHandle, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
  // OK aussi:  ShowWindow(AppHandle, SW_MAXIMIZE); 
end;

procedure TForm1.FormCreate(Sender: TObject);
var
 s, s2, d : string;
 i        : integer;
 processInfo : TProcessInformation;
 startupInfo : TStartupInfo;
 nTime       : Cardinal;

begin
  S2 :='iGO Zoomer - www.cybersuricate.com';

  if (NOT fileexists(ExtractFilePath(Application.exeName)+'iGOZoomer_108.exe')) then
  begin
      showmessage('NOT FOUND. - EXITING');
      Application.Terminate;
  end;

  d := ExtractFilePath(Application.exeName) + 'iGOZoomer_108.exe';

  ZeroMemory(@startupInfo, SizeOf(TStartupInfo));

  startupInfo.cb:= SizeOf(TStartupInfo);
  startupInfo.dwFlags:= STARTF_USESHOWWINDOW;
  startupInfo.wShowWindow:= SW_SHOW;

  if not CreateProcess(nil, pchar(d),
                       nil, nil, False, 0, nil, nil,
                       startupInfo, processInfo) then showmessage('failed');

  WaitForInputIdle(processInfo.hProcess, INFINITE);

  CloseHandle(processInfo.hProcess);
  CloseHandle(processInfo.hThread);

  MaxiApp('iGO Zoomer - www.cybersuricate.com');
  application.Terminate;
end;
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
13
La structure STARTUPINFO permet de fournir des infos de démarrage au processus lancé par CreateProcess. Il y a la taille, des handles d'entrée sortie... Mais la plupart de ces informations peuvent ne pas être utilisées par le processus créé (Ce sont des suggestions).

Dans le cas présent, on demande simplement que la fenêtre s'affiche (SW_SHOW). On est obligé de préciser la taille de la structure et on signale quels champs de la structure sont remplis avec des flags.

D'ailleurs tu aurais peut être pu utiliser directement SW_MAXIMIZE à la place de SW_SHOW dans cette structure.

PROCESS_INFORMATION est affecté par CreateProcess avec des informations sur le processus lancé. Il est impératif de fermer les hanles de cette structure avec CloseHandle.

Quand à la différence thread/processus, disons qu'un processus contient un thread principal et éventuellement des threads supplémentaire. Un processus dispose d'un espace mémoire privé, mais les threads d'un même processus vivent tous dans ce même espace mémoire. Un thread est une unité d'exécution. En gros c'est ce qui va exécuter les unes après les autres ce qui est généré à partir de tes lignes de Delphi.
Messages postés
10
Date d'inscription
jeudi 31 décembre 2009
Statut
Membre
Dernière intervention
14 avril 2019

rt15,

Grand merci. Je ne t'ai pas demandé de répondre à mes incompréhensions, mais tu las fait. Sympa!!!

Je profitte de ta bontée infinie :

>> Un processus dispose d'un espace mémoire privé, mais les threads d'un même processus vivent tous dans ce même espace mémoire. Un thread est une unité d'exécution.

Est-ce que ça veu dire que le programmeur doit prévoir cet "extra" de mémoire, dans le cas ou c'est l'utilisateur qui aurait l'option de demarrer des threads supplémentaires? Ce n'es pas l'OS qui atribuerais, a la demande?

Eitan.
Messages postés
10
Date d'inscription
jeudi 31 décembre 2009
Statut
Membre
Dernière intervention
14 avril 2019

rt15,

>> Un utilisateur ne peut pas directement démarrer de thread : Il démarre des processus.

Connais-tu Total Commander? C'est un formidable gestionnaire de fichiers.

Lorsqu'on demarre une copie, si elle est longue, on peut mettre son "progress-bar" en arriere plan (l'utilisateur) et continuer à utiliser TC librement.

L'auteur, Ghisler, appelle cela "un nouveau thread". Est-ce correct? C'est là l'origine de ma question.

Eitan.
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
13
Bah oui, il y a des chances qu'il ait mis un thread pour la copie. On utilise souvent les threads pour faire des tâches longue tout en gardant une fenêtre principale fonctionnelle.