Domanda

io uso per creare una funzione personalizzata come winexec(...):Hwnd che data di ritorno la maniglia di applicazione eseguita.

io ho usato la findwindow() ma avendo un problema, se cambia il titolo della finestra.

È stato utile?

Soluzione

Non c'è alcun modo per ottenere "il" handle di finestra di un'applicazione, perché non c'è alcuna garanzia che il programma ha una maniglia della finestra.Un programma può avere molti di livello superiore maniglie (cioè, Microsoft Word, uno per ogni documento), o si possono avere tutti.Si potrebbe mettere in discussione ciò che si ha realmente bisogno l'handle di finestra per;ci potrebbero essere modi migliori di fare qualunque cosa si sta cercando di fare, che non necessitano di alcuna specifica handle di finestra.

WinExec (che è sconsigliata per quasi 15 anni, così si dovrebbe considerare seriamente non lo usa più) e ShellExecute di ritorno assolutamente nessuna informazione circa i programmi di avvio, se essi, infatti, di avviare qualsiasi programma.(ShellExecute potrebbe utilizzare DDE per inviare un comando di un'istanza già in esecuzione dell'applicazione.) E se si avvia un'applicazione, potrebbe terminare prima che il programma venga eseguito più.

È possibile utilizzare CreateProcess o ShellExecuteEx invece.Se si avvia un programma, che vi darà un handle di processo che rappresenta il programma iniziato.È possibile utilizzare per aiutarvi a ottenere ulteriori informazioni circa il programma, ad esempio un elenco delle sue finestre.Non perdete tempo con FindWindow;la didascalia della finestra e della classe non è garantito per essere unico;un programma potrebbe utilizzare lo stesso nome della classe per molte finestre diverse e più istanze di un programma di utilizzare il nome della classe stessa, senza molto da selezionare quello che si vuole veramente.

EnumWindows è una funzione che è possibile utilizzare per ottenere un elenco di candidati handle di finestra.Un puntatore a funzione, e sarà chiamata la funzione una volta per ogni livello superiore della finestra sul desktop.Avrete bisogno di un modo di raccontare che il processo si è interessati, e un modo per restituire un elenco di risultati.La funzione accetta un parametro, il parametro dovrà essere un puntatore a una struttura che contiene più informazioni di:

type
  PWindowSearch = ^TWindowSearch;
  TWindowSearch = record
    TargetProcessID: DWord;
    ResultList: TWndList;
  end;

TWndList è un tipo che ho fatto per tenere una lista di HWnd valori.Se si dispone di Delphi 2009 o successiva, è possibile utilizzare TList<HWnd>;per le versioni precedenti, è possibile utilizzare un TList discendente o qualsiasi altra cosa si sceglie.

CreateProcess vi dirà il nuovo ID di processo in dwProcessID membro del TProcessInformation record riempie; ShellExecuteEx solo restituisce un handle di processo, in modo da utilizzare GetProcessID sul che.La finestra-l'enumerazione funzione ha bisogno di una funzione di callback che corrispondono a questa firma:

function SelectWindowByProcessID(Wnd: HWnd; Param: LParam): Bool; stdcall;

È possibile utilizzare EnumWindows per ottenere un handle lista come questa:

function GetWindowListByProcessID(pid: DWord): TWndList;
var
  SearchRec: TWindowSearch;
begin
  Result := TWndList.Create;
  try
    SearchRec.TargetProcessID := pid;
    SearchRec.ResultList := Result;
    Win32Check(EnumWindows(SelectWindowByProcessID, LParam(@SearchRec)));
  except
    Result.Free;
    raise;
  end;
end;

Sarà di implementare la funzione di callback come questo:

function SelectWindowByProcessID(Wnd: HWnd; Param: LParam): Bool; stdcall;
var
  SearchRec: PWindowSearch;
  WindowPid: DWord;
begin
  SearchRec := PWindowSearch(Param);
  Assert(Assigned(SearchRec));
  GetWindowThreadProcessID(Wnd, WindowPid);
  if WindowPid = SearchRec.TargetProcessID then
    SearchRec.ResultList.Add(Wnd);
  Result := True;
end;

Una volta che hai l'elenco, è possibile controllare gli altri attributi della finestra per determinare quali sono realmente quelli che si desidera.Si potrebbe determinare dal titolo della finestra o il nome di classe, o forse per gli altri controlli che sono una finestra.

Quando hai finito di utilizzare l'handle del processo, assicurarsi di chiamare CloseHandle su di esso in modo che il sistema operativo, il processo di pulizia della contabilità di informazioni.

Altri suggerimenti

C'è una funzione denominata EnumWindows.Penso che sarà utile a voi.

Controllare i seguenti link per ulteriori informazioni

http://delphi.about.com/od/windowsshellapi/l/aa080304a.htm

http://www.swissdelphicenter.ch/torry/showcode.php?id=327

Provare ad esempio 6 da questa pagina (http://delphidabbler.com/tips/134) e a modificarla un po'.Che è quello che ho fatto.

se si desidera dividere in cui si controlla e dove si rivede il risultato che si può fare qualcosa di simile

var
  //...
  runNext : Boolean;
  //...

begin
{ startup code from other sample here }

// but instead of if
runNext := ShellExecuteEx(@SEInfo);

{ some more code here }

    // need delay before running next process
    // run loop until window with Handle is closed
if runNext then
    with SEInfo do
     repeat
      GetExitCodeProcess(SEInfo.hProcess, ExitCode);
      Sleep(20);
      Application.ProcessMessages;
      CheckSynchronize();
    until (ExitCode <> STILL_ACTIVE) or Application.Terminated;

{ next process code here }
end;

Mi rendo conto che alcuni di voi cadrà la posta di odio su questo per il lancio Sleep(), ma io preferisco non bloccare le finestre fino a che l'esecuzione è terminata quando sto elaborazione di una barcata di roba e di attesa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top