Das Problem ist, dass leider nicht weiß, woran das liegt. Es könnte daran
Parent-Window unter seinem Hintern wegschieße.
in seinen ursprünglichen Parent und schicke ihm dann ein WM_CLOSE.
Code: Alles auswählen
; WinDuos
EnableExplicit
Enumeration ; Windows
#frmMain
EndEnumeration
Enumeration ; Gadgets
#frmMain_TB
#frmMain_Container_1
#frmMain_Container_2
#frmMain_Splitter
#frmMain_SB
#frmMain_Menu
#frmMain_Menu_Quit
#frmMain_Menu_AddFolders
#frmMain_Menu_EditFolders
#frmMain_Menu_Help
#frmMain_Menu_Info
#frmMain_FavoritenFolder_Item ; Muss als letztes stehen
EndEnumeration
Structure s_Explorer
Description.s
LeftPath.s
RightPath.s
LefthWnd.l
RighthWnd.l
LeftAddressbarhWnd.l
RightAddressbarhWnd.l
EndStructure
#AppName = "WinDuos"
Global Explorer.s_Explorer
Global AddressBarhWnd.l
#BufferSize = 2048
Global NewList Windows()
Global NewList Favoriten.s_Explorer()
; SetParentEx(), ResetParent() und GetOldParentWnd():
; http://www.aboutvb.de/khw/artikel/khwsetparentex.htm
Procedure.l SetParentEx(ChildWnd.l, NewParentWnd.l)
Protected nOldParentWnd.l
Protected nUserData.l
nOldParentWnd = SetParent_(ChildWnd, NewParentWnd)
nUserData = GetWindowLong_(ChildWnd, #GWL_USERDATA)
If nUserData = 0
SetWindowLong_(ChildWnd, #GWL_USERDATA, nOldParentWnd)
Else
ProcedureReturn nOldParentWnd
EndIf
EndProcedure
Procedure.l ResetParent(ChildWnd.l, OldParentWnd.l = 0)
Protected nOldParentWnd.l
If OldParentWnd > 0
nOldParentWnd = OldParentWnd
Else
nOldParentWnd = GetWindowLong_(ChildWnd, #GWL_USERDATA)
SetWindowLong_(ChildWnd, #GWL_USERDATA, 0)
EndIf
If nOldParentWnd
SetParent_(ChildWnd, nOldParentWnd)
Else
ProcedureReturn #True
EndIf
EndProcedure
Procedure.l GetOldParentWnd(ChildWnd.l)
ProcedureReturn GetWindowLong_(ChildWnd, #GWL_USERDATA)
EndProcedure
Procedure GetAddressBarhWnd(hwnd.l, void.l)
Protected a.s = Space(200)
GetClassName_(hwnd, @a, 199)
If a="Edit"
AddressBarhWnd = hwnd
ProcedureReturn 0
EndIf
ProcedureReturn 1
EndProcedure
Procedure SetStyles(ExplorerHandle.l)
SetWindowLong_(ExplorerHandle, #GWL_EXSTYLE, GetWindowLong_(ExplorerHandle, #GWL_EXSTYLE) &~ #WS_EX_CLIENTEDGE )
SetWindowLong_(ExplorerHandle, #GWL_EXSTYLE, GetWindowLong_(ExplorerHandle, #GWL_EXSTYLE) &~ #WS_EX_WINDOWEDGE )
SetWindowLong_(ExplorerHandle, #GWL_STYLE, GetWindowLong_(ExplorerHandle, #GWL_STYLE) &~ #WS_DLGFRAME)
SetWindowLong_(ExplorerHandle, #GWL_STYLE, GetWindowLong_(ExplorerHandle, #GWL_STYLE) &~ #WS_THICKFRAME)
SetWindowLong_(ExplorerHandle, #GWL_STYLE, GetWindowLong_(ExplorerHandle, #GWL_STYLE) &~ #WS_OVERLAPPED )
SetWindowLong_(ExplorerHandle, #GWL_STYLE, GetWindowLong_(ExplorerHandle, #GWL_STYLE) &~ #WS_BORDER)
EndProcedure
Procedure.s GetClassName(Handle.l)
Protected ClassName.s = Space(#BufferSize)
GetClassName_(Handle, @ClassName, #BufferSize)
ProcedureReturn ClassName
EndProcedure
Procedure.s GetTitle(Handle.l)
Protected Title.s = Space(#BufferSize)
GetWindowText_(Handle, @Title, #BufferSize)
ProcedureReturn Title
EndProcedure
Procedure EnumProc(Handle.l, lParam.l)
Protected ClassName.s = GetClassName(Handle)
If ClassName = "CabinetWClass" Or ClassName = "ExplorerWClass"
If Not IsWindowVisible_(Handle) ; Nur unsichtbare Fenster suchen
AddElement(Windows())
Windows()=Handle
EndIf
EndIf
ProcedureReturn #True
EndProcedure
Procedure CloseExplorer()
If Explorer\LefthWnd
; Explorer verstecken
ShowWindow_(Explorer\LefthWnd, #SW_HIDE)
; Ursprüngliche Parents wiederherstellen
ResetParent(Explorer\LefthWnd)
; Explorer schliessen
PostMessage_(Explorer\LefthWnd, #WM_CLOSE, 0, 0)
; Solange warten, bis die Explorer nicht mehr da sind
While IsWindow_(Explorer\LefthWnd) : Delay(10) : Wend
EndIf
If Explorer\RighthWnd
; Explorer verstecken
ShowWindow_(Explorer\RighthWnd, #SW_HIDE)
; Ursprüngliche Parents wiederherstellen
ResetParent(Explorer\RighthWnd)
; Explorer schliessen
PostMessage_(Explorer\RighthWnd, #WM_CLOSE, 0, 0)
; Solange warten, bis die Explorer nicht mehr da sind
While IsWindow_(Explorer\RighthWnd) : Delay(10) : Wend
EndIf
EndProcedure
Procedure.s CorrectPath(sPath.s)
; Anpassung der Pfade
; Erlaubt "C:" (mit abschliessendem Backslash)
; Erlaubt "C:\Programme" (ohne Backslash)
; dito mit UNC-Pfaden
If Left(sPath, 2) = "\"
If CountString(sPath, "") => 3
If Right(sPath, 1) = "" : sPath = Left(sPath, Len(sPath)-1) : EndIf
EndIf
Else
If CountString(sPath, "") => 2
If Right(sPath, 1) = "" : sPath = Left(sPath, Len(sPath)-1) : EndIf
EndIf
EndIf
ProcedureReturn sPath
EndProcedure
Procedure.l StartExplorer(LeftPath.s, RightPath.s)
; Debug LeftPath
; Debug RightPath
LeftPath = CorrectPath(Trim(LeftPath))
RightPath = CorrectPath(Trim(RightPath))
; Debug LeftPath
; Debug RightPath
If LCase(LeftPath) = LCase(RightPath)
MessageRequester(#AppName, "Linker und rechter Pfad dürfen nicht identisch sein.")
ProcedureReturn #False
EndIf
Protected ReturnValue.l
Protected TimeOut.l
NewList W_Before()
NewList W_After()
; Enumeration der bereits vorhandenen Fenster
ClearList(Windows())
EnumWindows_(@EnumProc(), 0)
ForEach Windows()
AddElement(W_Before())
W_Before()=Windows()
Next
Explorer\LeftPath = LeftPath
Explorer\RightPath = RightPath
ReturnValue = RunProgram("explorer.exe", Explorer\LeftPath, "", #PB_Program_Hide)
ReturnValue = RunProgram("explorer.exe", Explorer\RightPath, "", #PB_Program_Hide)
TimeOut = AddDate(Date(), #PB_Date_Second, 5) ; 5 Sekunden als Timeout (müsste eigentlich reichen)
Repeat
; Enumeration der Fenster nach RunProgram()
ClearList(Windows())
EnumWindows_(@EnumProc(), 0)
ClearList(W_After())
ForEach Windows()
AddElement(W_After())
W_After()=Windows()
Next
If CountList(W_Before()) + 2 = CountList(W_After()) ; 2 neue Fenster hinzugekommen?
; Nun alte Fensterliste mit neuer vergleichen
; identische Fenster werden aus W_After() entfernt
ForEach W_Before()
ForEach W_After()
If W_Before()=W_After()
DeleteElement(W_After())
EndIf
Next
Next
; Nun sind im Idealfall in W_After nur die von WinDuos
; gestarteten Explorer vorhanden
ForEach W_After()
; Hier wird nur FindString() verwendet, da in der Titelleiste
; nicht zwangsläufig der komplette Pfad steht
If FindString(Explorer\LeftPath, GetTitle(W_After()), 1)
Explorer\LefthWnd=W_After()
DeleteElement(W_After())
ElseIf FindString(Explorer\RightPath, GetTitle(W_After()), 1)
Explorer\RighthWnd=W_After()
DeleteElement(W_After())
EndIf
Next
If Explorer\LefthWnd And Explorer\RighthWnd : Break : EndIf
EndIf
Delay(100)
If Date() => TimeOut : Break : EndIf ; Timeout abgelaufen -> Raus aus der Schleife
ForEver
If Explorer\LefthWnd And Explorer\RighthWnd
AddressBarhWnd = 0 : EnumChildWindows_(Explorer\LefthWnd, @GetAddressBarhWnd(), 0) : Explorer\LeftAddressbarhWnd = AddressBarhWnd
AddressBarhWnd = 0 : EnumChildWindows_(Explorer\RighthWnd, @GetAddressBarhWnd(), 0) : Explorer\RightAddressbarhWnd = AddressBarhWnd
; Adressen der Explorer-Adressleiste ermitteln
If Explorer\LeftAddressbarhWnd And Explorer\RightAddressbarhWnd
SetParentEx(Explorer\LefthWnd, GadgetID(#frmMain_Container_1))
SetParentEx(Explorer\RighthWnd, GadgetID(#frmMain_Container_2))
SetStyles(Explorer\LefthWnd)
SetStyles(Explorer\RighthWnd)
ShowWindow_(Explorer\LefthWnd, #SW_MAXIMIZE)
ShowWindow_(Explorer\RighthWnd, #SW_MAXIMIZE)
ProcedureReturn #True
Else
MessageRequester(#AppName, "Adressleiste ist nicht angeschaltet.")
CloseExplorer()
EndIf
Else
MessageRequester(#AppName, "Mindestens ein Explorer konnte nicht gestartet werden.")
CloseExplorer()
EndIf
EndProcedure
Procedure ChangePathes()
SendMessage_(Explorer\LeftAddressbarhWnd, #WM_SETTEXT, 0, @Explorer\LeftPath)
SendMessage_(Explorer\LeftAddressbarhWnd, #WM_LBUTTONDOWN ,#MK_LBUTTON, 0)
SendMessage_(Explorer\LeftAddressbarhWnd, #WM_LBUTTONUP ,#MK_LBUTTON, 0)
SendMessage_(Explorer\LeftAddressbarhWnd, #WM_KEYDOWN, #VK_RETURN, 0)
SendMessage_(Explorer\LeftAddressbarhWnd, #WM_KEYUP, #VK_RETURN, 0)
SendMessage_(Explorer\RightAddressbarhWnd, #WM_SETTEXT, 0, @Explorer\RightPath)
SendMessage_(Explorer\RightAddressbarhWnd, #WM_LBUTTONDOWN ,#MK_LBUTTON, 0)
SendMessage_(Explorer\RightAddressbarhWnd, #WM_LBUTTONUP ,#MK_LBUTTON, 0)
SendMessage_(Explorer\RightAddressbarhWnd, #WM_KEYDOWN, #VK_RETURN, 0)
SendMessage_(Explorer\RightAddressbarhWnd, #WM_KEYUP, #VK_RETURN, 0)
EndProcedure
Procedure RebuildMenue()
If CreateMenu(#frmMain_Menu, WindowID(#frmMain))
MenuTitle("Datei")
MenuItem(#frmMain_Menu_Quit, "Beenden")
MenuTitle("Ordner")
ForEach Favoriten()
MenuItem(#frmMain_FavoritenFolder_Item + ListIndex(Favoriten()), Favoriten()\Description)
Next
MenuBar()
MenuItem(#frmMain_Menu_AddFolders, "Aktuelle Ordneransicht hinzufügen")
MenuItem(#frmMain_Menu_EditFolders, "Favoriten bearbeiten")
MenuTitle("Hilfe")
MenuItem(#frmMain_Menu_Help, "Hilfe...")
MenuItem(#frmMain_Menu_Info, "Über...")
EndIf
EndProcedure
Procedure LoadSettings()
Protected Counter.l
Protected Description.s
Protected LeftPath.s
Protected RightPath.s
OpenPreferences("winduos.ini")
ClearList(Favoriten())
Repeat
Counter + 1
Description = ReadPreferenceString("description" + Str(Counter), "")
LeftPath = ReadPreferenceString("leftpath" + Str(Counter), "")
RightPath = ReadPreferenceString("rightpath" + Str(Counter), "")
If Description And LeftPath And RightPath
AddElement(Favoriten())
Favoriten()\Description = Description
Favoriten()\LeftPath = LeftPath
Favoriten()\RightPath = RightPath
EndIf
Until Counter = 100
ClosePreferences()
EndProcedure
Procedure SaveSettings()
Protected Counter.l
If CreatePreferences("winduos.ini")
ForEach Favoriten()
Counter + 1
WritePreferenceString("description" + Str(Counter), Favoriten()\Description)
WritePreferenceString("leftpath" + Str(Counter), Favoriten()\LeftPath)
WritePreferenceString("rightpath" + Str(Counter), Favoriten()\RightPath)
Next
ClosePreferences()
EndIf
EndProcedure
Procedure AddFolders()
Protected Description.s
Protected TextLen.l
Protected LeftPath.s
Protected RightPath.s
Description = InputRequester("Favorit hinzufügen", "Bitte geben Sie eine Bezeichnung ein.", "")
If Description
TextLen = SendMessage_(Explorer\LeftAddressbarhWnd, #WM_GETTEXTLENGTH, 0, 0)
If TextLen
TextLen + 1
LeftPath = Space(TextLen)
SendMessage_(Explorer\LeftAddressbarhWnd, #WM_GETTEXT, TextLen, @LeftPath)
EndIf
TextLen = SendMessage_(Explorer\RightAddressbarhWnd, #WM_GETTEXTLENGTH, 0, 0)
If TextLen
TextLen + 1
RightPath = Space(TextLen)
SendMessage_(Explorer\RightAddressbarhWnd, #WM_GETTEXT, TextLen, @RightPath)
EndIf
; Debug LeftPath
; Debug RightPath
AddElement(Favoriten())
Favoriten()\Description = Description
Favoriten()\LeftPath = LeftPath
Favoriten()\RightPath = RightPath
RebuildMenue()
SaveSettings()
EndIf
EndProcedure
Procedure EditFolders()
Protected Text.s
Text + "Momentan können die Favoriten nur in der INI-Datei geändert werden." + #CRLF$
Text + #CRLF$
Text + "Soll die INI-Datei nun geöffnet werden?" + #CRLF$
If MessageRequester(#AppName, Text, #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
Text = "Bitte denken Sie daran, dass die geänderten Favoriten erst" + #CRLF$
Text + "nach einem Neustart von " + #AppName + " zur Verfügung stehen" + #CRLF$
Text + "und in dem Zeitraum zwischen den Änderungen in der INI und dem" + #CRLF$
Text + "Neustart kein Favorit über die Menüleiste hinzugefügt werden sollte." + #CRLF$
MessageRequester(#AppName, Text)
RunProgram("winduos.ini")
EndIf
EndProcedure
Procedure.l frmMain_Open()
Protected WindowFlags.l
WindowFlags | #PB_Window_SystemMenu
WindowFlags | #PB_Window_MinimizeGadget
WindowFlags | #PB_Window_MaximizeGadget
WindowFlags | #PB_Window_SizeGadget
WindowFlags | #PB_Window_Invisible
WindowFlags | #PB_Window_ScreenCentered
If OpenWindow(#frmMain, #PB_Ignore, #PB_Ignore, 800, 600, #AppName, WindowFlags)
If CreateGadgetList(WindowID(#frmMain))
If CreateToolBar(#frmMain_TB, WindowID(#frmMain))
If CreateStatusBar(#frmMain_SB, WindowID(#frmMain))
ContainerGadget(#frmMain_Container_1, 0, 0, 0, 0) : CloseGadgetList()
ContainerGadget(#frmMain_Container_2, 0, 0, 0, 0) : CloseGadgetList()
SetWindowLong_(GadgetID(#frmMain_Container_1), #GWL_STYLE, GetWindowLong_(GadgetID(#frmMain_Container_1), #GWL_STYLE) | #WS_CLIPCHILDREN)
SetWindowLong_(GadgetID(#frmMain_Container_2), #GWL_STYLE, GetWindowLong_(GadgetID(#frmMain_Container_2), #GWL_STYLE) | #WS_CLIPCHILDREN)
SplitterGadget(#frmMain_Splitter, 0, ToolBarHeight(#frmMain_TB), WindowWidth(#frmMain), WindowHeight(#frmMain) - ToolBarHeight(#frmMain_TB) - StatusBarHeight(#frmMain_SB), #frmMain_Container_1, #frmMain_Container_2, #PB_Splitter_Vertical)
SetWindowLong_(GadgetID(#frmMain_Splitter), #GWL_STYLE, GetWindowLong_(GadgetID(#frmMain_Splitter), #GWL_STYLE) | #WS_CLIPCHILDREN)
SetWindowLong_(WindowID(#frmMain), #GWL_STYLE, GetWindowLong_(WindowID(#frmMain), #GWL_STYLE) | #WS_CLIPCHILDREN)
SmartWindowRefresh(#frmMain, #True)
ProcedureReturn #True
EndIf
EndIf
EndIf
EndIf
EndProcedure
Procedure ResizeGadgets()
If Explorer\LefthWnd
MoveWindow_(Explorer\LefthWnd, 0, 0, GadgetWidth(#frmMain_Container_1), GadgetHeight(#frmMain_Container_1), #True)
EndIf
If Explorer\RighthWnd
MoveWindow_(Explorer\RighthWnd, 0, 0, GadgetWidth(#frmMain_Container_2), GadgetHeight(#frmMain_Container_2), #True)
EndIf
EndProcedure
Procedure.s GetSpecialFolder(Folder.l)
Protected *itemid.ITEMIDLIST = #Null
If SHGetSpecialFolderLocation_ (0, Folder, @*itemid) = #NOERROR
Protected location.s = Space (#MAX_PATH)
If SHGetPathFromIDList_ (*itemid, @location)
If Right(location, 1) <> "" : location + "" : EndIf
ProcedureReturn location
EndIf
EndIf
EndProcedure
Procedure Main()
Protected WWE.l
Protected Quit.l
LoadSettings()
If Not frmMain_Open() : End : EndIf
RebuildMenue()
If Not StartExplorer(GetSpecialFolder(#CSIDL_PROFILE), GetSpecialFolder(#CSIDL_PROGRAM_FILES)) : End : EndIf
While WindowEvent() : Wend
HideWindow(#frmMain, #False)
Repeat
WWE=WaitWindowEvent()
Select WWE
Case #PB_Event_SizeWindow
ResizeGadget(#frmMain_Splitter, #PB_Ignore, ToolBarHeight(#frmMain_TB), WindowWidth(#frmMain), WindowHeight(#frmMain) - ToolBarHeight(#frmMain_TB) - StatusBarHeight(#frmMain_SB) - MenuHeight())
ResizeGadgets()
Case #PB_Event_Gadget
Select EventGadget()
Case #frmMain_Splitter
ResizeGadgets()
EndSelect
Case #PB_Event_Menu
Select EventMenu()
Case #frmMain_Menu_Quit : Quit = #True
Case #frmMain_Menu_AddFolders : AddFolders()
Case #frmMain_Menu_EditFolders : EditFolders()
Case #frmMain_Menu_Help : MessageRequester(#AppName, "Sorry, Hilfe gibt es derzeit noch nicht.")
Case #frmMain_Menu_Info : MessageRequester(#AppName, "Copyright (c) 2007" + #CRLF$ + "Peter Tübben" + #CRLF$ + "http://www.tuebben.de/tools")
Default
ForEach Favoriten()
If EventMenu() = #frmMain_FavoritenFolder_Item + ListIndex(Favoriten())
Explorer\LeftPath = Favoriten()\LeftPath
Explorer\RightPath = Favoriten()\RightPath
ChangePathes()
Break
EndIf
Next
EndSelect
Case #PB_Event_CloseWindow : Quit = #True
EndSelect
Until Quit = #True
EndProcedure
Main()
HideWindow(#frmMain, #True)
CloseExplorer()