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 28. Jun 2015, 07:16
Hat keiner eine Idee? Wäre schön, wenn man diesen blöden Rand weg bekommen würde.
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
 
#2

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

  Alt 28. Jun 2015, 07:59
Das ist nicht der einzige Schönheitsfehler:

Die beiden Explorer-Instanzen bleiben im RAM als Leichen zurück und können nur im Task-Manager beendet werden.
Ich suche eine Lösung, evtl. mit CreateProcess/TerminateProcess.
  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 28. Jun 2015, 11:14
Richtig, da fehlt noch was. Aus dem Grund hab ich mir ja auch die Handles im TPanel.Tag gemerkt.

Delphi-Quellcode:
procedure TFrmExplorer2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if Panel1.Tag > 0 then SendMessage(Panel1.Tag, WM_CLOSE, 0, 0);
  if Panel2.Tag > 0 then SendMessage(Panel2.Tag, WM_CLOSE, 0, 0);
end;
Mir unverständlich ist, dass die Explorer-Instanzen erst nach etwa 20 Sekunden aus dem Taskmanager verschwinden
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
 
#4

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

  Alt 30. Jun 2015, 09:46
Hat keiner eine Idee? Wäre schön, wenn man diesen blöden Rand weg bekommen würde.
Mit Metro UI Tweaker (im Anhang) kriegt man Ribbon weg.
- > Disable Explorer Ribbon
Angehängte Grafiken
Dateityp: jpg DER-1.jpg (81,4 KB, 19x aufgerufen)
Dateityp: jpg WE2.jpg (72,4 KB, 18x aufgerufen)
Angehängte Dateien
Dateityp: zip MUITW8.zip (283,8 KB, 12x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von markus5766h
markus5766h

Registriert seit: 5. Mär 2009
Ort: Hamburg
569 Beiträge
 
Delphi XE8 Professional
 
#5

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

  Alt 8. Jul 2015, 19:29
Moin aus Hamburg.

Code:
procedure TFrmExplorer2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if Panel1.Tag > 0 then SendMessage(Panel1.Tag, WM_CLOSE, 0, 0);
  if Panel2.Tag > 0 then SendMessage(Panel2.Tag, WM_CLOSE, 0, 0);
end;
... PostMessage scheint hier zuverlässiger zu sein.
Selbst nach mehrmaligen Starten werden alle Instanzen gelöscht,
bei SendMessage habe ich immer Leichen mit ca. 8Mb und 6 Threads im Taskmanager
Markus H.

Geändert von markus5766h ( 8. Jul 2015 um 21:01 Uhr)
  Mit Zitat antworten Zitat
hathor
(Gast)

n/a Beiträge
 
#6

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

  Alt 8. Jul 2015, 19:55
Am Ende eines Programms sollte man immer PostMessage bevorzugen.
Ich habe es ausserdem in die Destroy-Procedure geschrieben.
Aber es dauert trotzdem lange, bis sie aus dem Task-Manager verschwinden.

Delphi-Quellcode:
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;

Geändert von hathor ( 8. Jul 2015 um 19:59 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von markus5766h
markus5766h

Registriert seit: 5. Mär 2009
Ort: Hamburg
569 Beiträge
 
Delphi XE8 Professional
 
#7

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

  Alt 8. Jul 2015, 20:42
Zitat:
Aber es dauert trotzdem lange, bis sie aus dem Task-Manager verschwinden.
ja, stimmt, bei mir ca. 15 bis 20 Sekunden - aber zuverlässig.
Markus H.
  Mit Zitat antworten Zitat
hathor
(Gast)

n/a Beiträge
 
#8

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

  Alt 15. Jul 2015, 07: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.
Angehängte Grafiken
Dateityp: jpg IExplore2x.jpg (107,1 KB, 46x aufgerufen)
Dateityp: jpg WETTER-LTE-1.jpg (124,3 KB, 36x aufgerufen)

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

n/a Beiträge
 
#9

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

  Alt 5. Sep 2015, 19: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
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 17:00 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