ClassNN Keeps Changing on TextBox

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
TXShooter
Posts: 165
Joined: 13 Dec 2017, 09:27

ClassNN Keeps Changing on TextBox

Post by TXShooter » 28 Nov 2020, 15:26

I've ran my scripts on an older Win7 setup for a couple of years without much of a problem. Now I'm updating computers and am having an issue with the latest and greatest Win10... the ClassNN of a specific textbox keeps changing, and often times within a few seconds of each reading of that textbox.

Window Spy will say at one minute its Edit10, and the next, Edit15 (so far those are the only two names). I think this is changing as a result of a child-window popping up and closing, but that hasn't been consistent either.

According to Window Spy, the Client X and Y for these textboxes don't change, so I'm trying to get something useful for ControlSetText and ControlGetText (write to the textbox, and read it back for confirmation before moving onto to the next step).

I've looked at

Code: Select all

handle:= DllCall("WindowFromPoint", Int,x, Int,y)
with the following:

Code: Select all

		EditPath := DllCall("WindowFromPoint", Int,77, Int,102) ; EditPath is now either Edit10 or Edit15
		EditFile := DllCall("WindowFromPoint", Int,77, Int,128) ; EditFile stays at Edit1
My whole snippet of code is:

Code: Select all

	SetTitleMatchMode, 1
	{
		EditPath := DllCall("WindowFromPoint", Int,77, Int,102)
		EditFile := DllCall("WindowFromPoint", Int,77, Int,128)
		Sleep 500
		WinActivate, Render to File
		Sleep 100
		ControlSetText, EditPath, %reaperFolderName%, Render to File ; Set Path
		Sleep 100
		ControlSetText, EditFile, %reaperFilename%, Render to File	  ; Set Filename
		Sleep 100
		ControlGetText, bState, EditPath, Render to File
		ControlGetText, cState, EditFile, Render to File
		MsgBox, 48, %Version% - Line 71, % "EditPath: " EditPath "`nEditFile: " EditFile
		if ((bState = reaperFolderName) && (cState = reaperFilename)) {
			break
		}
	}
MsgBox is outputting "EditPath: 724160 EditFile: 724160" (number changes from one iteration to the next, but are the same compared to each other during the same iteration), which tells me that I'm not using the DLLCall correctly.

Can someone explain this to me? How do I use the coordinates of these textboxes in a more appropriate manner?

Thank you.

User avatar
mikeyww
Posts: 27282
Joined: 09 Sep 2014, 18:38

Re: ClassNN Keeps Changing on TextBox

Post by mikeyww » 28 Nov 2020, 15:31

If you know the control's position, you can probably focus on the control of interest and then use ControlGetFocus to find its name. A handy trick is using MouseGetPos to get the control under the mouse.
OutputVarControl: This optional parameter is the name of the variable in which to store the name (ClassNN) of the control under the mouse cursor.

User avatar
Xtra
Posts: 2750
Joined: 02 Oct 2015, 12:15

Re: ClassNN Keeps Changing on TextBox

Post by Xtra » 28 Nov 2020, 16:33

Code: Select all

EditPath := DllCall("WindowFromPoint", Int,77, Int,102) ; Get control handle
EditFile := DllCall("WindowFromPoint", Int,77, Int,128) ; Get control handle

ControlSetText,, %reaperFolderName%, ahk_id %EditPath%  ; Set Path
ControlSetText,, %reaperFilename%, ahk_id %EditFile%    ; Set Filename

ControlGetText, bState,, ahk_id %EditPath%              ; Get Path
ControlGetText, cState,, ahk_id %EditFile%              ; Get Path
To operate upon a control's HWND (window handle), leave the Control parameter blank and specify ahk_id %ControlHwnd% for the WinTitle parameter (this also works on hidden controls even when DetectHiddenWindows is Off). The HWND of a control is typically retrieved via ControlGet Hwnd, MouseGetPos, or DllCall().
HTH

TXShooter
Posts: 165
Joined: 13 Dec 2017, 09:27

Re: ClassNN Keeps Changing on TextBox

Post by TXShooter » 28 Nov 2020, 18:44

Xtra wrote:
28 Nov 2020, 16:33

Code: Select all

EditPath := DllCall("WindowFromPoint", Int,77, Int,102) ; Get control handle
EditFile := DllCall("WindowFromPoint", Int,77, Int,128) ; Get control handle

ControlSetText,, %reaperFolderName%, ahk_id %EditPath%  ; Set Path
ControlSetText,, %reaperFilename%, ahk_id %EditFile%    ; Set Filename

