Sorry to reply to my own question, but I figured out a workaround that seems to work on Windows 10.
Just 2 procedures + 1 call, before you open any requesters.
Windows 7+ remembers the first DefaultDir you call. If you call that DefaultDir again, Windows ignores it and opens in the last selected path.
Apparently this was an attempt to solve lazy programs which don't track the user's selected path, when the user expects it to. But it broke other programs' intended behavior.
So a workaround is... first open DefaultDir to a temporary folder you'll likely never call again. Then future DefaultDir will work as expected.
Preferably, open DefaultDir as hidden as possible, in this workaround it closes it as soon as possible.
Code: Select all
;-
;- -----------------------------
;- WORKAROUND START
;-
CompilerIf (#PB_Compiler_OS = #PB_OS_Windows)
Procedure _PrepareFileRequester(*OFN.OPENFILENAME)
OpenFileRequester(PeekS(*OFN\lpstrTitle), PeekS(*OFN\lpstrInitialDir), "", 0)
EndProcedure
Procedure PrepareFileRequester()
Static Prepared.i = #False
If (Not Prepared)
Prepared = #True
If (OSVersion() >= #PB_OS_Windows_7)
Protected Title.s = " "
While (FindWindow_(#Null, @Title))
Title + " "
Wend
Protected TempDir.s = GetTemporaryDirectory() + "." + Str(Date())
CreateDirectory(TempDir)
Protected OFN.OPENFILENAME
OFN\lpstrTitle = @Title
OFN\lpstrInitialDir = @TempDir
Protected *Thread = CreateThread(@_PrepareFileRequester(), @OFN)
Protected *Window
Repeat : Delay(0) : *Window = FindWindow_(#Null, @Title) : Until (*Window)
SendMessage_(*Window, #WM_CLOSE, 0, 0)
Repeat : Delay(0) : Until (Not IsThread(*Thread))
DeleteDirectory(TempDir, "")
EndIf
EndIf
EndProcedure
CompilerElse
Macro PrepareFileRequester()
;
EndMacro
CompilerEndIf
;-
;- WORKAROUND END
;- -----------------------------
;-
;-
CompilerIf (#PB_Compiler_Debugger)
MessageRequester("Instructions",
"1. Compile this to an EXE (Desktop/test.exe or similar)" + #LF$ +
"2. Run it" + #LF$ +
"3. When the first requester opens, choose a file in a different folder" + #LF$ +
"4. The second requester opens in that folder (bug)" + #LF$ +
"5. Run the program again, and it opens in that changed folder (bug)" + #LF$ + #LF$ +
"Some sort of Windows caching issue ??" )
CompilerElse
ProgramDir.s = GetPathPart(ProgramFilename())
MessageRequester("Program Dir", ProgramDir)
PrepareFileRequester() ;- ADD THIS ONE LINE
OpenFileRequester("Title", ProgramDir, "All Files|*.*", 0)
SaveFileRequester("Title", ProgramDir, "All Files|*.*", 0)
CompilerEndIf
;-
EDIT - See MUCH nicer solution here:
viewtopic.php?p=549667#p549667