Position fenêtre avec ShellExecute [Résolu]

Signaler
Messages postés
6
Date d'inscription
mardi 9 septembre 2008
Statut
Membre
Dernière intervention
7 septembre 2009
-
cs_lebidouilleur
Messages postés
6
Date d'inscription
mardi 9 septembre 2008
Statut
Membre
Dernière intervention
7 septembre 2009
-
Bonjour,
Est-il possible de contrôler la position de la fenêtre d'une application lancée avec ShellExecute?
(Par exemple ouvrir un éditeur de texte en haut à droite de l'écran?)

12 réponses

Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
6
T'as aussi :

;,,ÝüÜyâÍ@*~

(ce sont tous les deux des API très simples commençant par "SetWi"...)

Cordialement, Bacterius !

Salut,

ShellExecute est une fonction API windowsienne. Elle est donc documentée dans la MSDN : Il suffit de lire

Dans ma fonction ShellExecute, il y a un parametre correspondant à un Handle. Connaissant le handle de l'application lancée, tu dois pouvoir placer la fenetre associée ou tu veux non ?
Messages postés
2527
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
16 octobre 2019
13
NAN, NAN! Y PEUT PAS.

Y'a 100 exemples de ShellExecute rien que sur ce site... Mais ça prend trop la tête.

'faut livrer à domicile!

Parce que les nouveaux programmeurs n'ont plus de temps à perdre avec ces c*** de recherches.

T'as pas répondu à la question, Francky !
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
6
La réponse est ...






...












...












............























;,,ÝüÜyâÍB nC

_______________________________


L'algo existe quelque part sur ce site, et il nécessite une clef.
Il suffit de chercher

...

Ah un indice : "DelphiFR"

Cordialement, Bacterius !



PS : oui je promote mes sources et alors j'ai pas le droit ? Ca leur fait un peu chercher ... de façon inhabituelle seulement :p

@Cari : "T'as pas répondu à la question, Francky !" Désolé Francky fait pas de livraison de Codes à domicile .

J'ai simplement voulu lui montrer que si la nature nous a doté d'un cerveau, c'est pour s'en servir . Autrement dit, la fonction ShellExecute ne permettait pas de faire une telle chose, trouver une parade ne nécessitait aucune prédisposition intéllectuelle, juste un peur de courage et un peu de réflexion .

je veux une fonction éditer pour corriger les fautes Si vou plé M'sieurs les Developpeurs
Messages postés
6
Date d'inscription
mardi 9 septembre 2008
Statut
Membre
Dernière intervention
7 septembre 2009

Merci Bactérius
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
6
De rien cher ami. Peux-tu poster la réponse en clair afin d'en faire profiter tout le monde ?

Cordialement, Bacterius !
Messages postés
6
Date d'inscription
mardi 9 septembre 2008
Statut
Membre
Dernière intervention
7 septembre 2009

Pour ceux qui seraient confrontés au même problème: plusieurs solutions:
1 consulter la doc de l'API windows, ce qui ne requière aucune prédisposition intellectuelle (il faut quand même savoir lire), vous finirez bien par trouver

2 utiliser la fonction SetWindowPos qui permet de positionner une fenêtre connaissant son handle.

Cordialement,
Messages postés
3793
Date d'inscription
samedi 22 décembre 2007
Statut
Membre
Dernière intervention
3 juin 2016
6
Yeah c'est bien SetWindowPos (j'avais mis SetWindowRect au début sans réfléchir mais j'ai fait un keyboard-lapsus ...).

Cordialement, Bacterius !
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
10
Salut,

Sinon, il y a une solution plus propre avec CreateProcess. Mais elle ne fonctionne que sur certains .exe, ceux qui utilisent CW_DEFAULT dans leur CreateWindow (Par exemple notepad n'est pas dans ce cas là, mais sysedit si).

procedure TForm1.Button1Click(Sender: TObject);
var
  startupInfo: TStartupInfo;
  processInfo: TProcessInformation;
begin
  ZeroMemory(@startupInfo, SizeOf(startupInfo));
  with startupInfo do
  begin
    cb:= SizeOf(startupInfo);
    dwFlags:= STARTF_USESHOWWINDOW or STARTF_USEPOSITION or STARTF_USESIZE;
    wShowWindow:= SW_SHOW;
    dwX:= 10;
    dwY:= 10;
    dwXSize:= 800;
    dwYSize:= 300;
  end;
  if not CreateProcess(nil, 'sysedit', nil, nil, False, 0, nil, nil, startupInfo, processInfo) then
    RaiseLastOSError
  else
  begin
    CloseHandle(processInfo.hProcess);
    CloseHandle(processInfo.hThread);
  end;
end;


Utiliser SetWindowPos est risqué car il faut récupérer le handle de la fenêtre de l'appli juste lancée. Donc si elle n'est pas complètement lancée, la fenêtre n'existe pas encore... D'où l'utilisation d'un Sleep, mais difficile de fixer sa valeur. Autre problème, plusieurs instance de l'application à lancer peuvent exister -> plusieurs fenêtres correspondantes. On utilise alors GetWindowThreadProcessId et comparer avec le PID renvoyé par CreateProcess.

Voilà une solution de meilleure qualité qu'avec un Sleep en utilisant WaitForSingleObject (On est sur d'attendre suffisamment tout en attendant le minimum de temps). Par contre il y a un risque de partir en boucle infinie. Mais il est réduit car la boucle s'arrête si le processus lancé s'arrête.

type TFindWindowParam = packed record
  nPid: Cardinal;
  bFound: LongBool;
end;

implementation

function EnumWndAndResize(hWnd: THandle; var lpFindWindowParam: TFindWindowParam): LongBool; stdcall;
var
  nPid: Cardinal;
begin
  Result:= True;

  // Changement de position si le PID correspond
  GetWindowThreadProcessId(hWnd, @nPid);
  if nPid = lpFindWindowParam.nPid then
  begin
    SetWindowPos(hWnd, 0, 10, 10, 800, 300, SWP_NOZORDER);
    lpFindWindowParam.bFound:= True;
    Result:= False;    // On arrête l'énumération
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  startupInfo: TStartupInfo;
  processInfo: TProcessInformation;
  findWindowParam: TFindWindowParam;
begin
  ZeroMemory(@startupInfo, SizeOf(startupInfo));
  with startupInfo do
  begin
    cb:= SizeOf(startupInfo);
    dwFlags:= STARTF_USESHOWWINDOW;
    wShowWindow:= SW_SHOW;
  end;
  if not CreateProcess(nil, 'notepad', nil, nil, False, 0, nil, nil, startupInfo, processInfo) then
    RaiseLastOSError
  else
  begin
    // Initialisation du paramètre passé à la fonction d'énumération des fenêtres
    with findWindowParam do
    begin
      nPid:= processInfo.dwProcessId;
      bFound:= False;
    end;

    // Boucle toute les milliseconde tant que le processus créé existe
    while WaitForSingleObject(processInfo.hProcess, 1) = WAIT_TIMEOUT do
    begin
      // Cherche une fenêtre correspondant
      EnumWindows(@EnumWndAndResize, Integer(@findWindowParam));
      if findWindowParam.bFound then Break;
    end;
    
    CloseHandle(processInfo.hProcess);
    CloseHandle(processInfo.hThread);
  end;
end;
Messages postés
6
Date d'inscription
mardi 9 septembre 2008
Statut
Membre
Dernière intervention
7 septembre 2009

Merci pour cette réponse.
Je m'étais effectivement contenté d'un sleep pour être sûr que l'appli était complètement lancée, mais je vais essayer ça.

cordialement,