Jump to content
c.haslam

Centering FileSelectFolder() in a GUI

Recommended Posts

c.haslam

I wish to center FileSelectFolder in a parent window created with AutoIt. I wish to have the same functionality as FileFindFolder.

Melba23's ChooseFileFolder.au3 seems to almost do this, but not quite.

Thoughts?


Spoiler

CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard

 

Share this post


Link to post
Share on other sites
Melba23

c.haslam,

Quote

Melba23's ChooseFileFolder.au3 seems to almost do this, but not quite

What exactly does my UDF not do that you would like to see it do?

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
c.haslam

Her's what I would like to do:

  • Initially, show Desktop with Computer and Network below it, including other PCs on the network
  • Select any folder, even one that has other folders within it
  • Show mapped drives
  • Do not show files

Perhaps ChooseFileFolder will do this.


Spoiler

CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard

 

Share this post


Link to post
Share on other sites
Melba23

c.haslam,

Why not try it and see - I have no mapped drives to test so I cannot say.

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
c.haslam

Here is a trial script:

Opt('MustDeclareVars',1)
#include 'GuiConstantsEx.au3'

#include "..\ChooseFileFolder Melba23\ChooseFileFolder.au3"
Local $gui = GUICreate('',@DesktopWidth/2,@DesktopHeight-57,1,1)
GUISetState()

    Local $root = "::{85BBD920-42A0-1069-A2E4-08002B30309D}"    ; Briefcase = Desktop
    Local $sPath = _CFF_Choose('Choose drive or directory',400,400, _
        (@DesktopWidth/2-400)/2,(@DesktopHeight-57-400)/2,@DesktopDir,2)
    MsgBox(0,'',$sPath)
    Exit

Local $nMsg
While True
    $nMsg = GUIGetMsg()
    If $nMsg=$GUI_EVENT_CLOSE Then
        Exit
    EndIf
WEnd

How can I get the left pane of this to show:

Clipboard01.jpg.5854aff8823050f87bd8ed96943e6e0d.jpg

(I only need Computer and Network, with both expandable.)


Spoiler

CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard

 

Share this post


Link to post
Share on other sites
Melba23

c.haslam,

A simple:

#include "ChooseFileFolder.au3"

 _CFF_Choose("Title", Default, Default, Default, Default, "", Default, 2)

should work.

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
c.haslam

I copied and pasted your suggestion. It shows

Clipboard01.jpg.2ebc69fb7cb10cdbfd232dcb5f9acc16.jpg

This is after clicking on each of the drives. Only local drives are showing, not mapped ones.


Spoiler

CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard

 

Share this post


Link to post
Share on other sites
Melba23

c.haslam,

You need a _CFF_RegMsg call to allow for expansion - I did not include it in that snippet as all I wanted was to see if you got the drives displayed.

The UDF uses DriveGetDrive("ALL") & DriveGetDrive("NETWORK") to list available drives if you do not specify which drives to open - I have no idea why your mapped drives do not appear. If they appear as folders within those drives then simply add the _CFF_RegMsg call and you should be able to see them when you expand the branches of the tree.

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
c.haslam
  • I have added the call to _CFF_RegMsg. Expansion now works.
  • In Windows Explorer, the mapped drives show as Disconnected Network Drive. They also show in PowerDesk.
  • I ran netstat from the command line. In Windows Explorer, they now show as Network Drive
  • DriveGetDrive('ALL') now shows the mapped drives.

We need a way in AutoIt of connecting to drives which are on a remote PC. I don't have a clue.


Spoiler

CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard

 

Share this post


Link to post
Share on other sites
c.haslam

I have figured out how to get the drive letters of mapped drives. (I also also able to get the drive names.) Here is my code:

Func AddMissingNetworkDrives(ByRef $a_Drives)
; Ref: https://www.autoitscript.com/forum/topic/71790-enum-network-connections/
    Local $host = "."
    Local $objWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $host & "\root\cimv2")
    Local $colItems = $objWMIService.ExecQuery ("SELECT * from Win32_NetworkConnection")

    Local $nuDrive,$bfound,$q
    For $objItem in $colItems
        $nuDrive = $objItem.LocalName
        $bfound = False
        For $i = 1 To $a_Drives[0]-1
            If $a_Drives[$i]=$nuDrive Then
                $bfound = True
                ExitLoop
            EndIf
        Next
        If Not $bfound Then
            $a_Drives[0] += 1
            ReDim $a_Drives[$a_Drives[0]+1]
            $a_Drives[$a_Drives[0]] = $nuDrive
        EndIf
    Next
EndFunc

and here is how it is called from _CFF_Choose():

; Create drive lists if no root set
    If $sRoot = "" Then
        ; Check if drive list set
        If $sDrives Then
            ; Create array of these drives
            $aAll_Drives = StringSplit($sDrives, "")
            For $i = 1 To $aAll_Drives[0]
                $aAll_Drives[$i] &= ":"
            Next
        Else
            ; Get array of drives
            $aAll_Drives = DriveGetDrive("ALL")
            If @error Then
                Local $aAll_Drives[1] = [0]
            EndIf
            AddMissingNetworkDrives($aAll_Drives)   ; ByRef
        EndIf
        ; Get array of network drives - to show indexing label if required
        $aNetwork_Drives = DriveGetDrive("NETWORK")
        If @error Then
            Local $aNetwork_Drives[1] = [0]
        EndIf
        AddMissingNetworkDrives($aNetwork_Drives)   ; ByRef
    EndIf

however, when I run

Opt('MustDeclareVars',1)
#include 'GuiConstantsEx.au3'
#include "..\ChooseFileFolder Melba23\cChooseFileFolder.au3"

; Register handlers
Local $sRet = _CFF_RegMsg()
If Not $sRet Then
    MsgBox(16, "Failure!", "Handler not registered")
    Exit
EndIf

Local $sPath = c_CFF_Choose("Title", Default, Default, Default, Default, "", Default, 2)

Local $nMsg
While True
    $nMsg = GUIGetMsg()
    If $nMsg=$GUI_EVENT_CLOSE Then
        Exit
    EndIf
WEnd

only local drives show.

Perhaps you can point out my error in adding my code to yours.

On my PC, when my function is run the first time:

  • on entry $a_drives contains [5,'c:','d:','e:','f:','g:','h:']
  • it updates $a_drives to [10,'c:','d:','e:','f:','g:','h:','w:','x:','y:','z:']

Thoughts?


Spoiler

CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard

 

Share this post


Link to post
Share on other sites
c.haslam

I think I see why the network drives, w: thru z:, are not showing: _CFF_Fill_Drives() and _CFF_Fill_Combo() (as does _CFF_SetPreCheck() ) contain the statement

If DriveStatus($sDrive & '\') == "READY" Then

A network drive may not be READY.

A possible way of solving the problem is to precede these statements with

For $i = 1 To $aDrives[0]-1
    If DriveStatus($aDrives[$i]<>'READY' And DriveGetType($aDrives[$i])='Network' Then
        $share = DriveMapGet($aDrives[$i])
        DriveMapDel($aDrives[$i])
        DriveMapAdd($aDrives[$i],$share,1)  ; persistent
    EndIf
Next

This seems like a fairly dire possible solution to the problem. I have not tried it.

Thoughts?


Spoiler

CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard

 

Share this post


Link to post
Share on other sites
c.haslam
Posted (edited)

Melba23,

I believe that I have succeeded in adding the ability to choose folders from mapped drives. In doing so, I have been careful to disturb your code as little as possible. My additions are 1 global variable, 6 functions (and calls to them). I have tested with

Local $sPath = _CFF_Choose("Title", Default, Default, Default, Default, "", Default, 2)

and

Local $sPath = _CFF_Choose("Title", Default, Default, Default, Default, "Z:\", Default, 2)

While I was at it, I added showing drive labels in a similar way to FileSelectFolder. These features give ChooseFileFolder more of the features that FileSelectFolder has.

The global variable is $g_oCFF_WmiDriveInfo, and the six functions are:

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: __CFF_GetWMIdriveInfo
; Description ...: Collects attributes of local and mapped drives for local computer
; Author ........: c.haslam
; Remarks .......: Includes remote drives that are not currently connected
;                  Ref: https://www.autoitscript.com/forum/topic/71790-enum-network-connections/
;                  Ref: Scriptomatic
; ===============================================================================================================================
Func _CFF_GetWMIdriveInfo()
    ; Ref: https://www.autoitscript.com/forum/topic/71790-enum-network-connections/
    ; Ref: Scriptomatic
    Local $host = "."
    Local $objWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $host & "\root\cimv2")
    $g_oCFF_WmiDriveInfo = $objWMIService.ExecQuery("SELECT * from Win32_NetworkConnection")
EndFunc   ;==>_CFF_GetWMIdriveInfo

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: _CFF_AddDisconnectedDriveLetters
; Description ...: Adds drive letters of all drives that are disconnected from local computer
; Author ........: c.haslam
; Remarks .......:
; ===============================================================================================================================
Func _CFF_AddDisconnectedDriveLetters(ByRef $a_Drives)
    If Not IsObj($g_oCFF_WmiDriveInfo) Then
        _CFF_GetWMIdriveInfo()
    EndIf
    Local $nuDrive, $bfound
    For $objItem In $g_oCFF_WmiDriveInfo
        If $objItem.ConnectionState = 'Disconnected' Then
            $nuDrive = $objItem.LocalName
            $bfound = False
            For $i = 1 To $a_Drives[0] - 1
                If $a_Drives[$i] = $nuDrive Then
                    $bfound = True
                    ExitLoop
                EndIf
            Next
            If Not $bfound Then
                $a_Drives[0] += 1
                ReDim $a_Drives[$a_Drives[0] + 1]
                $a_Drives[$a_Drives[0]] = StringUpper($nuDrive)
            EndIf
        EndIf
    Next
EndFunc   ;==>_CFF_AddDisconnectedDriveLetters

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: _CFF_ConnectMappedDrive
; Description ...: Connects a mapped (but currently disconnected) drive
; Author ........: c.haslam
; Remarks .......:
; ===============================================================================================================================
Func _CFF_ConnectMappedDrive($sDrive)
    If Not IsObj($g_oCFF_WmiDriveInfo) Then
        _CFF_GetWMIdriveInfo()
    EndIf
    For $objItem In $g_oCFF_WmiDriveInfo
        If $objItem.ConnectionState = 'Disconnected' And $objItem.LocalName = $sDrive Then
            ; persistent,Show authentication dialog if required
            DriveMapAdd($objItem.LocalName, $objItem.RemoteName, 1 + 8)
            ExitLoop
        EndIf
    Next
EndFunc   ;==>_CFF_ConnectMappedDrive

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:  _CFF_PrependLabelToDriveLetter
; Description ...:  For labelled drives, prepends label to drive letter
; Author ........:  c.haslam
; Remarks .......:
;Example ........; F:  => MProgsH (F:)
; ===============================================================================================================================
Func _CFF_PrependLabelToDriveLetter($sDrive)
    Local $sLabel = DriveGetLabel($sDrive)
    $sDrive = StringUpper($sDrive) ; manually added mapping may be lowercase
    Local $sRet
    If $sLabel <> '' Then
        Local $sRet = $sLabel & ' (' & $sDrive & ')'
    Else
        Local $sRet = $sDrive
    EndIf
    Return $sRet
EndFunc   ;==>_CFF_PrependLabelToDriveLetter

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:  _CFF_ExtractDriveFromLabelDrive
; Description ...:  For labelled drives, extracts drive letter from label (drive:)
; Author ........:  c.haslam
; Remarks .......:
;Example ........; MProgsH (F:) => F:
; ===============================================================================================================================
Func _CFF_ExtractDriveFromLabelDrive($sLabelDrive)
    Local $a1 = StringRegExp($sLabelDrive, '[A-Za-z]\:', 1) ; $STR_REGEXPARRAYMATCH
    Local $sDrive
    If @error = 0 Then
        $sDrive = $a1[0]
    Else
        $sDrive = $sLabelDrive
    EndIf
    Return $sDrive
EndFunc   ;==>_CFF_ExtractDriveFromLabelDrive

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:  _CFF_RemoveLabelFromPath
; Description ...:  For labelled drives, removes label from path
; Author ........:  c.haslam
; Remarks .......:
;Example ........; MProgsH (F:)\AutoIt scripts => F:\AutoIt scipts
; ===============================================================================================================================
Func _CFF_RemoveLabelFromPath($sPathInclLabel)
    Local $iBSl = StringInStr($sPathInclLabel, '\')
    Local $sRet
    If $iBSl = 3 Then
        $sRet = $sPathInclLabel
    Else
        $sRet = StringMid($sPathInclLabel, $iBSl - 3, 2) & StringMid($sPathInclLabel, $iBSl)
    EndIf
    Return $sRet
EndFunc   ;==>_CFF_RemoveLabelFromPath

The whole script is cChooseFileFolder.au3

I thank you, and many others whose code I have consulted.

There may well be unhandled conditions. Perhaps you can think of some, so I can add code to handle them. I hope that the AutoIt community will chip in.

cChooseFileFolder does not yet handle unmapped drives which are accessible by one PC from another. This would require getting into security policies. Also, I think that Windows permits mapping to a folder tree on a remote drive. I don't do this, so would need to set this up on one of my PCs.

 

Thougts?.

Edited by c.haslam

Spoiler

CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard

 

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

×