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

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
Seite 3 von 7     123 45     Letzte » 
hathor
(Gast)

n/a Beiträge
 
#21

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

  Alt 15. Jul 2015, 08:21
Nach dem gleichen Verfahren lassen sich auch 2 IEXPLORE.exe anzeigen.
Es sind nur geringe Änderungen erforderlich.

Delphi-Quellcode:
unit Unit1; //20150630 20150715

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Winapi.ShellApi, Vcl.StdCtrls, Winapi.ShlObj, Winapi.ActiveX, System.Win.ComObj;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    Panel3: TPanel;
    bnClose: TButton;
    bnMax: TButton;
    bnMin: TButton;
    Button1: TButton;
    Button2: TButton;
    procedure FormShow(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure bnCloseClick(Sender: TObject);
    procedure bnMaxClick(Sender: TObject);
    procedure bnMinClick(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    procedure ExplorerStart(aPanel: TPanel; aDirectory: string);
  protected

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  SetWindowLong(Handle, GWL_STYLE, (GetWindowLong(Handle, GWL_STYLE) and not WS_Caption));
end;

procedure TForm1.bnMaxClick(Sender: TObject);
begin Perform(WM_SYSCOMMAND,SC_MAXIMIZE,0); end;

procedure TForm1.bnMinClick(Sender: TObject);
begin Perform(WM_SYSCOMMAND,SC_MINIMIZE,0); end;

procedure TForm1.Button2Click(Sender: TObject);
begin //
end;

procedure TForm1.ExplorerStart(aPanel: TPanel; aDirectory: string);
var SEI: TShellExecuteInfo;
begin
  aPanel.Caption := aDirectory;
  FillChar(SEI, SizeOf(SEI), #0);
  SEI.cbSize := SizeOf(SEI);
  SEI.Wnd := Handle;
  SEI.fMask := SEE_MASK_NOCLOSEPROCESS;
  SEI.lpVerb := 'open';
  SEI.lpFile := PChar('iexplore.exe'); // <--------------------
  SEI.lpParameters := PChar(aDirectory);
  SEI.lpDirectory := nil;
  SEI.nShow := SW_MINIMIZE;
  if ShellExecuteEx(@SEI) then begin
    if SEI.hProcess > 32 then begin
      Sleep(500);
      aPanel.Tag := FindWindow('IEFrame',nil); // <--------------------
      if aPanel.Tag > 0 then begin
        Winapi.Windows.SetParent(aPanel.Tag, aPanel.Handle);
        SetWindowLongPtr(aPanel.Tag, GWL_STYLE, GetWindowLongPtr(aPanel.Tag, GWL_STYLE)
        and not WS_BORDER);
        SetWindowPos(aPanel.Tag, HWND_TOP, Left, Top, Width, Height, SWP_FRAMECHANGED);
      end;
    end;
  end;
  CloseHandle(SEI.hProcess);
end;
//------------------------------------------------------------------------------
procedure TForm1.FormDestroy(Sender: TObject);
begin
  if Panel1.Tag > 0 then PostMessage(Panel1.Tag, WM_CLOSE, 0, 0);
  if Panel2.Tag > 0 then PostMessage(Panel2.Tag, WM_CLOSE, 0, 0);
end;

procedure TForm1.bnCloseClick(Sender: TObject);
begin Application.Terminate; end;

procedure TForm1.FormResize(Sender: TObject);
begin
  Panel1.Width := ClientWidth div 2;
  if Panel1.Tag > 0 then MoveWindow(Panel1.Tag, 0, 0, Panel1.Width, Panel1.Height, True);
  if Panel2.Tag > 0 then MoveWindow(Panel2.Tag, 0, 0, Panel2.Width, Panel2.Height, True);
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  ExplorerStart(Panel1,'-new www.web.de'); // <------------ // Sample
  ExplorerStart(Panel2,'-new www.google.de'); // <------------// Sample
end;

end.
Miniaturansicht angehängter Grafiken
iexplore2x.jpg   wetter-lte-1.jpg  

Geändert von hathor (15. Jul 2015 um 08:36 Uhr)
  Mit Zitat antworten Zitat
FarAndBeyond
(Gast)

n/a Beiträge
 
#22

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

  Alt 5. Sep 2015, 20:13
Hab' das Ding etwas frisiert... Jetzt läuft das viel besser und stabiler bei mir...ist auch viel praktischer so: nur ein Klick und man hat beide vorne falls schon zwei geöffnet waren.
Ohne Delay oder Sleep.. Blitzschnell... Nur einmal zwei Fenster positionieren und das war's dann...
Leider hab' ich noch immer keine Möglichkeit gefunden das Verhalten des WindowsExplorers abzuschalten.
Delphi-Quellcode:
Unit u2WindowsExplorer;

Interface

 Uses
  Windows, Messages, SysUtils, Classes, Controls, Forms, ShellApi;
 
 Type
  TForm1 = Class(TForm)
   Procedure FormCreate(Sender: TObject);
   Procedure FormActivate(Sender: TObject);
   Procedure FormShow(Sender: TObject);
  End;

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

 Var
  Form1 : TForm1;
  stringlist_FindWindow : TStringlist;
  WindowHandle : THandle;
Implementation
 {$R *.dfm}


Procedure ErrorLog(ErrorInfo: String);
  Var
   LogFile : TStringlist;
   LoadedFile : TStringlist;
   boolean_Loaded : Boolean;

  Procedure LoadErrorLog;
   Begin
    Try
     boolean_Loaded := False;
     If FileExists('ErrorLog.txt')
     Then
      Begin
       LoadedFile := TStringlist.Create;
       LoadedFile.LoadFromFile('ErrorLog.txt');
       boolean_Loaded := True;
      End;
    Except
     Exit;
    End;
   End;

  Procedure Free_LogFile;
   Begin
    Try
     FreeAndNil(LogFile);
    Except
     Exit;
    End;
   End;

  Procedure Free_LoadedFile;
   Begin
    Try
     FreeAndNil(LoadedFile);
    Except
     Exit;
    End;
   End;

 Begin
  LoadErrorLog;
   Try
    LogFile:= TStringlist.Create;
     Try
      If boolean_Loaded = True
      Then
       Begin
        LogFile.Add(ErrorInfo);
        LogFile.Text := LogFile.Text + LoadedFile.Text;
        Free_LoadedFile;
       End
      Else
       Begin
        LogFile.Add(ErrorInfo);
       End;

      LogFile.SaveToFile('ErrorLog.txt');
     Finally
      Free_LogFile;
     End;
   Except
    Free_LoadedFile;
    Exit;
   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
     ErrorLog('EnumWindowsProc (Free_Memory) Failed');
     Exit;
    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;
            stringlist_FindWindow.Add(IntToStr(hWindow));
           End;
         End;
       End;
     End;
   Finally
    Free_Memory;
   End;
  Except
   ErrorLog('EnumWindowsProc Failed');
   Exit;
  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
   ErrorLog('FindAWindow Failed');
   Exit;
  End;
 End;


Procedure Start2WindowsExplorer;
 Begin
  Try
   If DirectoryExists('I:\')
   Then
    Begin
     ShellExecute(Form1.Handle, Nil, PChar('I:\MARTIN'), Nil, Nil, SW_SHOW);
     ShellExecute(Form1.Handle, Nil, PChar('I:\MARTIN\(DOWNLOADS)'), Nil, Nil, SW_SHOW);
    End
   Else
    Begin
     ShellExecute(Form1.Handle, Nil, PChar('C:\'), Nil, Nil, SW_SHOW);
     ShellExecute(Form1.Handle, Nil, PChar('D:\'), Nil, Nil, SW_SHOW);
    End;
  Except
   ErrorLog('Start2WindowsExplorer Failed');
   Exit;
  End;
 End;


Procedure Close1WindowsExplorer;

  Procedure Terminate;
   Begin
    Try
     WindowHandle := StrToInt(stringlist_FindWindow[0]);
     PostMessage(WindowHandle, WM_QUIT, 0, 0);
    Except
     ErrorLog('Close1WindowsExplorer (Terminate) Failed');
     Exit;
    End;
   End;

 Begin
  Try
   PostMessage(WindowHandle, WM_CLOSE, 0, 0);
   Start2WindowsExplorer;
  Except
   ErrorLog('Close1WindowsExplorer Failed');
   Terminate;
   Exit;
  End;
 End;


Procedure Bring2WindowsExplorerToFront;
  Var
   i : Integer;
 Begin
  Try
   For i:= 0 To stringlist_FindWindow.Count-1
   Do
    Begin
     WindowHandle := StrToInt(stringlist_FindWindow[i]);
     If IsIconic(WindowHandle)
     Then ShowWindow(WindowHandle, SW_RESTORE)
     Else
      Begin
       ShowWindow(WindowHandle, SW_MINIMIZE);
       ShowWindow(WindowHandle, SW_RESTORE);
      End;
    End;
  Except
   ErrorLog('Bring2WindowsExplorerToFront Failed');
   Exit;
  End;
 End;


Procedure DeleteAllAndStart2WindowsExplorer;
  Var
   i: Integer;
 Begin
  Try
   For i:= 0 To stringlist_FindWindow.Count-1
   Do
    Begin
     WindowHandle := StrToInt(stringlist_FindWindow[i]);
     PostMessage(WindowHandle, WM_CLOSE, 0, 0);
    End;
   Start2WindowsExplorer;
  Except
   ErrorLog('DeleteAllAndStart2WindowsExplorer Failed');
   Exit;
  End;
 End;


Procedure TForm1.FormCreate(Sender: TObject);

  Procedure Free_Stringlist;
   Begin
    Try
     FreeAndNil(stringlist_FindWindow);
    Except
     ErrorLog('FormCreate (Free_Stringlist) Failed');
     Exit;
    End;
   End;

 Begin
  Try
   Form1.Height := 1;
   Form1.Width := 1;
   Form1.Top := 0;
   Form1.Left := 0;
   Form1.AlphaBlend := True;
   Form1.AlphaBlendValue := 0;

   stringlist_FindWindow := TStringlist.Create;
    Try
     FindAWindow(':\', 'CabinetWClass');

     Case stringlist_FindWindow.Count
     Of
      0 : Start2WindowsExplorer;

      1 : Close1WindowsExplorer;

      2 : Bring2WindowsExplorerToFront;
     Else
      Begin
       DeleteAllAndStart2WindowsExplorer;
      End;
     End;
    Finally
     Free_Stringlist;
    End;
  Except
   ErrorLog('FormCreate Failed');
   Exit;
  End;
 End;


Procedure TForm1.FormShow(Sender: TObject);
   Var Owner: HWND;
 Begin
  Try
   Owner := GetWindow(Form1.Handle, GW_OWNER);
   ShowWindow(Owner, SW_HIDE);
  Except
   Exit;
  End;
 End;


Procedure TForm1.FormActivate(Sender: TObject);

  Procedure Terminate;
   Begin
    Try
     Application.Terminate;
    Except
     Exit;
    End;
   End;

 Begin
  Try
   Close;
  Except
   Terminate;
  End;
 End;

End.
WindowsTaste + E kann man problemlos nutzen und das neue Fenster kann man auch problemlos verschieben...
Darin zu suchen ist wahrscheinlich keine so gute Idee, hab' ich noch nicht getestet.

Auf STRG+N sollte man aber verzichten...

Ich hätte niemals gedacht, dass es so nervig sein kann ein Fenster das "wsNormal" ist nach vorne zu holen.
Delphi-Quellcode:
ShowWindow(WindowHandle, SW_Show); // Funktioniert nicht!
ShowWindow(WindowHandle, SW_ShowNormal); // Funktioniert nicht!

SetWindowPos(WindowHandle, HWND_TOP, .... // Funktioniert nicht!
SetWindowPos(WindowHandle, HWND_NoTOPMOST, // Funktioniert nicht!
SetWindowPos(WindowHandle, HWND_TOPMOST, // Das funzt, ist aber bei normaler Shell nicht zu empfehlen, bei eigener Shell vielleicht 'ne Lösung.

ShowWindow(WindowHandle, SW_MINIMIZE); //und gleichzeitig dahinter SW_Restore
ShowWindow(WindowHandle, SW_RESTORE); // Das hat bis jetzt immer geklappt.. zu 100%, auch bei mehreren Fenstern

//Vielleicht sollte ich nochmal WindowState probieren, aber ich meine, ich hätte damit früher schonmal Schwierigkeiten bekommen...
//SetForegroundWindow funzt nur für ein Fenster...
Zwei einfache wsNormal-Fenster wirklich immer nach vorne zu kriegen ohne "Topmost" ist tatsächlich ein kleines Wunder!
Alter Schwede ich kotz gleich in die Ecke...
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#23

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

  Alt 6. Sep 2015, 00:08
Kann es sein, dass du eine "Exception Paranoia" hast?
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
FarAndBeyond
(Gast)

n/a Beiträge
 
#24

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

  Alt 6. Sep 2015, 03:14
@Sir Rufo:
Nennt man das jetzt so? ... grins...
Ja mag sein, dass die Bezeichnung ins Schwarze trifft...

Ich hab' jetzt zwar gelernt, wie man es offiziell richtig macht, aber ich kann mich noch nicht so richtig dazu durchringen das umzusetzen. Es gibt da immer noch so eine Stimme die sagt:"Mach das Programm nicht zu geschwätzig, mach 'n ErrorLog für dich und schick' nur die Meldung 'raus, die dem Nutzer auch wirklich weiterhelfen kann.
Ich pendel noch zwischen den Polen und werd' meinen Weg wohl noch finden...

Kann sich nur noch um 100 Jahre handeln...

Ach so, vielleicht hast du auch einfach nur das WM_Quit gesehen... das kann da eigentlich weg... hab' 'n bisschen 'rumgespielt...

Hat aber auch 'was praktisches, ich teste meine Programme meistens außerhalb der IDE, dann muß ich bei 'nem falschen Stringlist Index nicht immer per Taskmanager Delphi7 killen und anschließend wieder neu starten... so weiß ich immer wo es kracht und zwar präzise mit meinen eigenen Worten bzw. Prozeduren...

Gut Ding will Weile haben oder wie war das...
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#25

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

  Alt 6. Sep 2015, 12:03
Hat aber auch 'was praktisches, ich teste meine Programme meistens außerhalb der IDE, dann muß ich bei 'nem falschen Stringlist Index nicht immer per Taskmanager Delphi7 killen und anschließend wieder neu starten... so weiß ich immer wo es kracht und zwar präzise mit meinen eigenen Worten bzw. Prozeduren...
Auch bei Delphi 7 konnte man das Programm stoppen wenn ein Fehler aufgetreten ist. Es gibt zwar keinen so schönen Stopp-Button in der ToolBar, aber über das Menü "Start" (so heißt es bei Delphi 2010 und XE3 und XE4 und ... kann man das Programm stoppen. Alternativ über den HotKey STRG + F2. Solltest du mal ausprobieren. Dann kannst du auch den Debugger sinvoll nutzen.
  Mit Zitat antworten Zitat
FarAndBeyond
(Gast)

n/a Beiträge
 
#26

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

  Alt 6. Sep 2015, 19:29
@Aviator:
Ja, das wär' schön... bei kleineren Fehlern, die mal auftreten kann man RESET (STRG+F2) drücken und ist wieder in der IDE. Aber bei sehr vielen StringlistINDEX-Fehlern stoppt Delphi das Programm und zeigt das auch in der Titelleiste an. Dann funktioniert RESET nicht mehr und auch per Taskmanager kann ich das Programm nicht mehr abschießen.
Das Einzige was dann noch geht ist Delphi7 komplett per Taskmanager abzuschießen und das ist nervig, da ich dann alle Units neuladen muss und wieder an die Position wo ich war gehen muss...
Man kann den Ladevorgang zwar automatisieren, aber damit hatte ich schonmal 'ne Menge "Spass" und hab' das dann wieder abgeschaltet.

Ja ich hab' gehört, dass es einen Debugger gibt, hab' ihn noch nie benutzt... vielleicht wird das irgendwann mal interessant, wenn ich genau herausfinden muss was der Prozess genau macht. Normalerweise programmiere ich einfach alles um, schließlich kann man ja eine Sache auf 1000 verschiedene Arten machen und die verschiedensten Befehle dazu nutzen. Also wenn etwas auf eine Art nicht klappt, egal ob es an mir liegt oder daran, dass es einfach so nicht geht, dann mache ich es eben auf eine andere Art...
  Mit Zitat antworten Zitat
FarAndBeyond
(Gast)

n/a Beiträge
 
#27

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

  Alt 28. Nov 2015, 05: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 05:15 Uhr) Grund: Screenshot
  Mit Zitat antworten Zitat
FarAndBeyond
(Gast)

n/a Beiträge
 
#28

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

  Alt 6. Jul 2016, 00:26
Finally ....

Ich hab's !!! Man kann den Windows-Explorer doch völlig problemlos positionieren mit "MoveWindow" und das Ganze ohne "Sleep".
Zuerst hatte ich an zwei Stellen "Sleep(10)", dachte das wäre notwendig, aber wenn ich das weglasse funzt es genauso.
Also weg damit... nicht das 20ms irgend eine Rolle gespielt hätten...

Und wo liegt jetzt die Magie???

Here it comes: ...and the winner is:
"die Repeat-Schleife" ... gepriesen sei die heilige Repeat-Schleife für ihre Existenz...
Delphi-Quellcode:
Repeat
 slFoundWnd.Clear;
 FindAllWindows('','CabinetWClass');
Until slFoundWnd.Count >= 2;
Das die Lösung so einfach ist hätte mir ruhig mal einer von euch "stecken" können... ... den Wald vor lauter Bäumen...

Und hier das ganze Ding:
Da mir das BringToFront mit "Minimize" und "Restore" zu nervig war hab' ich einfach alles weggelassen und lösche jetzt einfach immer alle Fenster. Somit gibt es nur noch eine Prozedur "StartTwoWinEx"... ist auch gleich viel übersichtlicher... Ich brauche eh nur zwei Fenster...

Jetzt kann man die beiden Windows-Explorer-Fenster drehen, biegen, zerknüddeln... ohne das sich irgendwas an der erneuten Darstellung ändert. Schon beim nächsten Klick auf den QuickLaunch-Button sieht alles wieder sauber und gerade aus (bildschirmfüllend) und ich brauche die TaskbarButton überhaupt nicht mehr benutzen... sehr schön ...
Delphi-Quellcode:
PROGRAM TwoWindowsExplorer;

 USES
  Windows, Messages, Classes, Forms, SysUtils, ShellApi;

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

 VAR
  slFoundWnd: TStringlist;
  WndHandle : THandle;
  I : Integer;

Procedure ErrorLog(ErrorInfo: String);
  Var
   slLoad : TStringlist;
   slSave : TStringlist;
   strErrorLog: String;

  Procedure Free_slLoad;
   Begin
    Try
     FreeAndNil(slLoad);
    Except
    End;
   End;

  Procedure Free_slSave;
   Begin
    Try
     FreeAndNil(slSave);
    Except
    End;
   End;

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

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

      If ErrorLogExists
      Then
       Begin
        slSave.Add(' ');
        slSave.Add(Trim(strErrorLog));
       End;

     slSave.SaveToFile('ErrorLog.txt');
   Finally
    Free_slSave;
   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'+#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;
            slFoundWnd.Add(IntToStr(hWindow));
           End;
         End;
       End;
     End;
   Finally
    Free_Memory;
   End;
  Except
   On E: Exception
   Do ErrorLog('EnumWindowsProc'+#13#10+E.ClassName+#13#10+E.Message);
  End;
 End;


Function FindAllWindows(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('FindAllWindows'+#13#10+E.ClassName+#13#10+E.Message);
  End;
 End;


Procedure StartTwoWinEx;
 Begin
  Try
   If DirectoryExists('I:\') And DirectoryExists('I:\(DOWNLOADS)')
   Then
    Begin
     ShellExecute(0, Nil, PChar('I:\'), Nil, Nil, SW_SHOW);
     ShellExecute(0, Nil, PChar('I:\(DOWNLOADS)'), Nil, Nil, SW_SHOW);

      Repeat
       slFoundWnd.Clear;
       FindAllWindows('','CabinetWClass');
       // Sleep(10);
      Until slFoundWnd.Count >= 2;

       // Sleep(10);
     MoveWindow(StrToInt(slFoundWnd[0]),
                0,
                0,
                (Screen.WorkAreaWidth Div 2),
                Screen.WorkAreaHeight,
                True);

     MoveWindow(StrToInt(slFoundWnd[1]),
                (Screen.WorkAreaWidth Div 2),
                0,
                (Screen.WorkAreaWidth Div 2),
                Screen.WorkAreaHeight,
                True);
    End
   Else
    Begin
     ShellExecute(0, Nil, PChar('C:\'), Nil, Nil, SW_SHOW);
     ShellExecute(0, Nil, PChar('D:\'), Nil, Nil, SW_SHOW);

      Repeat
       slFoundWnd.Clear;
       FindAllWindows('','CabinetWClass');
      Until slFoundWnd.Count >= 2;

     MoveWindow(StrToInt(slFoundWnd[0]),
                0,
                0,
                (Screen.WorkAreaWidth Div 2),
                Screen.WorkAreaHeight,
                True);

     MoveWindow(StrToInt(slFoundWnd[1]),
                (Screen.WorkAreaWidth Div 2),
                0,
                (Screen.WorkAreaWidth Div 2),
                Screen.WorkAreaHeight,
                True);
    End;
  Except
   On E: Exception
   Do ErrorLog('StartTwoWinEx'+#13#10+E.ClassName+#13#10+E.Message);
  End;
 End;


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


Begin
 Try
  slFoundWnd:= TStringlist.Create;
   Try
    FindAllWindows('','CabinetWClass');
     If slFoundWnd.Count >= 1
     Then
      Begin
       For I:= 0 To slFoundWnd.Count-1
       Do
        Begin
         WndHandle:= StrToInt(slFoundWnd[I]);
         SendMessage(WndHandle, WM_CLOSE, 0, 0);
        End;
      End;
    StartTwoWinEx;
   Finally
    Free_slFoundWnd;
   End;
 Except
  On E: Exception
  Do ErrorLog('MAIN PRG'+#13#10+E.ClassName+#13#10+E.Message);
 End;
End.
Getestet mit D7 und W7x64 Sp1...
Auf älteren Lazarus-Versionen lieft das im Delphi-Mode sehr gut, aber Version 1.6 mag den PFindWindowStruct TypeCast 4->8 wohl nicht... Wenn ich auch noch nicht kapiert hab' was der Compiler damit eigentlich meint... egal das finde ich auch noch 'raus...

Natürlich kann man das Ganze auch umbauen auf 4 oder 8 oder 150 Mio Fenster.... (Wer hätte das gedacht...)

Ach ja, ich hatte keine Lust das übertriebene Exception-Handling zu löschen... Nein.. niemand muß das so nachmachen...
Ich wußte das geht irgendwie und ich wußte ich krieg' das hin... hahaha....

Hat jemand von euch Lust das mal unter W8 oder W10 zu testen... Verhält sich der Explorer dort genauso ???
Muß auch nicht unbedingt, ich bin nur neugierig...
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.604 Beiträge
 
Delphi 11 Alexandria
 
#29

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

  Alt 6. Jul 2016, 05:24
Durch die vollkommen transparenten Fensterränder sieht es unter Windows 10 so aus als sei zwischen den Fenstern Platz. In Wirklichkeit sind das nur die Rahmen aber die sieht man ja nicht.

Leider lässt sich das programmtechnisch auch kaum lösen. Aero Snap ist ja leider per API nicht erreichbar und wenn man die Fenster so platziert, dass kein Abstand dazwischen sichtbar ist, überlappen sie in Wirklichkeit.

Da andere Fenstermanager mittlerweile aber auch Aero Snap Features haben, scheint es auf undokumentiertem Weg evtl. doch zu gehen. Das hätte den Vorteil, dass die Fenster auch wieder ihre normale Größe einnehmen, wenn man sie aus dem doppelt maximierten Zustand herauszieht.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Erdbär
(Gast)

n/a Beiträge
 
#30

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

  Alt 6. Jul 2016, 09:34
Finde ich ganz praktisch:

Delphi-Quellcode:
...
...
...

// Sorgt für mehr Übersicht auf dem Desktop:
procedure MinAllWindows;
begin
  KeyBd_Event(VK_LWIN, MapvirtualKey(VK_LWIN, 0), 0, 0);
  KeyBd_Event(Ord('M'), MapvirtualKey(Ord('M'), 0), 0, 0);
  KeyBd_Event(Ord('M'), MapvirtualKey(Ord('M'), 0), KEYEVENTF_KEYUP, 0);
  KeyBd_Event(VK_LWIN, MapvirtualKey(VK_LWIN, 0), KEYEVENTF_KEYUP, 0);
end;
// ^ Minimiert alle Fenster

Procedure StartTwoWinEx;
 Begin
 MinAllWindows; // Eingefügt
  Try
   If DirectoryExists('I:\') And DirectoryExists('I:\(DOWNLOADS)')
   Then ...
...
...
Kompiliert mit Delph7 unter Win10, getestet unter XP/8.1/10. Klappt

Danke!
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 09:34 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz