Einzelnen Beitrag anzeigen

mm1256

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

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

  Alt 23. Jun 2015, 21: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
Wenn du mit Gott reden willst, dann bete.
Wenn du ihn treffen willst, schreib bei Tempo 220 eine SMS
  Mit Zitat antworten Zitat