|
Antwort |
hathor
(Gast)
n/a Beiträge |
#21
AW: Zwei Windows Explorer starten und nebeneinander bildschirmfüllend positionieren15. 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. Geändert von hathor (15. Jul 2015 um 08:36 Uhr) |
Zitat |
FarAndBeyond
(Gast)
n/a Beiträge |
#22
AW: Zwei Windows Explorer starten und nebeneinander bildschirmfüllend positionieren5. 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:
WindowsTaste + E kann man problemlos nutzen und das neue Fenster kann man auch problemlos verschieben...
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. 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:
Zwei einfache wsNormal-Fenster wirklich immer nach vorne zu kriegen ohne "Topmost" ist tatsächlich ein kleines Wunder!
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... Alter Schwede ich kotz gleich in die Ecke... |
Zitat |
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 positionieren6. 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) |
Zitat |
FarAndBeyond
(Gast)
n/a Beiträge |
#24
AW: Zwei Windows Explorer starten und nebeneinander bildschirmfüllend positionieren6. 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... |
Zitat |
Registriert seit: 3. Jun 2010 1.611 Beiträge Delphi 10.3 Rio |
#25
AW: Zwei Windows Explorer starten und nebeneinander bildschirmfüllend positionieren6. Sep 2015, 12:03Hat 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...
|
Zitat |
FarAndBeyond
(Gast)
n/a Beiträge |
#26
AW: Zwei Windows Explorer starten und nebeneinander bildschirmfüllend positionieren6. 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... |
Zitat |
FarAndBeyond
(Gast)
n/a Beiträge |
#27
AW: Zwei Windows Explorer starten und nebeneinander bildschirmfüllend positionieren28. 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:
Fur alle die Windows 7 mögen und dazu noch den WindowsExplorer hier eine einfache Anleitung:
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. 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... Geändert von FarAndBeyond (28. Nov 2015 um 05:15 Uhr) Grund: Screenshot |
Zitat |
FarAndBeyond
(Gast)
n/a Beiträge |
#28
AW: Zwei Windows Explorer starten und nebeneinander bildschirmfüllend positionieren6. 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:
Das die Lösung so einfach ist hätte mir ruhig mal einer von euch "stecken" können... ... den Wald vor lauter Bäumen...
Repeat
slFoundWnd.Clear; FindAllWindows('','CabinetWClass'); Until slFoundWnd.Count >= 2; 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:
Getestet mit D7 und W7x64 Sp1...
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. 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... |
Zitat |
Online
Registriert seit: 10. Jun 2003 Ort: Berlin 9.650 Beiträge Delphi 11 Alexandria |
#29
AW: Zwei Windows Explorer starten und nebeneinander bildschirmfüllend positionieren6. 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
AppCentral |
Zitat |
Erdbär
(Gast)
n/a Beiträge |
#30
AW: Zwei Windows Explorer starten und nebeneinander bildschirmfüllend positionieren6. Jul 2016, 09:34
Finde ich ganz praktisch:
Delphi-Quellcode:
Kompiliert mit Delph7 unter Win10, getestet unter XP/8.1/10. Klappt
...
... ... // 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 ... ... ... Danke! |
Zitat |
Ansicht |
Linear-Darstellung |
Zur Hybrid-Darstellung wechseln |
Zur Baum-Darstellung wechseln |
ForumregelnEs 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
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
LinkBack URL |
About LinkBacks |