ControlGetText, bState,, ahk_id %EditPath%              ; Get Path
ControlGetText, cState,, ahk_id %EditFile%              ; Get Path
To operate upon a control's HWND (window handle), leave the Control parameter blank and specify ahk_id %ControlHwnd% for the WinTitle parameter (this also works on hidden controls even when DetectHiddenWindows is Off). The HWND of a control is typically retrieved via ControlGet Hwnd, MouseGetPos, or DllCall().
I must be doing something wrong. I keep getting matching numbers for both the EditPath and EditFile, and they change with each iteration. Do I need to call something before this?

Code: Select all

	{
		EditPath := DllCall("WindowFromPoint", Int,77, Int,102)
		Sleep 1000
		EditFile := DllCall("WindowFromPoint", Int,77, Int,128)
		Sleep 1000
		MsgBox, 48, %Version% - Line 71, % "EditPath: " EditPath "`nEditFile: " EditFile
		Sleep 500
		WinActivate, Render to File
		Sleep 100
		ControlSetText,, %reaperFolderName%, ahk_id %EditPath% ; Render to File ; Set Path
		Sleep 100
		ControlSetText,, %reaperFilename%, ahk_id %EditFile% ; Render to File ; Set Filename
		Sleep 100
		ControlGetText, bState, %EditPath%, Render to File
		ControlGetText, cState, %EditFile%, Render to File
		if ((bState = reaperFolderName) && (cState = reaperFilename)) {
			break
		}
	}
Question: If I'm not setting the Window Title of "Render to File" anymore, how does it know where to set the text? For that matter, how does the DLLCall know the reference point for the X and Y that Window Spy gives?

I'm attaching a screenshot to help me illustrate some things.
RDI ControlSetText.png
RDI ControlSetText.png (953.24 KiB) Viewed 672 times

User avatar
Xtra
Posts: 2750
Joined: 02 Oct 2015, 12:15

Re: ClassNN Keeps Changing on TextBox

Post by Xtra » 28 Nov 2020, 20:39

WindowFromPoint has a single parameter, which is a POINT struct.

Try it like this: DllCall("WindowFromPoint", int64, y << 32 | x)

Code: Select all

EditPath := DllCall("WindowFromPoint", int64, 102 << 32 | 77) ; Get control handle
EditFile := DllCall("WindowFromPoint", int64, 128 << 32 | 77) ; Get control handle

ControlSetText,, %reaperFolderName%, ahk_id %EditPath%        ; Set Path
ControlSetText,, %reaperFilename%, ahk_id %EditFile%          ; Set Filename

ControlGetText, bState,, ahk_id %EditPath%                    ; Get Path
ControlGetText, cState,, ahk_id %EditFile%                    ; Get Path
References:
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-windowfrompoint?redirectedfrom=MSDN
https://docs.microsoft.com/en-us/previous-versions//dd162805(v=vs.85)?redirectedfrom=MSDN

TXShooter
Posts: 165
Joined: 13 Dec 2017, 09:27

Re: ClassNN Keeps Changing on TextBox

Post by TXShooter » 28 Nov 2020, 21:59

Xtra wrote:
28 Nov 2020, 20:39
WindowFromPoint has a single parameter, which is a POINT struct.

Try it like this: DllCall("WindowFromPoint", int64, y << 32 | x)

Code: Select all

EditPath := DllCall("WindowFromPoint", int64, 102 << 32 | 77) ; Get control handle
EditFile := DllCall("WindowFromPoint", int64, 128 << 32 | 77) ; Get control handle

ControlSetText,, %reaperFolderName%, ahk_id %EditPath%        ; Set Path
ControlSetText,, %reaperFilename%, ahk_id %EditFile%          ; Set Filename

ControlGetText, bState,, ahk_id %EditPath%                    ; Get Path
ControlGetText, cState,, ahk_id %EditFile%                    ; Get Path
References:
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-windowfrompoint?redirectedfrom=MSDN
https://docs.microsoft.com/en-us/previous-versions//dd162805(v=vs.85)?redirectedfrom=MSDN
I tried your solution, but with the same results.

Maybe I'm thinking that WindowFromPoint is a solution, but in reality it may be more complex to use than just a simple call?

"Retrieves a handle to the window that contains the specified point."
There are 7 'windows' within my screenshot, so how does WindowFromPoint know which one to use the Client X/Y from?

User avatar
Xtra
Posts: 2750
Joined: 02 Oct 2015, 12:15

Re: ClassNN Keeps Changing on TextBox

Post by Xtra » 29 Nov 2020, 00:20

