3
votes

I have a window that displays a book. In two smaller boxes below, there is page number and volume information of the book that is open. I can get that information easily as follows:

ControlGetText, volume, ThunderRT6TextBox3      
ControlGetText, page, ThunderRT6TextBox2

Then my script makes my mouse pointer move to a button. It clicks it, and a new window pops open. In that window, there is more textual information related to the book, such as publisher, name author, edition etc. I want to retrieve that information. But when I try the same strategy it is not working, eg:

ControlGetText, data, RichTextWndClass3

The only difference between the two cases, is that those two small boxes are editable, you can enter text whereas this window is static.

I tried many other options such as: SendEvent ^a Which is equivalent to control + a, which should select everything. I tried putting pauses but it would never select. I tried the script to manually double click on that window. It works, and one word gets select like that. Even then SendEvent ^a doesn't do anything. However, if I do SendEvent ^{insert}, then the selected word gets copied to my clipboard.

I experimented with more combinations:

ControlSend ahk_class ThunderRT6FormDC, ^a
ControlSend ClassNN RichTextWndClass3, ^a

and

ControlSend ThunderRT6FormDC, ^a
ControlSend RichTextWndClass3, ^a

None of them work. All text selection does not manifest itself in that window.

The only alternative remaining for me is to make the script do a manual selection of the entire text. However, this is slow and very ridiculous. Moreover, in Window Spy under the section: Visible Window Text, the text is all there. I tried many other possibilities and I am at the end of my wits. How am I to harvest that text directly?


EDIT-- The text of the window shows in Window Spy under the heading: TitleMatchMode=slow Visible Text, NOT the heading: Visible Window Text


EDIT-- I spoke to you about two windows. The first one in which i get volume and page number. The second one which needs to pop up by pressing a button. Both these windows have the same class-name: ahk_class ThunderRT6MDIForm Is that problematic in any way?


EDIT-- The conclusion is that it is impossible for me to get that text from the second window directly. As such, I opted for the lame, boring manual method. I send out a {shift down} to the active window and then do a click at the bottom of the window. Then I save the selection to my clipboard. It works, but it is just stupid. Please help me find a more elegant solution than this one.

This is the code I used:

ControlGetText, volume, ThunderRT6TextBox3 

ControlGetText, page, ThunderRT6TextBox2 

Click, 110, 70 

sleep 1000

SendInput {shift down}

click 29, 490

SendInput {shift up}

sleep 1000

SendInput, ^{ins} 

sleep 100

It is funny to note that real keyboard keys, such as a b c are not possible. But I am able to send a ctrl, shift and an ins. As I noted above, ^c was also giving issues just like ^a was giving issues.

2
Window spy is sometimes inaccurate when it comes to finding specific controls. If the text is listed under window text, you have good cards. There's two ways: 1) Loop over each control the window exposes using WinGet, Outputvar, ControlList in order to find which control(s) contain the desired text. 2) Retrieve the text with WinGetText and extract what you need. I recommend 1) because it is more accurate.MCL
Thanks. I selected the fourth option from the link you gave me. It gives me a persistent window with all the information, about 8 items. All of them correspond to what Window Spy is saying. There is only one event I was unable to find, it is called tabstripwendclass1 or something like that. Also, I have to correct my claim in my post, the text shows in Window Spy under the heading: TitleMatchMode=slow Visible Text not the heading Visible Window Text.Khalil
Lastly, I don't understand properly how I am supposed to find out the correct control that contains the desired text by means of that tool. Is it supposed to show at the top of list that I am looping over with my mouse? It doesn't change, except if i change the window in its entirety.Khalil
It's a long shot, but try triple-clicking the window to see if it selects the entire textJohn Dvorak
Let me put it this way: Do not use Window Spy, as it won't give you what you need in your your case. Also, I never recommended using Example #4 or any other incoherent code from the docs. Step 1: Retrieve a ControlList with WinGet, myList, ControlList ... Step 2: Loop over that list: Loop, Parse, myList, `n, `r Step 3: Inside the loop, inspect each control, e.g.: ControlGetText, myText, % A_LoopField ... Step 4: Show the information in some way, e.g.: msgbox, ClassNN: %A_LoopField%`nText: %myText%MCL

2 Answers

1
votes

There is an autohotkey script that emulates most of the window spy logic. It is called AHK_Window_Info_v1.7.ahk. The nice thing is... you can run it to see if your second window text if visible to this script and if so... the logic needed to pull the information is available inside the script. Here is a link to the webpage and the script is available through SKANs dropbox link on that page. http://www.autohotkey.com/board/topic/8204-ahk-window-info-17/

1
votes

This routine will do the job of getting and returning from the active window the following text sections: - EdtWindowTextFastVisible - EdtWindowTextSlowVisible - EdtWindowTextFastHidden - EdtWindowTextSlowHidden

MyGetWindowText(ByRef EdtWindowTextFastVisible, ByRef EdtWindowTextSlowVisible, ByRef EdtWindowTextFastHidden,ByRef EdtWindowTextSlowHidden)
{
; Source: https://code.google.com/p/autohotkey-cn/source/browse/trunk/Source/AHK_Window_Info/AHK_Window_Info_v1.7.ahk?r=6
EdtWindowTextFastVisible =
EdtWindowTextSlowVisible =
EdtWindowTextFastHidden =
EdtWindowTextSlowHidden =

WindowControlTextSize = 32767
VarSetCapacity(WindowControlText, WindowControlTextSize)
WinGet, WindowUniqueID, ID, A

;Suggested by Chris
WinGet, ListOfControlHandles, ControlListHwnd, ahk_id %WindowUniqueID% ; Requires v1.0.43.06+.
Loop, Parse, ListOfControlHandles, `n
{
    text_is_fast := true
    If not DllCall("GetWindowText", "uint", A_LoopField, "str", WindowControlText, "int", WindowControlTextSize)
    {
        text_is_fast := false
        SendMessage, 0xD, WindowControlTextSize, &WindowControlText,, ahk_id %A_LoopField% ; 0xD is WM_GETTEXT
    }
    If (WindowControlText <> ""){
        ControlGet, WindowControlStyle, Style,,, ahk_id %A_LoopField%
        If (WindowControlStyle & 0x10000000)
        { ; Control is visible vs. hidden (WS_VISIBLE).
            If text_is_fast
            EdtWindowTextFastVisible = %EdtWindowTextFastVisible%%WindowControlText%`r`n
            Else
            EdtWindowTextSlowVisible = %EdtWindowTextSlowVisible%%WindowControlText%`r`n
        } Else
        { ; Hidden text.
            If text_is_fast
            EdtWindowTextFastHidden = %EdtWindowTextFastHidden%%WindowControlText%`r`n
            Else
            EdtWindowTextSlowHidden = %EdtWindowTextSlowHidden%%WindowControlText%`r`n
        }
    }
}

;EdtWindowTextFastVisibleFull := ShowOnlyAPartInGui("EdtWindowTextFastVisible", EdtWindowTextFastVisible, 400)
;EdtWindowTextSlowVisibleFull := ShowOnlyAPartInGui("EdtWindowTextSlowVisible", EdtWindowTextSlowVisible, 400)
;EdtWindowTextFastHiddenFull := ShowOnlyAPartInGui("EdtWindowTextFastHidden", EdtWindowTextFastHidden, 400)
;EdtWindowTextSlowHiddenFull := ShowOnlyAPartInGui("EdtWindowTextSlowHidden", EdtWindowTextSlowHidden, 400)

Return
}