Get Window Title at Specific Coordinates
-
- Posts: 864
- Joined: 21 Dec 2015, 02:34
Get Window Title at Specific Coordinates
Hi
Let's say I want to get the window title at x500, y500.
Is there an easy way to do this?
Rest assured I've spent all morning trying to find the solution but to no avail
Let's say I want to get the window title at x500, y500.
Is there an easy way to do this?
Rest assured I've spent all morning trying to find the solution but to no avail
Re: Get Window Title at Specific Coordinates
msdn WindowFromPoint
-
- Posts: 864
- Joined: 21 Dec 2015, 02:34
Re: Get Window Title at Specific Coordinates
this line activates the window at 500, 500
I tried adjusting the line to get the window title, but this doesn't work:
Code: Select all
WinActivate, % "ahk_id" DllCall("WindowFromPoint", Int,500, Int,500 )
Code: Select all
wingettitle, title, % "ahk_id" DllCall("WindowFromPoint", Int,500, Int,500 )
msgbox, %title%
-
- Posts: 864
- Joined: 21 Dec 2015, 02:34
Re: Get Window Title at Specific Coordinates
actually I guess I could just do this:
Code: Select all
WinActivate, % "ahk_id" DllCall("WindowFromPoint", Int,500, Int,500 )
wingettitle, title, A
msgbox, %title%
Re: Get Window Title at Specific Coordinates
i ain't sure if u can actually call this function this way
i think u need to declare a var and numput the coordinates in it but I cant test it rn
i think u need to declare a var and numput the coordinates in it but I cant test it rn
-
- Posts: 864
- Joined: 21 Dec 2015, 02:34
Re: Get Window Title at Specific Coordinates
winactivate works, but not wingettitle. I'd like to do it all on that one line. I will keep trying
-
- Posts: 4565
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Get Window Title at Specific Coordinates
Code: Select all
x := 500
y := 500
$F1::
hWnd := DllCall("WindowFromPoint", UInt64, x|(y << 32), Ptr)
hParent := DllCall("GetAncestor", Ptr, hWnd, UInt, GA_ROOT := 2, Ptr)
WinGetTitle, title, ahk_id %hParent%
MsgBox, % title
Return
-
- Posts: 864
- Joined: 21 Dec 2015, 02:34
Re: Get Window Title at Specific Coordinates
thanks teadrinker, that seems to do the trick!
Re: Get Window Title at Specific Coordinates
@anyone using DllCall: Just FYI, this change has been made to AHK v2:
AutoHotkey v2 alpha (UPDATES) - Page 3 - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=37&t=2120&p=275703#p275703
DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=31365
AutoHotkey v2 alpha (UPDATES) - Page 3 - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=37&t=2120&p=275703#p275703
I'll update this script at some point:Disabled unquoted arg and return types for DllCall.
DllCall converter/cleaner (e.g. x32 to x64/x32 two-way compatible) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=31365
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: Get Window Title at Specific Coordinates
@teadrinker
https://blogs.msdn.microsoft.com/oldnewthing/20101230-00/?p=11873/
last paragraph
and x seems to break on negative coords if u dont mask it off
that aside, these functions behave very weirdly. its says it accepts a POINT BY VALUE, what?? but i tried
but it didnt work. it only checked (0, 0) on my 2 monitor (-1920, 1920) setup, which is the topleft corner of my rhs main monitor
https://blogs.msdn.microsoft.com/oldnewthing/20101230-00/?p=11873/
last paragraph
Code: Select all
x := y := 500
CWP_ALL := 0x0000
CWP_SKIPINVISIBLE := 0x0001
CWP_SKIPDISABLED := 0x0002
CWP_SKIPTRANSPARENT := 0x0004
hwnd := DllCall("ChildWindowFromPointEx"
, "Ptr", DllCall("GetDesktopWindow", "Ptr")
, "UInt64", (x & 0xFFFFFFFF) | (y << 32)
, "UInt", CWP_SKIPINVISIBLE | CWP_SKIPDISABLED | CWP_SKIPTRANSPARENT
, "Ptr")
that aside, these functions behave very weirdly. its says it accepts a POINT BY VALUE, what?? but i tried
Code: Select all
VarSetCapacity(P, 8, 0)
NumPut(500, &P, 0, "Int")
NumPut(500, &P, 4, "Int")
; ... and passing it BY VALUE
, "Ptr", P
-
- Posts: 4565
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Get Window Title at Specific Coordinates
I would prefer to tell the script "what" to do, rather than "how", if this does not affect performance. The code with WindowFromPoint() and GetAncestor(GA_ROOT) looks more clear.
Compare the following two winapi functions:swagfag wrote:these functions behave very weirdly
WindowFromPoint:
GetCursorPos:HWND WindowFromPoint(
POINT Point
);
In the last case you need using VarSetCapacity.BOOL GetCursorPos(
LPPOINT lpPoint
);
Re: Get Window Title at Specific Coordinates
if it wants a pointer, u do:
so then, if it wants the struct itself, by value, u should be able to do:
except it doesnt work in this case
Code: Select all
VarSetCapacity(P, 8, 0)
NumPut(500, &P, 0, "Int")
NumPut(500, &P, 4, "Int")
; ...
, "Ptr", &P
Code: Select all
VarSetCapacity(P, 8, 0)
NumPut(500, &P, 0, "Int")
NumPut(500, &P, 4, "Int")
; ...
, "Ptr", P
-
- Posts: 4565
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Get Window Title at Specific Coordinates
Compare:
and
In this case
POINT is just a string.
Code: Select all
x := 500
y := 500
POINT := x|(y << 32)
MsgBox, % Format("{:#x}", POINT)
Code: Select all
x := 500
y := 500
VarSetCapacity(POINT, 8, 0)
NumPut(x, POINT, "Int")
NumPut(y, POINT, 4, "Int")
MsgBox, % POINT
You do not consider AHK syntax.u should be able to do
In this case
Code: Select all
x := 500
y := 500
POINT := x|(y << 32)
hWnd := DllCall("WindowFromPoint", UInt64, POINT, Ptr)
MsgBox, % Format("{:#x}", hWnd)
Re: Get Window Title at Specific Coordinates
tbh i have no clue what ure trying to convey here. u cant msgbox POINT(the struct, ie VarSetCapacity). yeah, so?
imagine u were writing this in c++:
so why then, do u have to do exactly what ure not supposed to do (ie the bitshifting stuff) in AHK for it to work properly
imagine u were writing this in c++:
Code: Select all
#include <iostream>
struct POINT {
long x;
long y;
};
void myWindowFromPoint(POINT P) {
std::cout << P.x << "," << P.y << "\n";
}
int main() {
POINT P = { 500, 500 };
myWindowFromPoint(P); // <<<<<<<<<<<<<<< here, u pass P BY VALUE, aka in AHK should be DllCall("WindowFromPoint", "Ptr", P, "Ptr") (NOT &P !!), where P is initialized with VarSetCapacity and filled with NumPut
// what u DONT do is this
// V
// myWindowFromPoint((400 & 0xFFFFFFFF) | (500 << 32)); which would end up being DllCall("WindowFromPoint", "UInt64", (x & 0xFFFFFFFF) | (y << 32), "Ptr") in AHK, for whatever reason apparently
return 0;
}
Last edited by swagfag on 10 May 2019, 17:27, edited 2 times in total.
-
- Posts: 4565
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Get Window Title at Specific Coordinates
But we writing this not in c++, we use AHK. In this case WindowFromPoint expects the numeric value, and DllCall accepts that value as a string.imagine u were writing this in c++
Re: Get Window Title at Specific Coordinates
- The definition specifies a struct, not a pointer to a struct,
- If it wanted a pointer to a struct, you could use VarSetCapacity and NumPut, and pass the address.
- In this case, you must pass an 8-byte integer directly as a value.
- You can form that 8-byte integer by using bitshift and bitwise-or on the x/y values. Alternatively, a MakeUInt64 function would be useful.
- This situation is rare, and so I mention it explicitly, as 'Point' functions, here:
jeeswg's DllCall and structs tutorial - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=7&t=63708
- (It appears that for 32-bit dll calls, you could pass 2 Ints, instead of 1 UInt64, but this doesn't work for 64-bit.)
- If it wanted a pointer to a struct, you could use VarSetCapacity and NumPut, and pass the address.
- In this case, you must pass an 8-byte integer directly as a value.
- You can form that 8-byte integer by using bitshift and bitwise-or on the x/y values. Alternatively, a MakeUInt64 function would be useful.
- This situation is rare, and so I mention it explicitly, as 'Point' functions, here:
jeeswg's DllCall and structs tutorial - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=7&t=63708
- (It appears that for 32-bit dll calls, you could pass 2 Ints, instead of 1 UInt64, but this doesn't work for 64-bit.)
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: Get Window Title at Specific Coordinates
but why? how does it expect a numeric value? it expects a POINT. a POINT is:WindowFromPoint expects the numeric value
Code: Select all
typedef struct tagPOINT
{
LONG x;
LONG y;
} POINT, *PPOINT, NEAR *NPPOINT, FAR *LPPOINT;
what it certainly isnt, is ONE UNsigned 64bit integer. so why then does AHK have to pass that for it to work properly. theres no method to this madness, whatsoever!
im not sold on the string thing. u can just as easily do
Code: Select all
hWnd := DllCall("WindowFromPoint", "UInt64", (400 & 0xFFFFFFFF) | (500 << 32), "Ptr")
MsgBox, % Format("{:#x}", hWnd)
@jeeswg
jesus christIt appears that for 32-bit dll calls, you could pass 2 Ints, instead of 1 UInt64
these functions just keep getting weirder still
-
- Posts: 4565
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Get Window Title at Specific Coordinates
What were passing IS a string. Look:swagfag wrote: ↑and it will work. here what were passing is decidedly not a stringCode: Select all
hWnd := DllCall("WindowFromPoint", "UInt64", (400 & 0xFFFFFFFF) | (500 << 32), "Ptr") MsgBox, % Format("{:#x}", hWnd)
Code: Select all
MsgBox, % (400 & 0xFFFFFFFF) | (500 << 32) " — it's just a string"
Ok, it expects a POINT, AHK accepts a string, interprets it as Int64 numeric value, then passes this value to WindowFromPoint, WindowFromPoint interprets the value as POINT, which was expected.
Re: Get Window Title at Specific Coordinates
Code: Select all
MsgBox, % (400 & 0xFFFFFFFF) | (500 << 32) " — it's just a string"
im not sure whether DllCall's Arg1, 2, ..., N are universally treated as strings, or if it depends on the type specified preceding it. the docs dont say, i dont think
yes, so far it is clear that WindowFromPoint treats the number(or number-like string) as a POINT struct passed by value.WindowFromPoint interprets the value as POINT, which was expected.
what isnt clear is why its doing it and how its doing it.
https://jeffpar.github.io/kbarchive/kb/138/Q138518/
the relevant section
so then how does a 64bit int that looks like this 0xYYYYYYYYXXXXXXXX, get converted to a struct with 2 32bit ints in it, correctly. what exactly happens during this conversion?also im curious if there are any winapi function function that take in, say, a RECT by value, or some other larger-than-64 struct. if so, then u couldnt possibly make the bitshift thing work in that case, so how then would u make it work(assuming the existence of such functions)
Re: Get Window Title at Specific Coordinates
@swagfag: If you look at the MessageBox Winapi function, it expects HWND and LPCTSTR, which are 8 or 4 byte numbers in x64/x32, and UINT, which is a 4-byte number. POINT is just an 8-byte number, the fact that it's a 'struct', or is composed of 2 4-byte numbers, doesn't matter.
I have only seen one Winapi function that asks to pass a number by value, where the value's size is greater than 8 bytes, it is MagSetWindowSource, and it expects a 16-byte RECT. In x32 I split the RECT as 4 Ints, in x64 I pass the address.
MagSetWindowSource is mentioned here:
jeeswg's DllCall and structs tutorial - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=7&t=63708
x64 calling convention | Microsoft Docs
https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=vs-2017
Re. DllCall and strings. E.g. to pass UInt64 0xFFFFFFFFFFFFFFFF to DllCall, use the Int64: -1, or a string: "18446744073709551615" or "0xFFFFFFFFFFFFFFFF" or "-1".
DllCall() - Syntax & Usage | AutoHotkey
https://autohotkey.com/docs/commands/DllCall.htm
I have only seen one Winapi function that asks to pass a number by value, where the value's size is greater than 8 bytes, it is MagSetWindowSource, and it expects a 16-byte RECT. In x32 I split the RECT as 4 Ints, in x64 I pass the address.
MagSetWindowSource is mentioned here:
jeeswg's DllCall and structs tutorial - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=7&t=63708
x64 calling convention | Microsoft Docs
https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=vs-2017
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.
Re. DllCall and strings. E.g. to pass UInt64 0xFFFFFFFFFFFFFFFF to DllCall, use the Int64: -1, or a string: "18446744073709551615" or "0xFFFFFFFFFFFFFFFF" or "-1".
DllCall() - Syntax & Usage | AutoHotkey
https://autohotkey.com/docs/commands/DllCall.htm
For parameters of type UInt64, large unsigned values may be passed as strings.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA