Sign in to follow this  
Followers 0
Clou42

Robust way to interact with Q-Dir

6 posts in this topic

I'm trying to automate the file manager Q-Dir (Download).

In the 4-pane-view, I need to change the Paths in all four panes and create new Tabs in some of them.

I'm currently sending keystrokes to do it, but that is not very robust because I have to guess how long to wait aber sending the hotkeys.

Can anyone figure out a way to do this more robustly using ControlClick, for example? The Control-IDs all seem random to me.

Thanks!

Share this post


Link to post
Share on other sites



It seems ControlClick does not work with this app...

I didn't know Q-Dir, it will be useful.

Instead of trying to automate it, did you try to use the File / Save and File / Open feature ? It can be simplest, no ?

Because I am good mood, here is a code to do want you want (I think) :)

#Include <WinAPI.au3>
 
 
 
; Get control list ############################################################################################
#Include <Array.au3>
 
Local $list = _WinGetControlList(WinGetHandle("Q-Dir") )
If $list = 0 Then Exit MsgBox(0, "Controls list" , "No control found") )
 
; _ArrayDisplay($list, "Controls list", Default, 0, "|", "CLASS|ClassnameNN|Advanced Mode|Handle|Text|ID|Position in window|Size|Position in screen|Visible")
; ##############################################################################################################





; Make an array with handle of listview and combo controls for each pane #######################################
Local $aPanes[1][2], $iCount = 0
For $i = 0 To UBound($list) - 1
    If $list[$i][0] = "SysListView32" AND $list[$i][9] Then 
        $iCount += 1
        Redim $aPanes[$iCount][2]
        $aPanes[$iCount - 1][0] = $list[$i][3]
    EndIf
Next

$iCount = 0
For $i = 0 To UBound($list) - 1
    If $list[$i][0] = "Edit" AND $list[$i][5] = 100 AND $list[$i][9] Then 
        $iCount += 1
        $aPanes[$iCount - 1][1] = $list[$i][3]
    EndIf
Next
; ##############################################################################################################

_ArrayDisplay($aPanes, "There are " & $iCount & " panes", Default, 0, "|", "LISTVIEW|COMBO")
WinActivate("Q-Dir")



; Sets c:\ as current view in all panes ########
For $i = 0 To $iCount - 1
    ControlFocus("Q-Dir", "", $aPanes[$i][1])
    ControlSetText("Q-Dir", "", $aPanes[$i][1], "C:\")
    Send ("{ENTER}")
    Sleep(100)
Next
; ##############################################


; Create a new tab ib the first pane and sets c:\windows as current view ###
ControlFocus("Q-Dir", "", $aPanes[0][0])
Sleep(100)
Send("^t")
Sleep(100)
ControlFocus("Q-Dir", "", $aPanes[0][1])
ControlSetText("Q-Dir", "", $aPanes[0][1], "C:\windows")
Send ("{ENTER}")
; ##########################################################################


 
 
Func _WinGetControlList($sTitle, $sText = "")
    Local $n = 0, $iCount
    Local $aControlPos, $iInstance, $aScreenPos
 
    Local $sClassList = WinGetClassList($sTitle, $sText)
    If $sClassList = "" Then Return SetError(1, 0, 0)
 
    Local $aResult = StringRegExp($sClassList, "(\N+)", 3)
    If NOT IsArray($aResult) Then Return SetError(1, 0, 0)
    Redim $aResult[UBound($aResult)][10]
 
    Local $aClasses = StringRegExp($sClassList, "(?s)(?:\A|\R)(\N+)(?=\R)(?!(?:\R\N+)*\R\1\R)", 3)
    For $i = 0 To UBound($aClasses) - 1
        StringRegExpReplace($sClassList, "\Q" & $aClasses[$i] & "\E\R", "")
        $iCount = @extended
 
        For $iInstance = 1 To $iCount
            $aResult[$n][0] = $aClasses[$i]                                                  ; Class
            $aResult[$n][1] = $aClasses[$i] & $iInstance                                     ; ClassnameNN
            $aResult[$n][2] = "[CLASS:" & $aClasses[$i] & "; INSTANCE:" & $iInstance& "]"    ; Advanced mode
            $aResult[$n][3] = ControlGetHandle($sTitle, $sText, $aResult[$n][2])             ; Handle
            $aResult[$n][4] = ControlGetText($sTitle, $sText, $aResult[$n][3] )              ; Text
            $aResult[$n][5] = _WinAPI_GetDlgCtrlID($aResult[$n][3])                          ; ID
 
            $aControlPos = ControlGetPos($sTitle, $sText, $aResult[$n][3])
            If IsArray($aControlPos) Then
                $aResult[$n][6] = "X=" & $aControlPos[0] & " ; Y=" & $aControlPos[1]          ; Position X,Y (in the Window)
                $aResult[$n][7] = "W=" & $aControlPos[2] & " ; H=" & $aControlPos[3]          ; Width and Height
            EndIf
 
            $aScreenPos = WinGetpos($aResult[$n][2])
            If IsArray($aScreenPos) Then
                $aResult[$n][8] = "X=" & $aScreenPos[0] & " ;  Y=" & $aScreenPos[1]           ; Position X,Y (relative to screen)
            EndIf
 
            $aResult[$n][9] = ControlCommand($sTitle, $sText, $aResult[$n][3], "IsVisible")   ; Visible
 
            $n += 1
        Next
    Next
 
    Return $aResult
EndFunc

Share this post


Link to post
Share on other sites

Yes, Q-Dir is a really nice tool, I use it all the time.

Save and Load functionality is exaclty what I'm trying to achieve ;) We start a lot of project in my company and for each project, I'd like to set up some directories and create a Q-Dir Favorite for the layout.

Thanks for your code, looks great and there's a lot less "Sleep()" needed than in my version :) I'll take a closer look tomorrow.

I guess there is no way to really test that the new tab is created successfully? With a lot of background (hard disk) activity, creating a new tab can take a lot longer than usual.

Share this post


Link to post
Share on other sites

Look at this

'?do=embed' frameborder='0' data-embedContent>>

With simplespy I was able to recognize all controls of Q-dir and to reliable know when to click you can catch the events in one of the more advanced eventhandling examples in that thread

But would't it be quicker to do

run("<myfile>.qdf")

or

shellexecute("<myfile>.qdf")

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Thanks, I'll take a look at it. The problem is creating those qdf-files in the first place. That's what I am trying to automate. Since I can't make sense of the file-format, this is the only way I can think of.

Edited by Clou42

Share this post


Link to post
Share on other sites

the qdr strings just seem to be hex encoded unicode strings in a bytestream

pick the string from the qdr and replace % sign with 0x

copy / paste it here and you see your recognizable directories chosen

http://hex.online-toolz.com/tools/text-hex-convertor.php

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
Sign in to follow this  
Followers 0