How to make Cross-Hair overlay click-through?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
Xennon
Posts: 12
Joined: 12 Oct 2014, 19:27

How to make Cross-Hair overlay click-through?

30 Sep 2017, 05:09

I'm using the SplashImage command to overlay an image on top of a game screen so as to have a better crosshair shown instead of the game's single white dot.

The image i made for the crosshair is completely 100% magenta in color except for the crosshair I want to see in-game. I set the magenta color as the transparent color and everything works perfectly except occasionally while playing the game, I get an error sound and the game screen loses focus and I need to quickly click back on the game window to resume playing.

I think the reason for this "error" is that the mouse clicks on one of the pixels in the crosshair overlay and it confuses the game or windows or both. The game uses the usual approach of having the game crosshair in the center of the screen at all times regardless of where you look and the camera just changes you point of view.

So, my question is - How can I make sure that mouse clicks go through my overlay crosshair image directly to the game window below?

Using SplashImage seems to be the easiest (for me at least) to understand, the GUI functions seem more complicated to do what I need and I don't fully understand how to use them effectively.
A_AhkUser
Posts: 1147
Joined: 06 Mar 2017, 16:18
Location: France
Contact:

Re: How to make Cross-Hair overlay click-through?

30 Sep 2017, 05:49

Hi,

A top-level window created with the WS_EX_NOACTIVATE style does not become the foreground window when the user clicks it. You'll find below an example with notepad.

Code: Select all

#NoEnv
; #Warn
#SingleInstance force


WS_EX_NOACTIVATE := "E0x08000000"

WinWait, ahk_exe notepad.exe ; with notepad for the example
WinGet, ID, ID, ahk_exe notepad.exe ; retrieves notepad ID
global AHKID := "ahk_id " . ID
WinGet, PID, PID, % AHKID ; retrieves notepad process ID (PID)

GUI, 2:-Caption +AlwaysOnTop +Owner +hwndID +%WS_EX_NOACTIVATE%
GUI, 2:Color, Red, Red
GUI, 2:Show, w10 h10,

EVENT_OBJECT_LOCATIONCHANGE := 0x800B ; https://msdn.microsoft.com/en-us/library/windows/desktop/dd318066(v=vs.85).aspx
hWinEventHook := SetWinEventHook(EVENT_OBJECT_LOCATIONCHANGE
				, EVENT_OBJECT_LOCATIONCHANGE
				, 0
				, RegisterCallback("OnLocationChange")
				, PID
				, 0
				, 0) ; https://msdn.microsoft.com/en-us/library/windows/desktop/dd373640(v=vs.85).aspx
