Einzelnen Beitrag anzeigen

FarAndBeyond
(Gast)

n/a Beiträge
 
#27

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

  Alt 28. Nov 2015, 04:05
Final Version...

- fehlendes FensterHandle hinzugefügt
- Overkill entfernt
- Exception-Handling minimal informativer gemacht
- kein Sleep erforderlich

Ergebnis: läuft super schnell und stabil bei mir...
Sollte ich alle paar Monate die Fenster mal wieder neu positionieren müssen wäre mir das auch egal, aber bis jetzt läuft alles sauber...
Läuft auch unter Lazarus // {$Mode Delphi} // oder selber Handanlegen und anpassen

Delphi-Quellcode:
Program TwoWindowsExplorer;

 Uses
  Windows, Messages, Classes, SysUtils, ShellApi;

Type
  PFindWindowStruct = ^TFindWindowStruct;
  TFindWindowStruct = Record
   Caption : String;
   ClassName : String;
   WindowHandle: THandle;
  End;

 Var
  FoundWindows: TStringlist;
  WndHandle : THandle;


Procedure ErrorLog(ErrorInfo: String);
  Var
   LoadErrorLog : TStringlist;
   SaveErrorInfo: TStringlist;
   ErrorLog : String;

  Procedure Free_LoadErrorLog;
   Begin
    Try
     FreeAndNil(LoadErrorLog);
    Except
    End;
   End;

  Procedure Free_SaveErrorInfo;
   Begin
    Try
     FreeAndNil(SaveErrorInfo);
    Except
    End;
   End;

  Function ErrorLogExists : Boolean;
   Begin
    Try
     Result:= False;
      If FileExists('ErrorLog.txt')
      Then
       Begin
        Try
         LoadErrorLog:= TStringlist.Create;
         LoadErrorLog.LoadFromFile('ErrorLog.txt');
         ErrorLog:= LoadErrorLog.Text;
         Result:= True;
        Finally
         Free_LoadErrorLog;
        End;
       End;
    Except
    End;
   End;

 Begin
  Try
   Try
    SaveErrorInfo:= TStringlist.Create;
     SaveErrorInfo.Add(DateTimeToStr(Now));
     SaveErrorInfo.Add(ErrorInfo);

      If ErrorLogExists
      Then
       Begin
        SaveErrorInfo.Add(' ');
        SaveErrorInfo.Add(Trim(ErrorLog));
       End;

     SaveErrorInfo.SaveToFile('ErrorLog.txt');
   Finally
    Free_SaveErrorInfo;
   End;
  Except
  End;
 End;


Function EnumWindowsProc(hWindow: HWND; lParam: LongInt): Boolean; StdCall;
  Var
   lpBuffer : PChar;
   WindowCaptionFound: Boolean;
   ClassNameFound : Boolean;

  Procedure Free_Memory;
   Begin
    Try
     FreeMem(lpBuffer, SizeOf(lpBuffer^));
    Except
     On E: Exception
     Do ErrorLog('EnumWindowsProc: Free_Memory Failed'+#13#10+E.ClassName+#13#10+E.Message);
    End;
   End;

 Begin
  Try
   GetMem(lpBuffer, 255);
   Result := True;
   WindowCaptionFound:= False;
   ClassNameFound := False;
   Try
    If GetWindowText(hWindow, lpBuffer, 255) > 0
    Then
     Begin
      If PFindWindowStruct(lParam).Caption = ''
      Then WindowCaptionFound:= True
      Else
       Begin
        If Pos(PFindWindowStruct(lParam).Caption, StrPas(lpBuffer)) > 0
        Then WindowCaptionFound:= True;
       End;

      If PFindWindowStruct(lParam).ClassName = ''
      Then ClassNameFound:= True
      Else
       Begin
        If GetClassName(hWindow, lpBuffer, 255) > 0
        Then
         Begin
          If Pos(PFindWindowStruct(lParam).ClassName, StrPas(lpBuffer)) > 0
          Then ClassNameFound:= True;

          If (WindowCaptionFound And ClassNameFound)
          Then
           Begin
            PFindWindowStruct(lParam).WindowHandle:= hWindow;
            FoundWindows.Add(IntToStr(hWindow));
           End;
         End;
       End;
     End;
   Finally
    Free_Memory;
   End;
  Except
   On E: Exception
   Do ErrorLog('EnumWindowsProc Failed'+#13#10+E.ClassName+#13#10+E.Message);
  End;
 End;


Function FindAWindow(WinCaption: String; WinClassName: String): THandle;
  Var
   WindowInfo: TFindWindowStruct;
 Begin
  Try
   WindowInfo.Caption := WinCaption;
   WindowInfo.ClassName := WinClassName;
   WindowInfo.WindowHandle:= 0;

   EnumWindows(@EnumWindowsProc, LongInt(@WindowInfo));
   Result:= WindowInfo.WindowHandle;
  Except
   On E: Exception
   Do ErrorLog('FindAWindow Failed'+#13#10+E.ClassName+#13#10+E.Message);
  End;
 End;


Procedure StartTwoExplorer;
 Begin
  Try
   If DirectoryExists('I:\')
   Then
    Begin
     ShellExecute(0, Nil, PChar('I:\MARTIN'), Nil, Nil, SW_SHOW);
     ShellExecute(0, Nil, PChar('I:\MARTIN\(DOWNLOADS)'), Nil, Nil, SW_SHOW);
    End
   Else
    Begin
     ShellExecute(0, Nil, PChar('C:\'), Nil, Nil, SW_SHOW);
     ShellExecute(0, Nil, PChar('D:\'), Nil, Nil, SW_SHOW);
    End;
  Except
   On E: Exception
   Do ErrorLog('StartTwoExplorer Failed'+#13#10+E.ClassName+#13#10+E.Message);
  End;
 End;


Procedure CloseOneExplorer;
 Begin
  Try
   WndHandle:= StrToInt(FoundWindows[0]);
   PostMessage(WndHandle, WM_CLOSE, 0, 0);
   StartTwoExplorer;
  Except
   On E: Exception
   Do ErrorLog('CloseOneExplorer Failed'+#13#10+E.ClassName+#13#10+E.Message);
  End;
 End;


Procedure TwoExplorerToFront;
  Var
   I: Integer;
 Begin
  Try

   For I:= 0 To FoundWindows.Count-1
   Do
    Begin
     WndHandle:= StrToInt(FoundWindows[I]);
     If IsIconic(WndHandle)
     Then ShowWindow(WndHandle, SW_RESTORE)
     Else
      Begin
       ShowWindow(WndHandle, SW_MINIMIZE);
       ShowWindow(WndHandle, SW_RESTORE);
      End;
    End;
    
  Except
   On E: Exception
   Do ErrorLog('TwoExplorerToFront Failed'+#13#10+E.ClassName+#13#10+E.Message);
  End;
 End;


Procedure CloseAllExplorer;
  Var
   I: Integer;
 Begin
  Try

   For I:= 0 To FoundWindows.Count-1
   Do
    Begin
     WndHandle:= StrToInt(FoundWindows[I]);
     PostMessage(WndHandle, WM_CLOSE, 0, 0);
    End;

   StartTwoExplorer;
  Except
   On E: Exception
   Do ErrorLog('CloseAllExplorer Failed'+#13#10+E.ClassName+#13#10+E.Message);
  End;
 End;


Procedure Free_Stringlist;
 Begin
  Try
   FreeAndNil(FoundWindows);
  Except
   On E: Exception
   Do ErrorLog('Free_Stringlist Failed'+#13#10+E.ClassName+#13#10+E.Message);
  End;
 End;


Begin
 Try
  FoundWindows:= TStringlist.Create;
   Try
    FindAWindow('','CabinetWClass');

     Case FoundWindows.Count
     Of
      0 : StartTwoExplorer;
      1 : CloseOneExplorer;
      2 : TwoExplorerToFront;
      Else CloseAllExplorer;
     End;

   Finally
    Free_Stringlist;
   End;
 Except
  On E: Exception
  Do ErrorLog('MainProgram Failed'+#13#10+E.ClassName+#13#10+E.Message);
 End;
End.
Fur alle die Windows 7 mögen und dazu noch den WindowsExplorer hier eine einfache Anleitung:

1.
Quicklaunch einrichten und Icon auswählen, Rechtsklick auf Icon - Eigenschaften: Pfad zur EXE eingeben

2.
Icon klicken und damit die EXE zum ersten Mal starten

3.
Fenster positionieren (Hinweis: Die Fenster müssen von Hand ausgerichet werden. Man kann aber die automatische Andockmöglichkeit unter Windows7 nutzen damit das schneller geht. Ausschließlich Andocken geht nicht, da sich der Explorer dann die Position nicht merkt!

4.
Fenster schließen und erneut auf das eingerichtete Icon klicken: Feintuning vornehmen, so das nur noch 1 Pixel oder wenige Pixel unten unausgefüllt bleiben...
Wer Lust hat zu Fummeln bekommt sicher auch den letzten Pixel noch weg...

5.
Fertig! Ab jetzt nur noch den neuen Button benutzen, egal ob kein Fenster gestartet ist oder nur ein Fenster sichtbar ist oder ob beide Fenster schon im Hintergrund laufen...
Es ist nur noch ein Klick notwendig um die beiden WindowsExplorer-Fenster anzeigen zu lassen.

Hinweis: Es kann sein, dass man bis zu 3 bis 4 Versuche benötigt bis sich der WindowsExplorer die Position gemerkt hat.
Wenn die Position dann einmal drin ist hat man Ruhe und gleichzeitig läuft das Ganze richtig schnell...

Ob das auch unter Windows 8 oder 8.1 läuft kann ich nicht sagen.
Ob das auch mit mehreren Monitoren oder größeren Monitoren und mehr Fenstern geht kann ich auch nicht sagen... TryAndError...for yourself...
Miniaturansicht angehängter Grafiken
twowindowsexplorer-screenshot.png  

Geändert von FarAndBeyond (28. Nov 2015 um 04:15 Uhr) Grund: Screenshot
  Mit Zitat antworten Zitat