orbs Posted June 27, 2016 Share Posted June 27, 2016 in this topic: there is a reference to this function, using the "old style" by DLL call: Func _FileSelectFolder ($title, $root = 0, $flags = 0, $hwnd = 0) Local $ret, $pidl, $res = '' Local $ubi = DllStructCreate ("hwnd;ptr;ptr;ptr;int;ptr;ptr;int") Local $utl = DllStructCreate ("char[512]") Local $urs = DllStructCreate ("char[260]") Local $ulf = BitOR (BitShift(BitAnd ($flags,1),-9), _ BitShift(BitAnd ($flags,2),-5), _ BitShift(BitAnd ($flags,4),-2)) DllStructSetData ($utl, 1, $title) DllStructSetData ($ubi, 1, $hwnd) DllStructSetData ($ubi, 3, DllStructGetPtr($urs)) DllStructSetData ($ubi, 4, DllStructGetPtr($utl)) DllStructSetData ($ubi, 5, $ulf) $ret = DllCall ("shell32.dll", "ptr", "SHGetSpecialFolderLocation", _ "int", 0 , _ "int", $root , _ "ptr", DllStructGetPtr($ubi, 2)) If $ret[0] Then Return $res $pidl = DllCall ("shell32.dll", "ptr", "SHBrowseForFolder", "ptr", DllStructGetPtr ($ubi)) If $pidl[0] Then $ret = DllCall ("shell32.dll", "int", "SHGetPathFromIDList", _ "ptr", $pidl[0], _ "ptr", DllStructGetPtr ($urs)) If $ret[0] Then $res = DllStructGetData ($urs, 1) DllCall ("ole32.dll", "int", "CoTaskMemFree", "ptr", $pidl[0]) EndIf DllCall ("ole32.dll", "int", "CoTaskMemFree", "ptr", DllStructGetData ($ubi, 2)) Return $res EndFunc this function accepts the "root" dir as an integer, not a string (it calls the SHBrowseForFolder function, which accepts the BROWSEINFO struct, which holds the folder as an integer). this is a complete mystery to me; however, for Windows, that apparently makes perfect sense. i can't understand how this function can accept any root dir other than the default. can anyone shed some light on that? Signature - my forum contributions: Spoiler UDF: LFN - support for long file names (over 260 characters) InputImpose - impose valid characters in an input control TimeConvert - convert UTC to/from local time and/or reformat the string representation AMF - accept multiple files from Windows Explorer context menu DateDuration - literal description of the difference between given dates Apps: Touch - set the "modified" timestamp of a file to current time Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes SPDiff - Single-Pane Text Diff Link to comment Share on other sites More sharing options...
MilesAhead Posted June 27, 2016 Share Posted June 27, 2016 I never did much with the Shell Namespace because I didn't have to and it is a pita. This site may shed some light on it: https://msdn.microsoft.com/en-us/library/windows/desktop/cc144090(v=vs.85).aspx#unknown_13653 The confusion may be that the PIDL is like an integer type that is used as a pointer. You might try to find examples in a different programming language. Maybe something in C# or C++ on the Code Project site. My Freeware Page Link to comment Share on other sites More sharing options...
orbs Posted June 28, 2016 Author Share Posted June 28, 2016 (edited) following MSDN links i came across this: SHParseDisplayName Translates a Shell namespace object's display name into an item identifier list and returns the attributes of the object. This function is the preferred method to convert a string to a pointer to an item identifier list (PIDL). i tried to implement it, and failed miserably. this is my attempt: expandcollapse popupFunc _FileSelectFolder($title, $sRoot = '', $flags = 0, $hwnd = 0) Local $ret, $pidl, $res = '' Local $ubi = DllStructCreate("hwnd;ptr;ptr;ptr;int;ptr;ptr;int") Local $utl = DllStructCreate("char[512]") Local $urs = DllStructCreate("char[260]") Local $ulf = BitOR(BitShift(BitAND($flags, 1), -9), _ BitShift(BitAND($flags, 2), -5), _ BitShift(BitAND($flags, 4), -2)) DllStructSetData($utl, 1, $title) DllStructSetData($ubi, 1, $hwnd) DllStructSetData($ubi, 3, DllStructGetPtr($urs)) DllStructSetData($ubi, 4, DllStructGetPtr($utl)) DllStructSetData($ubi, 5, $ulf) If $sRoot = '' Then $ret = DllCall("shell32.dll", "ptr", "SHGetSpecialFolderLocation", _ "int", 0, _ "int", 0, _ "ptr", DllStructGetPtr($ubi, 2)) If $ret[0] Then Return $res Else ; >>>>> how to call SHParseDisplayName so that the $ubi struct will contain the PIDL in element #3 ? $ret = DllCall("shell32.dll", "long", "SHParseDisplayName", _ 'ptr', Ptr($sRoot), _ 'ptr', Null, _ 'ptr', DllStructGetPtr($ubi, 2), _ 'ptr', Null, _ 'ptr', Null) DllStructSetData($ubi, 2, $ret[3]) ; >>>>> If $ret[0] Then Return $res EndIf $pidl = DllCall("shell32.dll", "ptr", "SHBrowseForFolder", "ptr", DllStructGetPtr($ubi)) If $pidl[0] Then $ret = DllCall("shell32.dll", "int", "SHGetPathFromIDList", _ "ptr", $pidl[0], _ "ptr", DllStructGetPtr($urs)) If $ret[0] Then $res = DllStructGetData($urs, 1) DllCall("ole32.dll", "int", "CoTaskMemFree", "ptr", $pidl[0]) EndIf DllCall("ole32.dll", "int", "CoTaskMemFree", "ptr", DllStructGetData($ubi, 2)) Return $res EndFunc ;==>_FileSelectFolder i redefined the parameter to accept a string (empty string by default). if the string is empty, it follows the original logic to calculate the PIDL of the "desktop". this still works. but if it's not empty, i try to call SHParseDisplayName to calculate the PIDL. as i understand, that PIDL should be placed into the DLL struct that is later passed to SHBrowseForFolder (named $ubi here), as the 3rd field of the struct. i can't get that to work - see the section marked by ; >>>>> in the code above. what am i doing wrong? Edited June 28, 2016 by orbs Signature - my forum contributions: Spoiler UDF: LFN - support for long file names (over 260 characters) InputImpose - impose valid characters in an input control TimeConvert - convert UTC to/from local time and/or reformat the string representation AMF - accept multiple files from Windows Explorer context menu DateDuration - literal description of the difference between given dates Apps: Touch - set the "modified" timestamp of a file to current time Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes SPDiff - Single-Pane Text Diff Link to comment Share on other sites More sharing options...
LarsJ Posted June 28, 2016 Share Posted June 28, 2016 SHBrowseForFolder is implemented in _WinAPI_BrowseForFolderDlg (WinAPIDlg.au3). Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
orbs Posted June 29, 2016 Author Share Posted June 29, 2016 thank you LarsJ, i'll look into that (and i'll keep in mind to look in the WinAPI UDF if i ever bump into a DLL call). Signature - my forum contributions: Spoiler UDF: LFN - support for long file names (over 260 characters) InputImpose - impose valid characters in an input control TimeConvert - convert UTC to/from local time and/or reformat the string representation AMF - accept multiple files from Windows Explorer context menu DateDuration - literal description of the difference between given dates Apps: Touch - set the "modified" timestamp of a file to current time Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes SPDiff - Single-Pane Text Diff Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now