Jump to content
Mbee

Trancexx: Help needed re Com objects in FileSelectFolder UDF

Recommended Posts

Mbee

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.

; _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!

 

Share this post


Link to post
Share on other sites
Mbee
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!

 

Share this post


Link to post
Share on other sites
Danyfirex

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

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • UEZ
      By UEZ
      Link and example: FrameGrabber.dll 
      What about my question regarding returning a bitmap handle or bitmap data rather than saving the grabbed frame to disk?
      Actually I would talk about VScript because I'm curious but Jon doesn't want it but can you show me the code please? You said it is similar to AU3 code. I want to understand how you did it.
       
      Thanks.
       
       
       
    • sanulevan
      By sanulevan
      Hi,

      i install the software NXPowerlite in my C:\Program Files (x86)\NXPowerLite folder,
      please give a sample code for running this software without using run,winwaitactive ,etc(using com obj).
×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.