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
Seite 2 von 2     12   
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 27. Jun 2015, 16:09
Vorschlag:

  SEI.nShow := SW_MINIMIZE; macht den Bildaufbau ruhiger.
DANKE!

Ein Problem gibt es noch: Die Explorerfenster haben beim Panel oben einen Rand etwa so hoch wie normalerweise die Titelleiste. Damit wollte ich den Rand eigentlich verhindern, aber irgendwas scheint noch zu fehlen. Hab schon rumprobiert, finde aber keine Lösung.

Delphi-Quellcode:
Style := GetWindowLong(aPanel.Tag, GWL_STYLE);
SetWindowLong(aPanel.Tag, GWL_STYLE, Style and NOT WS_BORDER );
Oder weigert sich der Explorer das anzunehmen?
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
FarAndBeyond
(Gast)

n/a Beiträge
 
#2

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

  Alt 5. Jul 2016, 23: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.948 Beiträge
 
Delphi 12 Athens
 
#3

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

  Alt 6. Jul 2016, 04: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
AppCentral
  Mit Zitat antworten Zitat
Erdbär
(Gast)

n/a Beiträge
 
#4

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

  Alt 6. Jul 2016, 08: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
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.948 Beiträge
 
Delphi 12 Athens
 
#5

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

  Alt 6. Jul 2016, 12:13
Funktioniert KeyBd_Event vielleicht auch mit Win + Left und Win + Right?
Dann müsste man nur statt MoveWindow erst das eine Fenster fokussieren, Win + Left schicken, dann das zweite Fokussieren und Win + Right schicken.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
FarAndBeyond
(Gast)

n/a Beiträge
 
#6

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

  Alt 6. Jul 2016, 20:43
Zitat:
Durch die vollkommen transparenten Fensterränder sieht es unter Windows 10 so aus als sei zwischen den Fenstern Platz.
Danke für die Info...
Na wenigstens funktioniert das in W10 noch. Wenn der Spalt nicht zu groß ist stört das ja vielleicht nicht so sehr.


Zitat:
procedure MinAllWindows;
Nette Idee... Kann ich vielleicht noch gebrauchen, mir ist nämlich folgendes aufgefallen: Wenn ich den Browser im Vordergrund geöffnet habe und dann den QuickLaunch-Button drücke bei zwei schon geöffneten WinEx-Fenstern, dann bringt er mir nur ein Explorer-Fenster nach vorne.
Also muß ich doch wieder zurück zu "MoveTwoWinExToFront" mit Hilfe von Minimize und Restore....
Eigenartigerweise ist das aber nicht immer der Fall, manchmal funzt es und beide Fenster kommen nach vorne.

Oder ich probier mal deine Prozedur... wenn alle Fenster vorher minimiert werden, dann würde man in dem Fall auch das zweite Fenster sehen.
Windows ist da offenbar etwas eigensinnig ...

Interessant unter XP und 8.1 geht das also auch... gut zu wissen...


Zitat:
Dann müsste man nur statt MoveWindow erst das eine Fenster fokussieren, Win + Left schicken, dann das zweite Fokussieren und Win + Right schicken.
Gute Alternative... aber dafür brauchst du auch ein Fensterhandle oder?
Ist wahrscheinlich gehopst wie gesprungen... wenn schon zwei geöffnet sind müssen die erstmal wieder nach vorne...
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#7

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

  Alt 7. Jul 2016, 02:23
Wozu die ganzen Try-Except-Blöcke, wenn sie doch leer sind?

Insbesondere hier:
Delphi-Quellcode:
Procedure Free_slLoad;
   Begin
    Try
     FreeAndNil(slLoad);
    Except
    End;
   End;
Und warum das Auslagern in eine eigene Prozedur? Das suggeriert, dass hier noch mehr passiert, tut es aber nicht. Davon abgesehen bitte mal dies zu FreeAndNil lesen: http://www.nickhodges.com/post/Using-FreeAndNil.aspx
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.948 Beiträge
 
Delphi 12 Athens
 
#8

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

  Alt 7. Jul 2016, 05:56
Gute Alternative... aber dafür brauchst du auch ein Fensterhandle oder?
Ist wahrscheinlich gehopst wie gesprungen... wenn schon zwei geöffnet sind müssen die erstmal wieder nach vorne...
Ich habe es heute Morgen einmal getestet...
Es funktioniert tatsächlich problemlos. Mit SetForegroundWindow lässt sich der Windows Explorer nach vorne holen und dann mit folgendem Code links snappen (und rechts dann analog):
Delphi-Quellcode:
  keybd_event(VK_LWIN, MapVirtualKey(VK_LWIN, 0), 0, 0);
  keybd_event(VK_LEFT, MapVirtualKey(VK_LEFT, 0), 0, 0);
  keybd_event(VK_LEFT, MapVirtualKey(VK_LEFT, 0), KEYEVENTF_KEYUP, 0);
  keybd_event(VK_LWIN, MapVirtualKey(VK_LWIN, 0), KEYEVENTF_KEYUP, 0);
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   

 

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 16:02 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