; set OnLocationChange as callback function for the event OBJECT_LOCATIONCHANGE (https://msdn.microsoft.com/en-us/library/windows/desktop/dd318066(v=vs.85).aspx#EVENT_OBJECT_LOCATIONCHANGE)
OnExit, exitSub ; specifies a subroutine or function to run automatically when the script exits
SetTimer, waitClose, -1
return ; end of the auto-execute section


waitClose:
exitSub:
WinWaitClose, ahk_exe notepad.exe
UnhookWinEvent(hWinEventHook)
ExitApp

; ------------------------------------------------------------------------------------

onLocationChange(__hWinEventHook, __event, __hwnd) {

	if not (__hwnd) ; if this isn't the window itself (and not the cursor for example) that triggered the EVENT_OBJECT_LOCATIONCHANGE
return
; otherwise...
SetWinDelay, -1 ; make the movement smoother

	WinGetPos, __x, __y, __w, __h, % AHKID
	GUI, 2:Show, % "NA x" . (__x+__w//2)-5 . " y" . (__y+__h//2)-5

}

; =====================================================

SetWinEventHook(__eventMin, __eventMax, __hmodWinEventProc, __lpfnWinEventProc, __idProcess, __idThread, __dwFlags) {
   DllCall("CoInitialize", "Uint", 0)
   return DllCall("SetWinEventHook"
			, "Uint", __eventMin
			, "Uint", __eventMax
			, "Ptr", __hmodWinEventProc
			, "Ptr", __lpfnWinEventProc
			, "Uint", __idProcess
			, "Uint", __idThread
			, "Uint", __dwFlags)
} ; https://autohotkey.com/boards/viewtopic.php?t=830
UnhookWinEvent(__hWinEventHook) {
    __v := DllCall("UnhookWinEvent", "Ptr", __hWinEventHook)
    DllCall("CoUninitialize")
return __v
} ; https://autohotkey.com/boards/viewtopic.php?t=830

Hope this helps.
my scripts
User avatar
boiler
Posts: 17106
Joined: 21 Dec 2014, 02:44

Re: How to make Cross-Hair overlay click-through?

30 Sep 2017, 09:39

You might want to add something so that when this occurs, your click doesn't just get absorbed by the cross-hair and does not get sent to your game window. Have your script detect when your Gui (the cross-hair) gets clicked on, then you can send a click to the intended window on that spot. You can try ControlClick to send it directly to that window under the cross-hair, or if that doesn't work, temporarily hide the cross-hair Gui and use the regular Click command.
User avatar
Exaskryz
Posts: 2882
Joined: 17 Oct 2015, 20:28

Re: How to make Cross-Hair overlay click-through?

30 Sep 2017, 14:37

This is what I use on a full-screen GUI to give a clickthrough and keep it overtop any window. I'd imagine this would work for a crosshair GUI; I use it just as a way to further darken my screen with a shade of gray fullscreen GUI.

Gui, +LastFound +AlwaysOnTop -Caption +E0x20 ; Click through GUI always on top.

Edit 2: Actually, SplashImage should be able to get the benefits of the ExStyle +E0x20 using WinSet. WinSet, ExStyle, +0x20, WinTitle should work, replacing WinTitle with the program name for the SplashImage (I guess that'd be your AHK script name? Haven't done SplashImage in a long time.)

Edit: You mentioned you're using SplashImage. Play a little bit with Gui, Picture control and use the line above which should make your GUI basically a borderless overlay. I'm whipping up a nice crosshair for myself as a demo.

Code: Select all

^1::
Gui, Color, 0xFFFF00
Gui, Add, Picture, ,crosshair.png ; dimensions of 41x41
Gui, +LastFound +AlwaysOnTop -Caption +E0x20 ; Click through GUI always on top.
WinSet, TransColor, 0xFFFF00
Gui, Show, % "x" A_ScreenWidth/2-21 " y" A_ScreenHeight/2-21 ; this centers it on screen, or at least what should be the center. Might be off by a pixel or two in either axis in any direction.
return
Here's some images of it in action, and the image itself:

https://imgur.com/a/3YHRX -- the third image in the album is the crosshair itself, but it doesn't show well on imgur's album page because of their black background; here's a direct link that shouldn't have the black background (may vary depending on browser settings): https://i.imgur.com/Hdpr42M.png

The yellowness I imagine is because of the TransColor being for a single color, but my original image had varying transparency. If anyone knows how to make it just the black with gradient, that would be cool to know; I'm sure there's an answer out there. Otherwise just a fully opaque crosshair on a transparent background in your image editor should do.
User avatar
Xennon
Posts: 12
Joined: 12 Oct 2014, 19:27

Re: How to make Cross-Hair overlay click-through?

01 Oct 2017, 02:27

Exaskryz wrote: Edit 2: Actually, SplashImage should be able to get the benefits of the ExStyle +E0x20 using WinSet. WinSet, ExStyle, +0x20, WinTitle should work, replacing WinTitle with the program name for the SplashImage (I guess that'd be your AHK script name? Haven't done SplashImage in a long time.)
Can you explain what the "+E0x20" means and maybe point me to a reference showing the possible values and their meaing?

I added the ExStyle to the WinSet command as well as the "+E0x20" and I noticed that when the game cursor moves over a solid pixel in the crosshair, the cursor changes to the normal Windows cursor which implies that the splashimage is going to receive any click that I might make. However, if is change the "+E0x20" to "+0x20" (drop the "E"), the cursor does not change to the windows cursor if moved over a solid pixel in the crosshair. Weird!

This is the splashimage code I'm using:

Code: Select all

	SplashCrossHairs:
	SplashImage, 5:off
	if (ShowCrossHairs)
	{
		if(CrossHairVersion==1)
		{
			SplashImage, 5:CrossHairs1.png, B X0 Y0 ; User version 1 of crosshairs
		}
		else 
			SplashImage, 5:CrossHairs2.png, B X0 Y0 ; User version 2 of crosshairs
		
		WinSet, TransColor, FF00FF, ahk_exe AutoHotKey.exe 
		WinSet, ExStyle, +0x20, ahk_exe AutoHotKey.exe
		WinSet, AlwaysOnTop
	}
	else
		SplashImage, 5:off
return
So far everything seems to work exactly as before and due to the "problem" being intermittent I cannot actually test if I still have the same trouble as before. I'll just have to wait and see if it happens again.

I tried the Gui approach, but failed miserably, and the overlay crosshair image didn't appear at all except for a tiny magenta region in the top left corner and given that the overlay image is the same size at the game window (1920x1080), that clearly wasn't right. It also triggered a new taskbar button which i assume represented the Gui window. I read up on Gui in the help file and only managed to give myself a migraine trying to understand it - I remember getting a headache reading about SplashImage as well when I first wrote the script.

In any case, many thanks for your reply - it seems it may work, or if not, at least it didn't break what I already had. If i ever feel brave enough, i might revisit the idea at a later date.
User avatar
Exaskryz
Posts: 2882
Joined: 17 Oct 2015, 20:28

Re: How to make Cross-Hair overlay click-through?

01 Oct 2017, 12:34

Xennon wrote:
Exaskryz wrote: Edit 2: Actually, SplashImage should be able to get the benefits of the ExStyle +E0x20 using WinSet. WinSet, ExStyle, +0x20, WinTitle should work, replacing WinTitle with the program name for the SplashImage (I guess that'd be your AHK script name? Haven't done SplashImage in a long time.)
Can you explain what the "+E0x20" means and maybe point me to a reference showing the possible values and their meaning?
I don't know where I found the 0x20 value, but it was years ago, probably on the old AHK forums. But there should be resources somewhere as this is part of Windows native functionality most languages can use on googling.
Xennon wrote: I added the ExStyle to the WinSet command as well as the "+E0x20" and I noticed that when the game cursor moves over a solid pixel in the crosshair, the cursor changes to the normal Windows cursor which implies that the splashimage is going to receive any click that I might make. However, if is change the "+E0x20" to "+0x20" (drop the "E"), the cursor does not change to the windows cursor if moved over a solid pixel in the crosshair. Weird!
The E should only be used in the GUI actually, as the E specifies ExStyle. But in WinSet, you already specified ExStyle, so you use +0x20 without the E.

Hopefully the SplashImage works for you. I would expect the GUI code I gave exactly as is should work (if you have a crosshair.png in the same folder as your script), but maybe I missed something that was included in the rest of my testing script. It could be an AHK version issue -- make sure you have the latest (1.1.26.01) by using MsgBox %A_AhkVersion%.
User avatar
Xennon
Posts: 12
Joined: 12 Oct 2014, 19:27

Re: How to make Cross-Hair overlay click-through?

01 Oct 2017, 19:47

Exaskryz wrote: Hopefully the SplashImage works for you. I would expect the GUI code I gave exactly as is should work (if you have a crosshair.png in the same folder as your script), but maybe I missed something that was included in the rest of my testing script. It could be an AHK version issue -- make sure you have the latest (1.1.26.01) by using MsgBox %A_AhkVersion%.
Thanks for the reminder regarding the version - My version was 1.1.23 so a little out dated. I've not tried your code since updating but with some luck, the added WinSet changes might make it work now. Can't think of any way to trigger the problem for testing, but if it's still broken it'll show up eventually in which case I'll revisit the whole approach and start from scratch if necessary. (actually - i just thought of a way to test it by making the crosshair image more "solid" and see if that breaks the code)
User avatar
FanaticGuru
Posts: 1907
Joined: 30 Sep 2013, 22:25

Re: How to make Cross-Hair overlay click-through?

02 Oct 2017, 02:43

Here is a link to a version that seems to work well.
https://autohotkey.com/boards/viewtopic.php?t=29256

Shows how to make the png fade in and out.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
User avatar
Exaskryz
Posts: 2882
Joined: 17 Oct 2015, 20:28

Re: How to make Cross-Hair overlay click-through?

02 Oct 2017, 13:01

I just wanted to give an update to this thread because it came out handy. For whatever reason when waking my computer from hibernation today, I Don't have a mouse cursor. So I thought of this script, got it into action. (I had a backup crosshair that was full width and full height of the screen to use a guide markers when using SnippingTool, but it didn't have the clickthrough setting). I changed it so the crosshair moves with my mouse instead of locked into center of the screen.

A few minutes into this testing I haven't encountered an issue with clicks not registering or focus jumping back to the crosshair GUI (And I do see it has a taskbar button like you mentioned @Xennon).

Code: Select all

^1::
CoordMode, Mouse, Screen
If (ch2toggle:=!ch2toggle)
{
Gui, ch:new
Gui, ch:Default
Gui, Color, 0xFFFF00
Gui, Add, Picture, ,crosshair.png ; dimensions of 41x41
Gui, +LastFound +AlwaysOnTop -Caption +E0x20 ; Click through GUI always on top.
WinSet, TransColor, 0xFFFF00
Gui, Show, % "x" A_ScreenWidth/2-21 " y" A_ScreenHeight/2-21, Crosshair ; this centers it on screen, or at least what should be the center. Might be off by a pixel or two in either axis in any direction.
SetTimer, UpdateCrossHair, 50
}
else
{
SetTimer, UpdateCrossHair, Off
Gui, ch:destroy
}
return

UpdateCrossHair:
DetectHiddenWindows, On
MouseGetPos, X, Y
WinMove, Crosshair, ,% X-31,% Y-28 ; it's not a perfect -21 for some reason. Probably hidden window border shenanigans. I used tooltip to report X/Y coordinates to me and then calibrated for a 0,0 reported when the crosshair visually appeared in the top left corner
return

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Beorn, BPet, peter_ahk, whoops, Yincognito and 227 guests