AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Zwei Windows Explorer starten und nebeneinander bildschirmfüllend positionieren
Thema durchsuchen
Ansicht
Themen-Optionen

Zwei Windows Explorer starten und nebeneinander bildschirmfüllend positionieren

Ein Thema von FarAndBeyond · begonnen am 23. Jun 2015 · letzter Beitrag vom 19. Jul 2016
Antwort Antwort
mm1256

Registriert seit: 10. Feb 2014
Ort: Wackersdorf, Bayern
642 Beiträge
 
Delphi 10.1 Berlin Professional
 
#1

AW: Zwei Windows Explorer starten und nebeneinander bildschirmfüllend positionieren

  Alt 23. Jun 2015, 19:12
Hallo,

die Idee als solches finde ich ja gut. Die Zähne beisse ich mir aber schon seit über einer Stunde daran aus, das "Sleep" zu ersetzen, weil es ja hardwareabhängig ist.

Der Grundgedanke ist, aus dem ProcessHandle das WindowHandle zu bekommen.

Delphi-Quellcode:
function ShellExecExplorer(aClientHandle: THandle;
                           aParameters: string;
                           var aExplorerHandle: THandle): Boolean;
var
  SEI: TShellExecuteInfo;
begin
  aExplorerHandle := 0;
  FillChar(SEI, SizeOf(SEI), #0);
  SEI.cbSize := SizeOf(SEI);
  SEI.Wnd := aClientHandle;
  SEI.fMask := SEE_MASK_NOCLOSEPROCESS;
  SEI.lpVerb := 'open';
  SEI.lpFile := PChar('explorer.exe');
  SEI.lpParameters := PChar(aParameters);
  SEI.lpDirectory := nil;
  SEI.nShow := SW_SHOWNORMAL;
  Result := ShellExecuteEx(@SEI);
  if Result then begin
    if SEI.hProcess > 32 then begin
      Sleep(1000);
       // WaitForInputIdle(SEI.hProcess, INFINITE); hab ich probiert, tut nicht
    end;
  end;
  CloseHandle(SEI.hProcess);
end;
Vielleicht hat ja jemand eine Idee?
Gruss Otto PS: Sorry wenn ich manchmal banale Fragen stelle. Ich bin Hobby-Programmierer und nicht zu faul die SuFu zu benutzen
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#2

AW: Zwei Windows Explorer starten und nebeneinander bildschirmfüllend positionieren

  Alt 23. Jun 2015, 19:39
das "Sleep" zu ersetzen, weil es ja hardwareabhängig ist.
Was meinst du damit bzw. wo ist das Problem?
  Mit Zitat antworten Zitat
mm1256

Registriert seit: 10. Feb 2014
Ort: Wackersdorf, Bayern
642 Beiträge
 
Delphi 10.1 Berlin Professional
 
#3

AW: Zwei Windows Explorer starten und nebeneinander bildschirmfüllend positionieren

  Alt 23. Jun 2015, 20:15
Wenn die Explorer-Instanz nicht innerhalb der Sleep-Zeit gestartet wird, findet FindWindow kein Handle und folglich funzt auch MoveWindow nicht.

In der Zwischenzeit hab ich noch etwas rum gespielt. Schön wär es auch, wenn eine bereits vorhandene Instanz angezeigt und neu positioniert würde. Je länger ich daran "spiele" umso mehr gefällt mir der Gedanke.

Aktueller Stand (ist noch nicht fertig)

Delphi-Quellcode:
const
  TC = ' | ';

function ShellExecExplorer(aClientHandle: THandle;
                           aParameters: string;
                           var aExplorerHandle: THandle): Boolean;
var
  SEI: TShellExecuteInfo;
begin
  aExplorerHandle := 0;
  FillChar(SEI, SizeOf(SEI), #0);
  SEI.cbSize := SizeOf(SEI);
  SEI.Wnd := aClientHandle;
  SEI.fMask := SEE_MASK_NOCLOSEPROCESS;
  SEI.lpVerb := 'open';
  SEI.lpFile := PChar('explorer.exe');
  SEI.lpParameters := PChar(aParameters);
  SEI.lpDirectory := nil;
  SEI.nShow := SW_SHOWNORMAL;
  Result := ShellExecuteEx(@SEI);
  if Result then begin
    if SEI.hProcess > 32 then begin
      Sleep(1000);
// WaitForInputIdle(SEI.hProcess, 2000{ INFINITE});
    end;
  end;
  CloseHandle(SEI.hProcess);
end;

function EnumWindowsProc(aHandle: HWND; aLST: TStrings): Bool; stdcall; export;
var
  Caption, ClassName: array[0..MAX_PATH] of Char;
begin
  Result := True;
  if IsWindowVisible(aHandle) then begin
    GetClassName(aHandle, ClassName, MAX_PATH);
    if SameText(string(ClassName),'CabinetWClass') then begin
      GetWindowText(aHandle, Caption, MAX_PATH);
      aLST.Add(IntToStr(aHandle)+TC+UpperCase(string(Caption)));
    end;
  end;
end;

function JustDirectory(aDirectory: string): string;
var
  p: integer;
begin
  if (Pos(':',aDirectory) = 0) AND
     (Pos('\',aDirectory) = 0) AND
     (Pos('.',aDirectory) = 0)
  then Exit(aDirectory);
  Result := ExtractFileDir(aDirectory);
  p := Pos(':',Result);
  if p = 0 then exit;
  if Length(Result) <= 3 then SetLength(Result,1) else begin
    Delete(Result,1,3);
    p := Pos('\',Result);
    while p > 0 do begin
      Delete(Result,1,p);
      p := Pos('\',Result);
    end;
  end;
end;

function GetExplorerHandle(aCaption: string): THandle;
var
  i, p: integer;
  LST: TStrings;
begin
  Result := 0;
  LST := TStringList.Create;
  try
    EnumWindows(@EnumWindowsProc, Integer(LST));
    aCaption := UpperCase(JustDirectory(aCaption));
    for i := 0 to Pred(LST.Count) do begin
      if Pos(aCaption, LST[i]) > 0 then begin
        p := Pos(TC,LST[i]) - 1;
        Result := StrToIntDef(Copy(LST[i],1,p),0);
        Break;
      end;
    end;
  finally
    LST.Free;
  end;
end;

procedure WinExplorerStart(aClientHandle: THandle;
                           aLeftFileNameOrDirectory,
                           aRightFileNameOrDirectory : string);
var
  ExplorerHandle: THandle;

  procedure ShowExplorer(aHandle: THandle);
  var
    ForegroundWindowThreadID : Dword;
    WindowThreadID : DWord;
  begin
    if aHandle = GetForegroundWindow then exit;
    ForegroundWindowThreadID := GetWindowThreadProcessId(GetForegroundWindow, nil);
    WindowThreadID := GetWindowThreadProcessId(aHandle, nil);
    if (ForegroundWindowThreadID <> WindowThreadID) then begin
      AttachThreadInput(ForegroundWindowThreadID, WindowThreadID, true);
      SetForegroundWindow(aHandle);
      AttachThreadInput(ForegroundWindowThreadID, WindowThreadID, false);
    end else SetForegroundWindow(aHandle);
    ShowWindow(aHandle, SW_RESTORE);
  end;


  function Start(aCmdLine: string): boolean;
  begin
    Result := false;
    ExplorerHandle := GetExplorerHandle(JustDirectory(aCmdLine));
    if ExplorerHandle = 0 then begin
      if FileExists(aCmdLine)
      then aCmdLine := '/select,' + aCmdLine
      else begin
        aCmdLine := ExcludeTrailingBackslash(aCmdLine);
        // if not DirectoryExists(aCmdLine) then exit;
        // => keine gute Idee weil z.B. "Dokumente" oder "Dieser PC"
        // nicht funktioniert
      end;
      ShellExecExplorer(aClientHandle, aCmdLine, ExplorerHandle);
      ExplorerHandle := GetExplorerHandle(JustDirectory(aCmdLine));
    end else ShowExplorer(ExplorerHandle);
    Result := ExplorerHandle > 0;
  end;

begin
  if Start(aLeftFileNameOrDirectory)
  then MoveWindow(ExplorerHandle, 0, 0, (Screen.Width div 2), Screen.WorkAreaHeight, True);
  if Start(aRightFileNameOrDirectory)
  then MoveWindow(ExplorerHandle, Screen.Width div 2, 0, Screen.Width div 2, Screen.WorkAreaHeight, True);
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  WinExplorerStart(Handle,'C:\Windows', 'Dokumente');
end;
Gruss Otto PS: Sorry wenn ich manchmal banale Fragen stelle. Ich bin Hobby-Programmierer und nicht zu faul die SuFu zu benutzen
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.656 Beiträge
 
Delphi 12 Athens
 
#4

AW: Zwei Windows Explorer starten und nebeneinander bildschirmfüllend positionieren

  Alt 23. Jun 2015, 20:44
Nur so ein paar Ideen: wenn Du doch eh schon ShellExecuteEx verwendest, hast Du doch auch das Prozesshandle. Das könntest Du erstens dazu benutzen, um mit WaitForInputIdle darauf zu warten, dass der Prozess "befehlsbereit" ist, zum anderen dazu, mit EnumWindows und GetWindowThreadProcessId (oder ähnlichen Funktionen) das oder die Fenster zu ermitteln, die zum gerade gestarteten Prozess gehören (dürfte ja eigentlich nur ein Top-Level-Window je Explorer-Instanz sein, wenn ich keinen Denkfehler mache). Und das passt Du dann eben entsprechend an.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
mm1256

Registriert seit: 10. Feb 2014
Ort: Wackersdorf, Bayern
642 Beiträge
 
Delphi 10.1 Berlin Professional
 
#5

AW: Zwei Windows Explorer starten und nebeneinander bildschirmfüllend positionieren

  Alt 23. Jun 2015, 21:09
"WaitForInputIdle" hab ich ja schon versucht, siehe Kommentar, aber das kommt sofort zurück.

Die grundsätzliche Idee die hinter der Verwendung von ShellExecuteEx steckt ist ja, über das Processhandle auf das WindowHandle zu kommen. Aber wie? Da fehlt mir leider das Basiswissen.

Na ja, wenn es nicht geht, auch nicht schlimm. Ist kein Pflichtprojekt
Gruss Otto PS: Sorry wenn ich manchmal banale Fragen stelle. Ich bin Hobby-Programmierer und nicht zu faul die SuFu zu benutzen
  Mit Zitat antworten Zitat
hathor
(Gast)

n/a Beiträge
 
#6

AW: Zwei Windows Explorer starten und nebeneinander bildschirmfüllend positionieren

  Alt 23. Jun 2015, 23:11
Andere Version - aber die Version in #2 gefällt mir besser...

Delphi-Quellcode:
Function CallFileName( pFileName, pParameter : PChar): THandle;
var SEI: TShellExecuteInfo;
begin
 FillChar(SEI, SizeOf(SEI), 0);
 SEI.cbSize := SizeOf(SEI);
 SEI.fMask := SEE_MASK_NOCLOSEPROCESS;
 SEI.Wnd := GetTopWindow(0);
 SEI.lpVerb := 'OPEN';
 SEI.lpFile := pFileName;
 SEI.lpParameters := pParameter;
 SEI.lpDirectory := '';
 SEI.nShow := SW_SHOWNORMAL;
 SEI.hInstApp := 0;
 SEI.hProcess := 0;

 ShellExecuteEx( @SEI );
 Sleep(500);
 Result := SEI.hProcess;
end;

procedure TForm1.Button1Click(Sender: TObject);
var tmpHandle : THandle;
begin
  tmpHandle :=CallFileName(PChar('Explorer.exe'), PChar('F:\TOOLS'));
  MoveWindow(GetForegroundWindow, 0, 0,(Screen.Width div 2), Screen.WorkAreaHeight, True);

  tmpHandle :=CallFileName(PChar('Explorer.exe'), PChar('C:\'));
  MoveWindow(GetForegroundWindow, Screen.Width div 2, 0,(Screen.Width div 2), Screen.WorkAreaHeight, True);
end;
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:31 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz