Jump to content

ioa747
 Share

Recommended Posts

prologue

On the occasion of  @TheDcoder  post  (I wonder if someone can port it to AutoIt :lol: )
and because in the past I already had something similar (Active_SaveFileDlg),
( in which I remember making an effort so that it wouldn't catch windows other than Scite's)
So I took it as a challenge.  :rambo:

Of course, since I don't know much, I skipped the extras and stuck to the basics :lol:


A brief description

While the script is running in the background when you display the SaveFileDlg or OpenFileDlg window,  display a button-icon in the center of the window title.
Click it brings up a list of some favorite path plus the paths from all open folders.
by selecting one of them, WindowDlg goes to the selected path.
 

Active_FileDlg.au3

; https://www.autoitscript.com/forum/topic/212478-active_filedlg/
;----------------------------------------------------------------------------------------
; Title...........: Active_FileDlg.au3
; Description.....: Add All open folder & some extra as contex menu in SaveFileDlg & OpenFileDlg
; AutoIt Version..: 3.3.16.1   Author: ioa747
;----------------------------------------------------------------------------------------
#NoTrayIcon
#AutoIt3Wrapper_Icon=shell32-68.ico
#AutoIt3Wrapper_Res_Description=Add All open folder & some extra as contex menu in SaveFileDlg & OpenFileDlg
#AutoIt3Wrapper_Res_Fileversion=0.0.0.4
#AutoIt3Wrapper_Res_ProductName=Active_FileDlg.au3
#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

#include <WindowsConstants.au3>
#include <ButtonConstants.au3>
#include <WinAPISysWin.au3>
#include <Misc.au3>
#include <GuiTreeView.au3>
#include <Array.au3>

Global $aFavFolder[3]
; Fav folder
$aFavFolder[0] = 2
$aFavFolder[1] = @DesktopDir        ; * <--------- Fav1 folder (get one of your own)
$aFavFolder[2] = @MyDocumentsDir    ; * <--------- Fav2 folder (get one of your own)

_CmdLineWatcher()

While 1
    _main()
    Sleep(500)
WEnd

Exit

;--------------------------------------------------------------------------------------------------------------------------------
Func _main()
    If WinActive("[CLASS:#32770]") Then
        Local $hWnd = WinGetHandle("[ACTIVE]")

        ; checck if gui all redy exist for this Dlg
        If WinExists("GUI-" & $hWnd) Then Return

        Local $Executable = @Compiled ? '"' & @ScriptFullPath & '"' : '"' & @AutoItExe & '" "' & @ScriptFullPath & '"'

        ;specify FileDlg criteria
        _AddressBarPath($hWnd)
        If @error Then
            Local $sText = WinGetText($hWnd)
            If StringInStr($sText, "File &name") Then
                ; FoldersGUI($hWnd, 2)
                Run($Executable & ' FoldersGUI ' & $hWnd & ' 2')
                WinWaitActive("GUI-" & $hWnd, "", 5)
            EndIf

        Else
            ; FoldersGUI($hWnd, 1)
            Run($Executable & ' FoldersGUI ' & $hWnd & ' 1')
            WinWaitActive("GUI-" & $hWnd, "", 5)
        EndIf

    EndIf
EndFunc   ;==>_main
;----------------------------------------------------------------------------------------
Func FoldersGUI($hWnd, $iFlag)
    ; $iFlag:  1=_AddressBarPath, 2=File &name

    ; if parameter coming from cmdline as text
    If Not IsHWnd($hWnd) Then $hWnd = HWnd($hWnd)
    If Not IsInt($iFlag) Then $iFlag = Int($iFlag)

    Local $hGUI = GUICreate("GUI-" & $hWnd, 24, 24, -50, -50, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_NOACTIVATE), $hWnd)
    Local $idDummy = GUICtrlCreateDummy()
    Local $idButton = GUICtrlCreateButton("contex button", 0, 0, 24, 24, $BS_ICON)
    GUICtrlSetImage(-1, "shell32.dll", -68)

    Local $idContext = GUICtrlCreateContextMenu($idButton)
    Local $OpenFolders = _EnumAllOpenFolder()

    ;If not open folder, just add fav
    If $OpenFolders[0][0] = 0 Then
        ReDim $OpenFolders[UBound($OpenFolders) + 1][2]
    Else
        _ArrayInsert($OpenFolders, 1, "0|") ; separator
    EndIf

    ; Add Fav folder (the numbers on the front don't matter)
    For $i = 1 To $aFavFolder[0]
        _ArrayInsert($OpenFolders, 1, $i & "|" & $aFavFolder[$i])
    Next

    $OpenFolders[0][0] = UBound($OpenFolders) - 1
    ;_ArrayDisplay($OpenFolders)

    ; Create Context Menu
    For $i = 1 To $OpenFolders[0][0]
        GUICtrlCreateMenuItem($OpenFolders[$i][1], $idContext)
    Next

    Local $Wpos = WinGetPos($hWnd)
    WinMove($hGUI, "", $Wpos[0] + $Wpos[2] * 0.5, $Wpos[1] + 3)
    Sleep(50)
    GUISetState(@SW_SHOWNOACTIVATE, $hGUI)

    WinActivate($hWnd)
    Local $MsgId

    While WinExists($hWnd)
        $Wpos = WinGetPos($hWnd)
        WinMove($hGUI, "", $Wpos[0] + $Wpos[2] * 0.5, $Wpos[1] + 3)

        $MsgId = GUIGetMsg()
        Switch $MsgId
            Case 6 To $OpenFolders[0][0] + 6
                Switch $iFlag
                    Case 1
                        _AddressBarPath($hWnd, $OpenFolders[$MsgId - 5][1])
                    Case 2
                        _AltName($hWnd, $OpenFolders[$MsgId - 5][1])
                EndSwitch

            Case $idButton
                GUICtrlSendToDummy($idDummy)
            Case $idDummy
                MouseClick("right")
        EndSwitch
    WEnd

    GUIDelete($hGUI)

    Exit

EndFunc   ;==>FoldersGUI
;----------------------------------------------------------------------------------------
Func _EnumAllOpenFolder() ; enumerating all open folders
    Local $oShell = ObjCreate("Shell.Application")
    Local $sPath, $index = 0
    Local $aArray[$oShell.Windows.Count + 1][2] = [["hWnd", "Path"]]
    For $oWin In $oShell.Windows
        $index += 1
        $aArray[0][0] = $index
        $sPath = StringTrimLeft($oWin.LocationURL, 8) ; trim 'file:///'
        $sPath = StringReplace($sPath, "/", "\")
        $sPath = _UnicodeURLDecode($sPath)
        $aArray[$index][0] = HWnd($oWin.HWND)
        $aArray[$index][1] = $sPath
    Next
    Return $aArray
EndFunc   ;==>_EnumAllOpenFolder
;----------------------------------------------------------------------------------------
Func _UnicodeURLDecode($toDecode)
    Local $strChar = "", $iOne, $iTwo
    Local $aryHex = StringSplit($toDecode, "")
    For $i = 1 To $aryHex[0]
        If $aryHex[$i] = "%" Then
            $i = $i + 1
            $iOne = $aryHex[$i]
            $i = $i + 1
            $iTwo = $aryHex[$i]
            $strChar = $strChar & Chr(Dec($iOne & $iTwo))
        Else
            $strChar = $strChar & $aryHex[$i]
        EndIf
    Next
    Local $Process = StringToBinary($strChar)
    Local $DecodedString = BinaryToString($Process, 4)
    Return $DecodedString
EndFunc   ;==>_UnicodeURLDecode
;----------------------------------------------------------------------------------------
Func _AddressBarPath($hWnd, $sNewBarPath = "")
    WinActivate($hWnd)
    For $i = 1 To 10
        Local $hCtrl = ControlGetHandle($hWnd, "", "ToolbarWindow32" & $i)
        If @error Then ExitLoop
        Local $sControlText = ControlGetText($hWnd, "", $hCtrl)
        If StringLeft($sControlText, 9) = "Address: " Then
            Local $aTextPart = StringSplit($sControlText, ": ", 1)
            If $aTextPart[0] = 2 Then
                ; Get AddressBarPath
                If $sNewBarPath == "" Then
                    Return $aTextPart[2]
                Else ; Set AddressBarPath
                    ControlCommand($hWnd, "", $hCtrl, "SendCommandID", 1280)
                    Local $sCtrlNN = ControlGetFocus($hWnd)
                    Local $hCtrlHnd = ControlGetHandle($hWnd, "", $sCtrlNN)
                    ControlSetText($hWnd, "", $hCtrlHnd, $sNewBarPath)
                    ControlSend($hWnd, "", $hCtrlHnd, "{ENTER}")
                    Return $sNewBarPath
                EndIf
            EndIf
        EndIf
    Next

    ; If Error, return an empty string
    Return SetError(1, 0, "")
EndFunc   ;==>_AddressBarPath
;----------------------------------------------------------------------------------------
Func _AltName($hWnd, $sNewBarPath)
    WinActivate($hWnd)
    ControlSend($hWnd, "", "", "!n") ; File &name ;File &name:
    Local $sCtrlNN = ControlGetFocus($hWnd)
    Local $hCtrlHnd = ControlGetHandle($hWnd, "", $sCtrlNN)
    ControlSetText($hWnd, "", $hCtrlHnd, $sNewBarPath)
    ControlSend($hWnd, "", $hCtrlHnd, "{ENTER}")
    Return $sNewBarPath
EndFunc   ;==>_AltName
;----------------------------------------------------------------------------------------
Func _CmdLineWatcher()
    ; Run('"' & @AutoItExe & '" "' & @ScriptFullPath & '" FoldersGUI ' & $hWnd & ' 1')
    Local $aArgs = $CmdLine
    Local $sFunc
    If $aArgs[0] > 0 Then
        $sFunc = $aArgs[1]
        _ArrayDelete($aArgs, 1)
        $aArgs[0] = "CallArgArray"
        Call($sFunc, $aArgs)
        If @error = 0xDEAD And @extended = 0xBEEF Then
            ToolTip("error !! Function does not exist" & @CRLF & "or wrong number of parameter", Default, Default, @ScriptName, 3)
            Sleep(4000)
            ToolTip("")
            Exit
        EndIf
    EndIf

EndFunc   ;==>_CmdLineWatcher
;----------------------------------------------------------------------------------------

 

Please, every comment is appreciated!
leave your comments and experiences here!
Thank you very much  :)

 

 

Edited by ioa747
UpDate to version 0.0.0.4

I know that I know nothing

Link to comment
Share on other sites

I used to use a program named FolderMenu (on my PC) a lot. I knew it was written in AutoIt ...

This post remided me of it and i started googling for it and to my surprise ... there is a sourcecode available at

https://github.com/Silvernine0S/FolderMenu3EX/tree/master

I haven't tested it yet.
It worked very well with almost every save/open dialog (with rare exceptions)

As for your code ... it would be nice if it worked with more dialogs, so far chrome save as and crimson editor are not working.

Edited by Dan_555

Some of my script sourcecode

Link to comment
Share on other sites

This is the first approach,
which covers almost everything modern SaveFileDlg & OpenFileDlg & SaveFolderDlg & OpenFolderDlg
It doesn't cover programs with elevated rights, as I didn't want to give it admin rights
It does not cover improvised or boxed dialogue (like qt application)
In the meantime I thought, if something comes up that I consider essential, I can add it and upgrade my script with a new version

in chrome save as it works for me. I just tried it
in the crimson editor it doesn't work for 2 reasons

  1.  wants admin rights
  2.  I have set as a criterion that it should have at least   1 [CLASS:DirectUIHWND] and 1 [CLASS:SysTreeView32]

which does not meet


Thank you for the interaction, and for sharing your thoughts. :)

 

Edited by ioa747

I know that I know nothing

Link to comment
Share on other sites

6 hours ago, ioa747 said:

It doesn't cover programs with elevated rights, as I didn't want to give it admin rights

.., not sure. Haven't tried. But if you install to the "programs folder" you're supposed to have access to elevated windows. Untested. Just a thought. I may be wrong, very wrong.

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

I updated to version 0.0.0.2
I changed the approach a bit and became more flexible with the criteria.
You don't need any more [CLASS:DirectUIHWND] and  [CLASS:SysTreeView32].
For now, you only need it to have a ToolbarWindow32 with a path
(the text box inside the toolbar should start with Address: )

and we see :)

I know that I know nothing

Link to comment
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
 Share

×
×
  • Create New...