Path Requester a simple way to control X Y?
-
- Always Here
- Posts: 6426
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Path Requester a simple way to control X Y?
Is there a simple way to set the Path Requester's Window X and Y? It's quite a tall Window with long paths, so on a wide HD screen the bottom of the Window is off-screen. It's Y position is about 1/3 from the top of my screens. I know I could DIY the whole thing but if there is a lazy way.....
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
Re: Path Requester a simple way to control X Y?
One way -> viewtopic.php?p=590402#p590402
You'll need to tweak it to support X and Y (and maybe W and H) parameters.
You'll need to tweak it to support X and Y (and maybe W and H) parameters.
Re: Path Requester a simple way to control X Y?
This code works with PathRequesters and MessageRequesters. Looking for the requester window by classname avoids problems with different system languages.
Happy coding and stay healthy.
Code: Select all
; ---------------------------------------------------------------------------------------------------------------------
Structure TPosSize
X.i
Y.i
W.i
H.i
EndStructure
; ---------------------------------------------------------------------------------------------------------------------
Procedure PosSizeOfRequesterThread(*PosSize.TPosSize)
Protected hwnd, flags = 0
If *PosSize\X = #PB_Ignore Or *PosSize\Y = #PB_Ignore
flags = #SWP_NOMOVE ; move the window with valid values for X, Y
EndIf
If *PosSize\W = #PB_Ignore Or *PosSize\H = #PB_Ignore
flags = #SWP_NOSIZE ; size the window with valid values for W, H
EndIf
Repeat
hwnd = FindWindow_("#32770", 0) ; look for classname / should work with different languages
If hwnd
SetWindowPos_(hwnd, #HWND_TOPMOST, *PosSize\X, *PosSize\Y, *PosSize\W, *PosSize\H, flags)
EndIf
Until hwnd
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
; Path$ = PathRequester(Title$, InitialPath$)
Procedure.s PathRequesterEx(Title$, InitialPath$, X=#PB_Ignore, Y=#PB_Ignore, W=#PB_Ignore, H=#PB_Ignore)
Protected PosSize.TPosSize
PosSize\X = X : PosSize\Y = Y : PosSize\W = W : PosSize\H = H
CreateThread(@PosSizeOfRequesterThread(), @PosSize)
ProcedureReturn PathRequester(Title$, InitialPath$)
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
; MessageRequester(Title$, Text$, Flags)
Procedure.i MessageRequesterEx(Title$, Text$, Flags, X=#PB_Ignore, Y=#PB_Ignore)
Protected PosSize.TPosSize
PosSize\X = X : PosSize\Y = Y : PosSize\W = #PB_Ignore : PosSize\H = #PB_Ignore
CreateThread(@PosSizeOfRequesterThread(), @PosSize)
ProcedureReturn MessageRequester(Title$, Text$, Flags)
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
CompilerIf #PB_Compiler_IsMainFile
Debug "Test the Stuff ...."
Debug PathRequesterEx("Select Directory:", "", 80, 40);, 400, 800)
Debug MessageRequesterEx("Test Requester", ":1: This is a simple test only. ", #MB_ICONINFORMATION, 80, 40)
Debug MessageRequesterEx("Test Requester", ":2: This is a simple test only. ", 0, 800, 400)
CompilerEndIf
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
Re: Path Requester a simple way to control X Y?
Here is one of the ways not to use any thread.
Using global variables instead of using the file map object will make it simpler.
Using global variables instead of using the file map object will make it simpler.

Code: Select all
#EVENT_SYSTEM_FOREGROUND = $0003
#WINEVENT_INCONTEXT = 4
Procedure WinEventProc(hWinEventHook, event.l, hwnd, idObject.l, idChild.l, idEventThread.l, dwmsEventTime.l)
Protected Buffer.s{64}, *NewPosition.RECT, hMap, rt.RECT, hShell, hTree, hItem, x, y, w, h
If hwnd
If event = #EVENT_SYSTEM_FOREGROUND
If GetClassName_(hwnd, @Buffer, 63)
If Buffer = "#32770"
UnhookWinEvent_(hWinEventHook)
;Get the data of the global memory.
hMap = OpenFileMapping_(#FILE_MAP_ALL_ACCESS, 0, "AppPosData")
If hMap
*NewPosition = MapViewOfFile_(hMap, #FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(RECT))
If *NewPosition
If GetWindowRect_(hwnd, rt)
With rt
If *NewPosition\left = #PB_Ignore : x = \left : Else : x = *NewPosition\left : EndIf
If *NewPosition\top = #PB_Ignore : y = \top : Else : y = *NewPosition\top : EndIf
If *NewPosition\right = #PB_Ignore : w = \right - \left : Else : w = *NewPosition\right : EndIf
If *NewPosition\bottom = #PB_Ignore : h = \bottom - \top : Else : h = *NewPosition\bottom : EndIf
EndWith
SetWindowPos_(hwnd, 0, x, y, w, h, #SWP_NOZORDER | #SWP_NOOWNERZORDER | #SWP_FRAMECHANGED)
;Fix the problem that the selected item is sometimes not visible after resizing.
hShell = GetDlgItem_(hwnd, 0)
If hShell
hTree = GetDlgItem_(hShell, 100)
If hTree
If GetClassName_(hTree, @Buffer, 63)
If FindString(Buffer, "treeview", 1, #PB_String_NoCase)
hItem = SendMessage_(hTree, #TVM_GETNEXTITEM, #TVGN_CARET, 0)
If hItem
SendMessage_(hTree, #TVM_ENSUREVISIBLE, 0, hItem)
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
UnmapViewOfFile_(*NewPosition)
EndIf
CloseHandle_(hMap)
EndIf
EndIf
EndIf
EndIf
EndIf
EndProcedure
Procedure.s New_PathRequester(Title$, InitialPath$, x = #PB_Ignore, y = #PB_Ignore, w = #PB_Ignore, h = #PB_Ignore)
Protected sPath.s, hMap, *NewPosition.RECT
Protected hHook = SetWinEventHook_(#EVENT_SYSTEM_FOREGROUND, #EVENT_SYSTEM_FOREGROUND, GetModuleHandle_(0), @WinEventProc(), GetCurrentProcessId_(), GetCurrentThreadId_(), #WINEVENT_INCONTEXT)
hMap = CreateFileMapping_(#INVALID_HANDLE_VALUE, 0, #PAGE_READWRITE, 0, SizeOf(RECT), "AppPosData")
If hMap
*NewPosition = MapViewOfFile_(hMap, #FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(RECT))
If *NewPosition
*NewPosition\left = x
*NewPosition\top = y
*NewPosition\right = w
*NewPosition\bottom = h
EndIf
EndIf
sPath = PathRequester(Title$, InitialPath$)
If hMap
If *NewPosition
UnmapViewOfFile_(*NewPosition)
EndIf
CloseHandle_(hMap)
EndIf
If hHook
UnhookWinEvent_(hHook)
EndIf
ProcedureReturn sPath
EndProcedure
Debug New_PathRequester("test", "c:\", #PB_Ignore, #PB_Ignore, 300, 300)
Debug New_PathRequester("test", "c:\", 300, #PB_Ignore, 500, 500)
Debug New_PathRequester("test", "c:\", 100, 100)
Re: Path Requester a simple way to control X Y?
With few lines you can do everything with any Requester
Code: Select all
Global Hook,px,py,pw,ph
Procedure HookCB ( uMsg , wParam , lParam)
Select uMsg
Case #HCBT_ACTIVATE
SetDlgItemText_ (wParam, 1, "Option #1")
SetDlgItemText_ (wParam, 2, "Option #2")
SetDlgItemText_ (wParam, 14150, "Option #3")
MoveWindow_(wParam,px,py,pw,ph,1)
UnhookWindowsHookEx_(Hook)
EndSelect
ProcedureReturn #False
EndProcedure
Hook = SetWindowsHookEx_ ( #WH_CBT, @ HookCB () , 0, GetCurrentThreadId_ ())
InitialPath$ = "C:\"
px = 100 :py = 100
pw = 400 :ph = 450
Path.s = PathRequester("Please choose your path", InitialPath$)
Debug Path
Egypt my love
-
- Always Here
- Posts: 6426
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: Path Requester a simple way to control X Y?
Thanks BarryG, Axolotl, breeze4me and Rashad.
I'm sure I'm not the only one that will find these solution very useful. I'm using Rashad's code as it is very concise.
I'm sure I'm not the only one that will find these solution very useful. I'm using Rashad's code as it is very concise.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
Re: Path Requester a simple way to control X Y?
Sure you're not the only one.IdeasVacuum wrote: Thu Oct 20, 2022 3:08 am Thanks BarryG, Axolotl, breeze4me and Rashad.
I'm sure I'm not the only one that will find these solution very useful. I'm using Rashad's code as it is very concise.
I have it for Open(Save)FileRequester but not for the path requester. So thanks
Code: Select all
If OpenWindow(1,40,40,0,0,"",#PB_Window_BorderLess)
OpenFileRequester("Choose a file","","All files (*.*)|*.*",0)
CloseWindow(1)
EndIf
#
Yes but unfortunately it is not enough here on my windows 10 x64.Axolotl wrote: Wed Oct 19, 2022 2:29 pm Looking for the requester window by classname avoids problems with different system languages.
With FindWindow_("#32770", 0), it finds another window, hidden and with the same class
Code: Select all
Procedure EnumWindows(hwnd, lParam)
Protected isOwned, winExStyle, title.s{1024}, class.s{64}
isOwned = GetWindow_(hwnd, #GW_OWNER)
If isOwned = #Null
winExStyle = GetWindowLong_(hwnd, #GWL_EXSTYLE)
If (Not (winExStyle & #WS_EX_TOOLWINDOW)) Or (winExStyle & #WS_EX_APPWINDOW)
If GetClassName_(hwnd, @class, 63)
If class = "#32770"
;If IsWindowVisible_(hWnd) = lParam
GetWindowText_(hwnd,@title,1024)
Debug "WindowTitle: " + title + " - Class: " + class + " - Visible: " + IsWindowVisible_(hWnd)
;EndIf
EndIf
EndIf
EndIf
EndIf
ProcedureReturn #True
EndProcedure
EnumWindows_(@EnumWindows(), #True)
WindowTitle: The Event Manager Dashboard - Class: #32770 - Visible: 0
WindowTitle: Rechercher un dossier - Class: #32770 - Visible: 1
How to do it in this case with the 2 callbacks for EnumWindows and the thread ?
Or, else, how to find the Dll and the string identifier for "Browse for Folder", "Rechercher un dossier"
Code: Select all
Procedure.s LoadDllString(sDll.s, id)
Protected hInstance, sReturn.s{261}, sExpand.s{261}
ExpandEnvironmentStrings_(@sDll, @sExpand, 255)
hInstance = LoadLibraryEx_(@sExpand, 0, #LOAD_LIBRARY_AS_DATAFILE)
If hInstance
LoadString_(hInstance, id, @sReturn, 256)
FreeLibrary_(hInstance)
ProcedureReturn sReturn
EndIf
ProcedureReturn ""
EndProcedure
Re: Path Requester a simple way to control X Y?
Thanks @ChrisR for pointing that out ...
I mainly use StringGadgets with this extension...
I found another solution.
Select Folder Dialog ... as a PathRequester Replacement on Windows
Sorry for sharing untested code.
I mainly use StringGadgets with this extension...
Code: Select all
; --- gathered together from different source files ---
CoInitialize_(#Null) ; for autocomplete in stringgadgets
SHAutoComplete_(GadgetID(#GADGET_Main_StrDestDir), $50000021) ; #SHACF_AUTOAPPEND_FORCE_ON | #SHACF_AUTOSUGGEST_FORCE_ON | #SHACF_FILESYSTEM | #SHACF_FILESYS_DIRS
CoUninitialize_() ; autocomplete
Select Folder Dialog ... as a PathRequester Replacement on Windows
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).