Get Window Title at Specific Coordinates

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Get Window Title at Specific Coordinates

Post by swagfag » 12 May 2019, 13:00

sorry, i still dont understand how this is supposed to work. so we have the 8 byte(64 bit) struct POINT

Code: Select all

struct POINT {
  __int32 x;
  __int32 y;
};
which is being treated as an __int64 because "Structs and unions of size 8, 16, 32, or 64 bits, and __m64 types, are passed as if they were integers of the same size.".
ok, suppose __int32 x = 0xXXXXXXXX; and __int32 y = 0xYYYYYYYY;, u have somewhere in memory 0xXXXXXXXX and right next to it 0xYYYYYYYY.
now, this 16 byte (64 bit) sequence of bytes in memory: .... XXXX XXXX YYYY YYYY .... is looked at and reinterpreted as the 64 bit integer: __int64 theArgument = 0xXXXXXXXXYYYYYYYY;.
that integer is then passed to WindowFromPoint and WindowFromPoint somehow knows that the high bytes are meant to be the X, whereas the low bytes represent the Y coordinate.

BUT! in the DllCall, if we're passing this number it has to be constructed the other way around: 0xYYYYYYYYXXXXXXXX, the high bytes are Y and the low - X.
???

also, presumably, these 64bit ints fit entirely into the 64bit RCX
the "rect by value" function is a nice find, gj

User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Get Window Title at Specific Coordinates

Post by jeeswg » 12 May 2019, 13:14

Because it's little endian, when you store an 8-byte number, the later digits are stored at the front. When writing, the bytes are swapped. And when reading, the bytes are swapped.

Code: Select all

q:: ;test write UInt64, and read as UInts/UShorts/UChars
VarSetCapacity(vData, 8)
NumPut("0x8877665544332211", &vData, 0, "UInt64")

vOutput := ""

Loop, 2
	vNum := NumGet(&vData, (A_Index-1)*4, "UInt")
	, vOutput .= (A_Index=1?"":" ") Format("0x{:X}", vNum)
vOutput .= "`r`n"

Loop, 4
	vNum := NumGet(&vData, (A_Index-1)*2, "UShort")
	, vOutput .= (A_Index=1?"":" ") Format("0x{:X}", vNum)
vOutput .= "`r`n"

Loop, 8
	vNum := NumGet(&vData, A_Index-1, "UChar")
	, vOutput .= (A_Index=1?"":" ") Format("0x{:X}", vNum)
vOutput .= "`r`n"

Clipboard := vOutput
MsgBox, % vOutput
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

teadrinker
Posts: 4295
Joined: 29 Mar 2015, 09:41
Contact:

Re: Get Window Title at Specific Coordinates

Post by teadrinker » 12 May 2019, 13:17

swagfag wrote: (400 & 0xFFFFFFFF) | (500 << 32) by itself isnt a string, its purely numeric, it should be of type __int64.
Formally, this value is a number, but AHK stores this value in memory as a string, and you can easily verify this:

Code: Select all

MsgBox, % (400 & 0xFFFFFFFF) | (500 << 32)        . "`n"
        . Ord( (400 & 0xFFFFFFFF) | (500 << 32) ) . "`n"  ; 50 — character code of 2
        . Chr(50)                                         ; 2 — first number in 2147483648400
        
POINT := (400 & 0xFFFFFFFF) | (500 << 32)
Loop % StrLen(POINT) {
   ch := NumGet(POINT, (A_Index - 1) << !!A_IsUnicode, A_IsUnicode ? "UShort" : "UChar")
   MsgBox, % POINT                . "`n"
   . "char position: " . A_Index  . "`n"
   . "char code: "     . ch       . "`n"
   . "char: "          . Chr(ch)
}

swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Get Window Title at Specific Coordinates

Post by swagfag » 12 May 2019, 14:28

jeeswg wrote:
12 May 2019, 13:14
Because it's little endian
holy batman, yes, finally, now it all makes sense. thank u

if u have the struct:

Code: Select all

struct POINT {
	__int32 x = 0xX4X3X2X1; 
	__int32 y = 0xY4Y3Y2Y1; 
}
in memory it will be laid out like this:

Code: Select all

                          |
                          V
__int32 = 0xX4 X3 X2 X1   ..
             |  |  |  +-> X1
             |  |  +----> X2
             |  +-------> X3
             +----------> X4

__int32 = 0xY4 Y3 Y2 Y1   
             |  |  |  +-> Y1
             |  |  +----> Y2
             |  +-------> Y3
             +----------> Y4
                          ..
                          |
                          V

-->> .. .. X1 X2 X3 X4 Y1 Y2 Y3 Y4 .. .. -->>
so if u store this exact byte sequence in RCX by some other means, u will trick WindowFromPoint into thinking it's working with a struct. and the means to do so, happen to be "bitshift the y coord into the high order bytes and leave the x coord in the low order bytes", (0xY4 Y3 Y2 Y1 << 32) | 0xX4 X3 X2 X1 produces 0xY4 Y3 Y2 Y1 X4 X3 X2 X1, in other words:

Code: Select all

                            |
                            V
0xY4 Y3 Y2 Y1 X4 X3 X2 X1   ..
   |  |  |  |  |  |  |  +-> X1
   |  |  |  |  |  |  +----> X2
   |  |  |  |  |  +-------> X3
   |  |  |  |  +----------> X4
   |  |  |  +-------------> Y1
   |  |  +----------------> Y2
   |  +-------------------> Y3
   +----------------------> Y4
                            ..
                            |
                            V

-->> .. .. X1 X2 X3 X4 Y1 Y2 Y3 Y4 .. .. -->>
same byte sequence as the one produced by the struct

lexikos
Posts: 9494
Joined: 30 Sep 2013, 04:07
Contact:

Re: Get Window Title at Specific Coordinates

Post by lexikos » 20 Jun 2021, 06:27

teadrinker wrote:
12 May 2019, 13:17
Formally, this value is a number, but AHK stores this value in memory as a string, and you can easily verify this:
As people are referring to this topic, I will point out that this is technically correct, but misleading.

When you assign the result of a bitwise operator to a variable, AutoHotkey in fact stores a 64-bit integer. When you access the variable with &var or NumGet, or pass it to a command like MsgBox, a numeric string is computed and cached in the variable. Any subsequent access which needs a string will refer to this string, not the original number, which is also retained. &var and NumGet will only let you examine the string, for backward-compatibility reasons. Using Ord() does not prove anything, because Ord expects a string, and will attempt to convert whatever value you give it to a string in order to carry out its purpose.

For more details, see Concepts - Caching.

This is a little different in v2, where the caching behaviour has been changed to preserve the original type of the value, &var has been replaced with StrPtr(var), and NumGet doesn't refer to a variable's (string) content directly.

If you pass the result of (400 & 0xFFFFFFFF) | (500 << 32) directly to an int64 parameter for WindowFromPoint, it will not be converted to (or stored as) a string.



As for passing POINT by value;

The target function doesn't know where the value came from; it only has the raw binary content of the stack or register. So for an 8-byte struct, if you compose a 64-bit integer which has the right raw binary value, it is sufficient to pass this number as "int64" because DllCall takes care of the details of passing an 8-byte value. Bitwise operators aren't the only way; you could prepare the struct with NumPut, then use NumGet(struct, "int64") to get the value to pass to DllCall.

For 32-bit, int64 parameters are pushed onto the stack, occupying 8 bytes instead of the usual 4 bytes per parameter. For 64-bit, passing int64 is essentially the same, but all smaller parameters are widened to 64-bit, and the first four parameters are copied into registers as well.

Passing the x and y coordinates as individual int parameters works for 32-bit because they are simply pushed onto the stack, right to left, 4 bytes at a time. This would not work with smaller types, because each parameter would be widened to 32-bit. It also would not work for x64 because each parameter (int) would be widened to 64-bit.

For larger structs, there's no simple way to target both 32-bit and 64-bit with a single DllCall expression, because DllCall doesn't support passing values larger than int64. You would need to break the struct into individual int64 or int/uint parameters on 32-bit, and pass a single ptr on 64-bit. Fortunately, functions which take structs larger than 8 bytes by value are fairly rare.
Structs and unions of size 8, 16, 32, or 64 bits, and __m64 types, are passed as if they were integers of the same size. Structs or unions of other sizes are passed as a pointer to memory allocated by the caller.
Source: x64 calling convention | Microsoft Docs
(There are other 32-bit and 64-bit platforms where some of the above may not apply; I'm referring only to the x86 and x86-64 platforms where AutoHotkey runs. I have no idea about ARM64...)

teadrinker
Posts: 4295
Joined: 29 Mar 2015, 09:41
Contact:

Re: Get Window Title at Specific Coordinates

Post by teadrinker » 20 Jun 2021, 16:18

@lexikos, thanks for clarification.

User avatar
Avtem
Posts: 43
Joined: 01 Jun 2021, 02:20

Re: Get Window Title at Specific Coordinates

Post by Avtem » 22 Jun 2021, 04:31

People, come on! Why do you complicate all this? There is a two-line solution to the problem (although, be aware that you need to have a sufficient variable size to store the title).

Code: Select all

varSetCapacity(title, 200, 0)
DllCall("GetWindowText", "ptr", DllCall("WindowFromPoint", "Int", 500, "Int", 500)
		, "str", title, "int", 199)	
msgbox %title%

teadrinker
Posts: 4295
Joined: 29 Mar 2015, 09:41
Contact:

Re: Get Window Title at Specific Coordinates

Post by teadrinker » 22 Jun 2021, 06:45

@Avtem
Your code doesn't work on 64 bit AHK. If you read the text above, you get why. :)

User avatar
Avtem
Posts: 43
Joined: 01 Jun 2021, 02:20

Re: Get Window Title at Specific Coordinates

Post by Avtem » 22 Jun 2021, 07:18

teadrinker wrote:
22 Jun 2021, 06:45
@Avtem
Your code doesn't work on 64 bit AHK. If you read the text above, you get why. :)
Hm, i think i'm running 64 bit version AHK (see the screenshot). Did you try to run my code?
Attachments
My version of ahk.png
My version of ahk.png (15.53 KiB) Viewed 1921 times

teadrinker
Posts: 4295
Joined: 29 Mar 2015, 09:41
Contact:

Re: Get Window Title at Specific Coordinates

Post by teadrinker » 22 Jun 2021, 08:40

Try this:

Code: Select all

Gui, New, -Caption +Border
Gui, Margin, 0, 0
Gui, Font, s24
Gui, Add, Edit,, This text must be shown
Gui, Show, x497 y497
varSetCapacity(title, 200, 0)
DllCall("GetWindowText", "ptr", DllCall("WindowFromPoint", "Int", 500, "Int", 500)
      , "str", title, "int", 199)	
msgbox %title%
ExitApp
What the text the message box shows?

User avatar
emrekarahan0001
Posts: 25
Joined: 18 Jan 2021, 14:19

Re: Get Window Title at Specific Coordinates

Post by emrekarahan0001 » 22 Jun 2021, 08:46

Avtem wrote:
teadrinker wrote:
22 Jun 2021, 06:45
@Avtem
Your code doesn't work on 64 bit AHK. If you read the text above, you get why. :)
Hm, i think i'm running 64 bit version AHK (see the screenshot). Did you try to run my code?
me too running 64 bit version AHK and no problem. :thumbup:

teadrinker
Posts: 4295
Joined: 29 Mar 2015, 09:41
Contact:

Re: Get Window Title at Specific Coordinates

Post by teadrinker » 22 Jun 2021, 09:04

@emrekarahan0001
Did you try my code above?

teadrinker
Posts: 4295
Joined: 29 Mar 2015, 09:41
Contact:

Re: Get Window Title at Specific Coordinates

Post by teadrinker » 22 Jun 2021, 09:28

emrekarahan0001 wrote: me too running 64 bit version AHK and no problem
Looks like there was a problem. :)

User avatar
emrekarahan0001
Posts: 25
Joined: 18 Jan 2021, 14:19

Re: Get Window Title at Specific Coordinates

Post by emrekarahan0001 » 22 Jun 2021, 10:14

