Verfasst: 26.10.2007 13:54
wirklich seltsam... 
hier mal der zugrunde liegende Source:
Die Meldung "Mindestens ein Explorer konnte nicht gestartet werden."
kommt aus der Prozedur StartExplorer(). Dort übergebe ich die beiden
initialen Pfade. Danach enumeriere ich die vorhandenen Fenster, starte die
Explorer und enumeriere noch einmal. Hierdurch kann ich dann die
Handles der beiden neu hinzugekommenen Explorer-Fenster ermitteln.
Nach einem Timeout von 5 Sekunden wird die Schleife verlassen.
Wozu der Aufwand, wenn's mit FindWindow_() auch geht? Nun, ich möchte,
dass nur die von mir gestarteten Explorer mit SetParent_() in meine
Applikation gebracht werden.
Wenn beispielsweise bereits ein "C:\Programme"-Explorer vor
dem Programmstart von WinDuos existierte, besteht die Gefahr, dass ich
mir das falsche Fenster grapsche.
Wäre nett, wenn Ihr das mal bei Euch testen könntet. Ein Ansatzpunkt
wäre es, den TimeOut auf vielleicht 10 Sekunden zu setzen (ich weiß ja
nicht, wie lange es bei Euch dauert, bis das Fenster erscheint...)
Danke & Grüße ... Kiffi
// Edit: Fehler im Code behoben (thx @NicTheQuick!)

hier mal der zugrunde liegende Source:
Die Meldung "Mindestens ein Explorer konnte nicht gestartet werden."
kommt aus der Prozedur StartExplorer(). Dort übergebe ich die beiden
initialen Pfade. Danach enumeriere ich die vorhandenen Fenster, starte die
Explorer und enumeriere noch einmal. Hierdurch kann ich dann die
Handles der beiden neu hinzugekommenen Explorer-Fenster ermitteln.
Nach einem Timeout von 5 Sekunden wird die Schleife verlassen.
Wozu der Aufwand, wenn's mit FindWindow_() auch geht? Nun, ich möchte,
dass nur die von mir gestarteten Explorer mit SetParent_() in meine
Applikation gebracht werden.
Wenn beispielsweise bereits ein "C:\Programme"-Explorer vor
dem Programmstart von WinDuos existierte, besteht die Gefahr, dass ich
mir das falsche Fenster grapsche.
Wäre nett, wenn Ihr das mal bei Euch testen könntet. Ein Ansatzpunkt
wäre es, den TimeOut auf vielleicht 10 Sekunden zu setzen (ich weiß ja
nicht, wie lange es bei Euch dauert, bis das Fenster erscheint...)
Danke & Grüße ... Kiffi
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() ; speichert die Handles beim Enumerieren
Global NewList Favoriten.s_Explorer()
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"
AddElement(Windows())
Windows()=Handle
EndIf
ProcedureReturn #True
EndProcedure
Procedure.l StartExplorer(LeftPath.s, RightPath.s)
If LCase(LeftPath) = LCase(RightPath)
MessageRequester(#AppName, "Linker und rechter Pfad dürfen nicht identisch sein.")
ProcedureReturn #False
EndIf
LeftPath =Trim(LeftPath)
RightPath=Trim(RightPath)
Debug LeftPath
Debug RightPath
; Anpassung der Pfade
; Erlaubt "C:\" (mit abschliessendem Backslash)
; Erlaubt "C:\Programme" (ohne Backslash)
; dito mit UNC-Pfaden
If Left(LeftPath, 2) = "\\"
If CountString(LeftPath, "\") => 3
If Right(LeftPath, 1) = "\"
LeftPath=Left(LeftPath, Len(LeftPath)-1)
EndIf
EndIf
Else
If CountString(LeftPath, "\") => 2
If Right(LeftPath, 1) = "\"
LeftPath=Left(LeftPath, Len(LeftPath)-1)
EndIf
EndIf
EndIf
If Left(RightPath, 2) = "\\"
If CountString(RightPath, "\") => 3
If Right(RightPath, 1) = "\"
RightPath=Left(RightPath, Len(RightPath)-1)
EndIf
EndIf
Else
If CountString(RightPath, "\") => 2
If Right(RightPath, 1) = "\"
RightPath=Left(RightPath, Len(RightPath)-1)
EndIf
EndIf
EndIf
Debug LeftPath
Debug RightPath
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 bereits 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()
If GetTitle(W_After()) = Explorer\LeftPath
Explorer\LefthWnd=W_After()
DeleteElement(W_After())
ElseIf GetTitle(W_After()) = Explorer\RightPath
Explorer\RighthWnd=W_After()
DeleteElement(W_After())
EndIf
Next
If Explorer\LefthWnd And Explorer\RighthWnd
Break
EndIf
EndIf
Delay(10)
If Date() => TimeOut : Break : EndIf ; Timeout abgelaufen -> Raus aus der Schleife
ForEver
If Explorer\LefthWnd And Explorer\RighthWnd
SetParent_(Explorer\LefthWnd, GadgetID(#frmMain_Container_1))
SetParent_(Explorer\RighthWnd, GadgetID(#frmMain_Container_2))
SetStyles(Explorer\LefthWnd)
SetStyles(Explorer\RighthWnd)
; Adressen der Explorer-Adressleiste ermitteln
AddressBarhWnd = 0 : EnumChildWindows_(Explorer\LefthWnd, @GetAddressBarhWnd(), 0) : Explorer\LeftAddressbarhWnd = AddressBarhWnd
AddressBarhWnd = 0 : EnumChildWindows_(Explorer\RighthWnd, @GetAddressBarhWnd(), 0) : Explorer\RightAddressbarhWnd = AddressBarhWnd
If Explorer\LeftAddressbarhWnd And Explorer\RightAddressbarhWnd
ShowWindow_(Explorer\LefthWnd, #SW_MAXIMIZE)
ShowWindow_(Explorer\RighthWnd, #SW_MAXIMIZE)
ProcedureReturn #True
Else
MessageRequester(#AppName, "Adressleiste ist nicht angeschaltet.")
EndIf
Else
MessageRequester(#AppName, "Mindestens ein Explorer konnte nicht gestartet werden.")
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 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.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 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 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 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
CloseWindow(#frmMain)
EndProcedure
Main()