You will want to pass screen coords to the dllcall.
Find the window position with wingetpos and then add the control position to that number. (relative to the window not client area)
This will handle the window in any position on screen.

just me
Posts: 9557
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: ClassNN Keeps Changing on TextBox

Post by just me » 29 Nov 2020, 05:34

Controls may have an additional internal identifier. You can get it using the following code:

Code: Select all

#NoEnv
; GetDlgCtrlID    -> https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdlgctrlid
; GetDlgItem      -> https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdlgitem
Return

+^LButton:: ; press Ctrl+Shift+LButton to get the information for the control under the mouse cursor
ClassNN := ""
DCID := HWIN := HWND := DCID := HCTL := 0
MouseGetPos, , , HWIN, ClassNN
MouseGetPos, , , , HWND, 2
If (HWND)
   DCID := DllCall("GetDlgCtrlID", "Ptr", HWND, "Int")
If (DCID)
   HCTL := DllCall("GetDlgItem", "Ptr", HWIN, "Int", DCID, "UPtr")
Result := "HWIN: "    . (HWIN + 0) . "`n"
        . "HWND: "    . (HWND + 0) . "`n"
        . "ClassNN: " . ClassNN    . "`n"
        . "DCID: "    . DCID       . "`n"
        . "HCTL: "    . HCTL
MsgBox, 0, Control under mouse, %Result%
Return

Esc::ExitApp
If you get unique constant values for DCID and identical handles displayed for HWND and HCTL you most probably can use this IDs. You need to pass the current HWND of the parent window and the control ID to GetDlgItem() to get the current HWND of the control.

TXShooter
Posts: 165
Joined: 13 Dec 2017, 09:27

Re: ClassNN Keeps Changing on TextBox

Post by TXShooter » 29 Nov 2020, 08:28

just me wrote:
29 Nov 2020, 05:34
Controls may have an additional internal identifier. You can get it using the following code:

If you get unique constant values for DCID and identical handles displayed for HWND and HCTL you most probably can use this IDs. You need to pass the current HWND of the parent window and the control ID to GetDlgItem() to get the current HWND of the control.
I’m away from the computer but was able to VNC into it. I can’t fully check to see if the ClassNN changes, but I managed to get these screenshots off of my phone.

I’m confused from your instructions on which set of numbers should be used.
45ADB325-5061-4017-A6D2-C57FBF70E9F7.png
45ADB325-5061-4017-A6D2-C57FBF70E9F7.png (117.17 KiB) Viewed 629 times
06F15068-AFB0-4698-B644-970503C2A1C9.png
06F15068-AFB0-4698-B644-970503C2A1C9.png (123.39 KiB) Viewed 629 times

TXShooter
Posts: 165
Joined: 13 Dec 2017, 09:27

Re: ClassNN Keeps Changing on TextBox

Post by TXShooter » 29 Nov 2020, 17:26

just me wrote:
29 Nov 2020, 05:34
Controls may have an additional internal identifier. You can get it using the following code:

If you get unique constant values for DCID and identical handles displayed for HWND and HCTL you most probably can use this IDs. You need to pass the current HWND of the parent window and the control ID to GetDlgItem() to get the current HWND of the control.
I'm trying to transliterate your code into something that gets the text as well, and I'm just not learned in the ways of C. What do I need to correct here to get the text of the textbox?

Something is producing ErrorLevel -2, which I'm assuming is my error since I don't know what I'm doing here. lol

Code: Select all

+^LButton:: ; press Ctrl+Shift+LButton to get the information for the control under the mouse cursor
ClassNN := lpString := ""
cchMax := 255
DCID := HWIN := HWND := DCID := HCTL := 0
MouseGetPos, , , HWIN, ClassNN
MouseGetPos, , , , HWND, 2
If (HWND)
   DCID := DllCall("GetDlgCtrlID", "Ptr", HWND, "Int")
If (DCID)
   HCTL := DllCall("GetDlgItem", "Ptr", HWIN, "Int", DCID, "UPtr")
TXT := DllCall("GetDlgItemTextA", "Ptr", HWIN, "Int", DCID, "UPtr", "LPSTR", lpString, "int", cchMax) 
Result := "HWIN: "    	. (HWIN + 0)	. "`n"
        . "HWND: "    	. (HWND + 0)	. "`n"
        . "ClassNN: " 	. ClassNN		. "`n"
        . "DCID: "    	. DCID			. "`n"
        . "HCTL: "    	. HCTL			. "`n"
		. "TXT:  "		. TXT
MsgBox, 0, Control under mouse, %Result%
Return
Esc::ExitApp

Post Reply

Return to “Ask for Help (v1)”