Mbee Posted June 11, 2016 Share Posted June 11, 2016 I'm in need of subtatial help with trancexx's FileSelectFolder UDF, if possible from the author herself. That UDF uses COM objects derived from the system-standard file dialog (IFileDialog), which object is then somewhat modified to implement the specific features trancexx wanted. What I want to do is modify that COM object further to add two Radio Button groups to the dialog, and return their values to the caller. Here's a rough example of what I think the modified FileSelectFolder2 code would have to approximate. Note that the string arguments containing all caps are from a C++ example provided by Microsoft. expandcollapse popup; _MyModSelectFolder.au3 ;.......script written by trancexx (trancexx at yahoo dot com) ; Donations to help me write more are very welcome. I can receive them via PayPal address: trancexx at yahoo dot com ; Thank you for the shiny stuff :kiss: #include <GUIConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #Include <GuiButton.au3> #include <Array.au3> #include <Constants.au3> #include <StaticConstants.au3> #include <Misc.au3> #include <String.au3> #include <StringConstants.au3> #include <File.au3> #include <FileConstants.au3> #include <ColorConstants.au3> #include <GDIPlus.au3> #include <GDIPlusConstants.au3> #include <StructureConstants.au3> #include <Date.au3> #include <WinAPI.au3> #include "ModStatusMessages.au3" #include-once ;=============================================================================== #interface "IShellItem" Global Const $sIID_IShellItem = "{43826d1e-e718-42ee-bc55-a1e261c37bfe}" Global $tagIShellItem = "BindToHandler hresult(ptr;clsid;clsid;ptr*);" & _ "GetParent hresult(ptr*);" & _ "GetDisplayName hresult(int;ptr*);" & _ "GetAttributes hresult(int;int*);" & _ "Compare hresult(ptr;int;int*);" ;=============================================================================== ;=============================================================================== #interface "IShellItemArray" Global Const $sIID_IShellItemArray = "{b63ea76d-1f85-456f-a19c-48159efa858b}" Global $tagIShellItemArray = "BindToHandler hresult(ptr;clsid;clsid;ptr*);" & _ "GetPropertyStore hresult(int;clsid;ptr*);" & _ "GetPropertyDescriptionList hresult(struct*;clsid;ptr*);" & _ "GetAttributes hresult(int;int;int*);" & _ "GetCount hresult(dword*);" & _ "GetItemAt hresult(dword;ptr*);" & _ "EnumItems hresult(ptr*);" ;=============================================================================== ;=============================================================================== #interface "IModalWindow" Global Const $sIID_IModalWindow = "{b4db1657-70d7-485e-8e3e-6fcb5a5c1802}" Global $tagIModalWindow = "Show hresult(hwnd);" ;=============================================================================== ;=============================================================================== #interface "IFileDialog" Global Const $sIID_IFileDialog = "{42f85136-db7e-439c-85f1-e4075d135fc8}" Global $tagIFileDialog = $tagIModalWindow & _ "SetFileTypes hresult(uint;ptr);" & _ "SetFileTypeIndex hresult(uint);" & _ "GetFileTypeIndex hresult(uint*);" & _ "Advise hresult(ptr;dword*);" & _ "Unadvise hresult(dword);" & _ "SetOptions hresult(int);" & _ "GetOptions hresult(int*);" & _ "SetDefaultFolder hresult(ptr);" & _ "SetFolder hresult(ptr);" & _ "GetFolder hresult(ptr*);" & _ "GetCurrentSelection hresult(ptr*);" & _ "SetFileName hresult(wstr);" & _ "GetFileName hresult(ptr*);" & _ "SetTitle hresult(wstr);" & _ "SetOkButtonLabel hresult(wstr);" & _ "SetFileNameLabel hresult(wstr);" & _ "GetResult hresult(ptr*);" & _ "AddPlace hresult(ptr;int);" & _ "SetDefaultExtension hresult(wstr);" & _ "Close hresult();" & _ "SetClientGuid hresult(clsid);" & _ "ClearClientData hresult();" & _ "SetFilter hresult(ptr);" ;=============================================================================== ;=============================================================================== #interface "IFileOpenDialog" Global Const $sCLSID_FileOpenDialog = "{DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7}" Global Const $sIID_IFileOpenDialog = "{d57c7288-d4ad-4768-be02-9d969532d960}" Global $tagIFileOpenDialog = $tagIFileDialog & _ "GetResults hresult(ptr*);" & _ "GetSelectedItems hresult(ptr*);" ;=============================================================================== ; Initiates a Browse For Folder dialog - new Windows style - if available. If not available old style gets invoked. ; Same parameters as built-in functions plus few more :P. Func _MyModSelectFolder( $arg_PromptStr, $arg_RootFoldVal ) Local $iFlag=0, $sInitialDir="", $hWindow=0, $iFlags=Default, $sButtonText=Default Local $sDialogText = $arg_PromptStr, $sRootDir = $arg_RootFoldVal Local $Lf_Stat, $Lf_RadioButtonListObjPtr ; ; ;~ Func FileSelectFolder2($sDialogText, $sRootDir, $iFlag = 0, $sInitialDir = "", $hWindow = 0, $iFlags = Default, $sButtonText = Default) ; Local $oIFileDialog = ObjCreateInterface($sCLSID_FileOpenDialog, $sIID_IFileOpenDialog, $tagIFileOpenDialog) If @error Then _MyUpdStatusMsg("_MyModSelectFolder() - ObjCreateInterface(FileDialog) failed") Return "" EndIf ; Local $Lf_DlgObjID_CustomizeObjPtr = $oIFileDialog.QueryInterface() If $Lf_DlgObjID_CustomizeObjPtr = 0 Then ; Null return means error _MyUpdStatusMsg("_MyModSelectFolder() - $oIFileDialog.QueryInterface method failed") Return "" EndIf ; $Lf_Stat = $Lf_DlgObjID_CustomizeObjPtr.AddRadioButtonList("CONTROL_RADIOBUTTONLIST") If $Lf_Stat <> 0 Then ; Call failed _MyUpdStatusMsg("_MyModSelectFolder() - AddRadioButtonList method failed") Return "" EndIf ; $Lf_Stat = $Lf_DlgObjID_CustomizeObjPtr.SetControlState("CONTROL_RADIOBUTTONLIST, CDCS_VISIBLE | CDCS_ENABLED") If $Lf_Stat <> 0 Then ; Failure _MyUpdStatusMsg("_MyModSelectFolder() - SetControlState method failed") Return "" EndIf ; $Lf_Stat = $Lf_DlgObjID_CustomizeObjPtr.AddControlItem("CONTROL_RADIOBUTTONLIST, CONTROL_RADIOBUTTONGroup1") If $Lf_Stat <> 0 Then ; Failure _MyUpdStatusMsg("_MyModSelectFolder() - AddControlItem - RadioButtonGroup1 method failed") Return "" EndIf ; $Lf_Stat = $Lf_DlgObjID_CustomizeObjPtr.AddControlItem("CONTROL_RADIOBUTTONLIST, CONTROL_RADIOBUTTONGroup2") If $Lf_Stat <> 0 Then ; Failure _MyUpdStatusMsg("_MyModSelectFolder() - AddControlItem - RadioButtonGroup2 method failed") Return "" EndIf ; $Lf_Stat = $Lf_DlgObjID_CustomizeObjPtr.SetSelectedControlItem("CONTROL_RADIOBUTTONLIST, CONTROL_RADIOBUTTON1") If $Lf_Stat <> 0 Then ; Failure _MyUpdStatusMsg("_MyModSelectFolder() - AddControlItem - SetSelectedControlItem method failed") Return "" EndIf ; ; ; Pick up from trancexx's UDF code ; $oIFileDialog.SetTitle($sDialogText) If $sButtonText <> Default Then $oIFileDialog.SetOkButtonLabel($sButtonText) If $sRootDir = "" Then $sRootDir = @DesktopDir Local $pIDL = FSF_SHParseDisplayName($sRootDir) Local $oRoot = ObjCreateInterface(FSF_SHCreateShellItem($pIDL), $sIID_IShellItem, $tagIShellItem) If @error Then _MyUpdStatusMsg("_MyModSelectFolder() - ObjCreateInterface(FSF_SHCreateShellItem) #2 Failed!") Return "" ;~ Return FileSelectFolder($sDialogText, $sRootDir, $iFlag, $sInitialDir, $hWindow) EndIf FSF_CoTaskMemFree($pIDL) $oIFileDialog.SetFolder($oRoot()) $oIFileDialog.SetFileName($sInitialDir) Local Const $FOS_PICKFOLDERS = 0x20 if $iFlags = Default Then $iFlags = $FOS_PICKFOLDERS $oIFileDialog.SetOptions($iFlags) $oIFileDialog.Show($hWindow) ; Tada mtfk! Local $pShellItemArray $oIFileDialog.GetResults($pShellItemArray) Local $oShellItemArray = ObjCreateInterface($pShellItemArray, $sIID_IShellItemArray, $tagIShellItemArray) If @error Then Return SetError(1, 0, "") Local $iCount $oShellItemArray.GetCount($iCount) Local $pShellItem, $oIShellItem, $pName, $sName Local Const $S_OK = 0 Local Const $SIGDN_DESKTOPABSOLUTEEDITING = 0x8004c000, $SIGDN_FILESYSPATH = 0x80058000 ; ; For _MyModSelectFolder, the following code must be modified to return both radio button group's choice status ; For $i = 0 To $iCount - 1 $oShellItemArray.GetItemAt($i, $pShellItem) $oIShellItem = ObjCreateInterface($pShellItem, $sIID_IShellItem, $tagIShellItem) If @error Then ContinueLoop If $oIShellItem.GetDisplayName($SIGDN_FILESYSPATH, $pName) <> $S_OK Then If $oIShellItem.GetDisplayName($SIGDN_DESKTOPABSOLUTEEDITING, $pName) <> $S_OK Then Return SetError(2, 0, "") EndIf $sName &= DllStructGetData(DllStructCreate("wchar[" & FSF_StringLenW($pName) + 1 & "]", $pName), 1) & "|" FSF_CoTaskMemFree($pName) Next SetError(0, 0, StringTrimRight($sName, 1)) Return StringTrimRight($sName, 1) EndFunc ; Few helper functions down below... Func FSF_SHParseDisplayName($sPath) Local $aCall = DllCall("shell32.dll", "long", "SHParseDisplayName", "wstr", $sPath, "ptr", 0, "ptr*", 0, "ulong", 0, "ulong*", 0) If @error Or $aCall[0] Then Return SetError(1, 0, 0) Return $aCall[3] EndFunc Func FSF_SHCreateShellItem($pPIDL) Local $aCall = DllCall("shell32.dll", "long", "SHCreateShellItem", "ptr", 0, "ptr", 0, "ptr", $pPIDL, "ptr*", 0) If @error Or $aCall[0] Then Return SetError(1, 0, 0) Return $aCall[4] EndFunc Func FSF_CoTaskMemFree($pMemory) DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $pMemory) If @error Then Return SetError(1, 0, 0) Return 1 EndFunc Func FSF_StringLenW($vString) Local $aCall = DllCall("kernel32.dll", "int", "lstrlenW", "struct*", $vString) If @error Then Return SetError(1, 0, 0) Return $aCall[0] EndFunc ; ; ; Func _MyUpdStatusMsg( $arg_Msg ) Local $Lf_MsgLineAra = StringSplit( $arg_Msg, @CR, $STR_ENTIRESPLIT ) If @error = 1 Then ; If no crlf delimiters found... StatusMsgs_WriteLine( $arg_Msg ) Else Local $Lf_MsgCount = $Lf_MsgLineAra[0] For $i = 1 To $Lf_MsgCount StatusMsgs_WriteLine( StringStripCR($Lf_MsgLineAra[$i]) ) Next EndIf EndFunc Obviously, this code must be fleshed out considerably, for which I am seeking assistance. For example, what data structures are used in these COM object calls, such as the Radio Button List Control ("CONTROL_RADIOBUTTONLIST"), and how do I create and populate them? Am I missing any method calls I need? Etc, etc... I would be endlessly grateful for guidance and coding assistance! Link to comment Share on other sites More sharing options...
Jfish Posted June 11, 2016 Share Posted June 11, 2016 You can tag people in your posts like this @trancexx. Thought that may be useful for your bat-signal post Xandy 1 Build your own poker game with AutoIt: pokerlogic.au3 | Learn To Program Using FREE Tools with AutoIt Link to comment Share on other sites More sharing options...
Mbee Posted June 11, 2016 Author Share Posted June 11, 2016 39 minutes ago, Jfish said: You can tag people in your posts like this @trancexx. Thought that may be useful for your bat-signal post Hey, thanks for the helpful tip, jfish! Link to comment Share on other sites More sharing options...
Danyfirex Posted June 11, 2016 Share Posted June 11, 2016 I don't have time to program right now but here is a C++ sample https://msdn.microsoft.com/en-us/library/windows/desktop/bb776913(v=vs.85).aspx Saludos Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut 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