teadrinker wrote:
22 Jun 2021, 09:04
@emrekarahan0001
Did you try my code above?
Yes and your code working too :thumbup:

teadrinker
Posts: 4295
Joined: 29 Mar 2015, 09:41
Contact:

Re: Get Window Title at Specific Coordinates

Post by teadrinker » 22 Jun 2021, 10:27

Are you sure you launch it on 64 bit? This code can't show you "This text must be shown" with 64 bit AHK.

User avatar
emrekarahan0001
Posts: 25
Joined: 18 Jan 2021, 14:19

Re: Get Window Title at Specific Coordinates

Post by emrekarahan0001 » 22 Jun 2021, 10:37

teadrinker wrote:
22 Jun 2021, 09:28
emrekarahan0001 wrote: me too running 64 bit version AHK and no problem
Looks like there was a problem. :)
yes i have a problem, but i don't know how can i explain, This is my code, if Title Turkish or English, first check which one, and then wait the true title for work
:facepalm:

Code: Select all

^z::
varSetCapacity(title, 200, 0)
DllCall("GetWindowText", "ptr", DllCall("WindowFromPoint", "Int", 500, "Int", 500)
      , "str", title, "int", 199)

   	if title = Home / Twitter - Google Chrome
   	{
   	Msgbox, English
	gosub, En
   	}
	else 
	{
	WinWait, Home / Twitter - Google Chrome
	}

   	if title = Anasayfa / Twitter - Google Chrome
   	{
   	Msgbox, Turkish
	gosub, Tr
   	}
	else 
	{
	WinWait, Anasayfa / Twitter - Google Chrome
	}

En:
   	Msgbox, Hello World
Return

Tr:
   	Msgbox, Merhaba Dünya
Return

User avatar
emrekarahan0001
Posts: 25
Joined: 18 Jan 2021, 14:19

Re: Get Window Title at Specific Coordinates

Post by emrekarahan0001 » 22 Jun 2021, 10:53

Image
teadrinker wrote:
22 Jun 2021, 10:27
Are you sure you launch it on 64 bit? This code can't show you "This text must be shown" with 64 bit AHK.

teadrinker
Posts: 4295
Joined: 29 Mar 2015, 09:41
Contact:

Re: Get Window Title at Specific Coordinates

Post by teadrinker » 22 Jun 2021, 11:16

emrekarahan0001 wrote: WinWait, Anasayfa / Twitter - Google Chrome
As I see, you are trying to get the title from the browser. Most likely, it is open in full screen. Your code really gets the title of the window from coords 500, 0.
But what my code shows in its message box?

User avatar
emrekarahan0001
Posts: 25
Joined: 18 Jan 2021, 14:19

Re: Get Window Title at Specific Coordinates

Post by emrekarahan0001 » 22 Jun 2021, 11:34

teadrinker wrote:
22 Jun 2021, 11:16
emrekarahan0001 wrote: WinWait, Anasayfa / Twitter - Google Chrome
As I see, you are trying to get the title from the browser. Most likely, it is open in full screen. Your code really gets the title of the window from coords 500, 0.
But what my code shows in its message box?
if title "Anasayfa / Twitter - Google Chrome"

Code: Select all

"WinWait, "Home" / Twitter - Google Chrome"
waiting....

User avatar
emrekarahan0001
Posts: 25
Joined: 18 Jan 2021, 14:19

Re: Get Window Title at Specific Coordinates

Post by emrekarahan0001 » 22 Jun 2021, 11:41

by the way, i dont need this

Code: Select all

^z::
varSetCapacity(title, 200, 0)
DllCall("GetWindowText", "ptr", DllCall("WindowFromPoint", "Int", 500, "Int", 500)
      , "str", title, "int", 199)

   	if title = Home / Twitter - Google Chrome
   	{
   	Msgbox, English
	gosub, En
   	}
	else if title = Anasayfa / Twitter - Google Chrome
	{
   	Msgbox, Turkish
	gosub, Tr
	}

En:
   	Msgbox, Hello World
Return

Tr:
   	Msgbox, Merhaba Dünya
Return

Post Reply

Return to “Ask for Help (v1)”