Gui buttons (can't double click)

Ask gaming related questions (AHK v1.1 and older)
User avatar
Shoobis
Posts: 3
Joined: 15 Apr 2023, 15:51

Gui buttons (can't double click)

Post by Shoobis » 16 Apr 2024, 16:57

Hello guys,
I've been trying to do a multipurpose On-Screen micro keyboard, pad or gamepad, but I'm stuck at the final steps as my attempts lack the desired results.

My ideal or goal is to make the buttons behave like the buttons in the integrated Windows OSK as much as possible, but with a flexible layout that it can be from 1-3 buttons to a full gamepad. As a person with limited mobility due a motor disability this kind of projects helps me greatly. :dance:

Version A

Code: Select all

#NoEnv
#SingleInstance force

SetKeyDelay, 20, 10
SetMouseDelay, 10
SetBatchLines,-1

; Set the size of the gamepad
Width := 355
Height := 180

; Gamepad variables
global btnPressed = ""
global btnList := {ButtonA: "a", ButtonB: "b", ButtonC: "c", ButtonX: "x", ButtonY: "y", ButtonZ: "z", ButtonM: "q", ButtonN: "space", ButtonO: "e", ButtonTL: "e", ButtonTR: "r", ButtonStart: "enter", ButtonSelect: "backspace", ButtonKU: "Up", ButtonKD: "Down", ButtonKL: "Left", ButtonKR: "Right"}

; Create the GUI for the gamepad
Gui, +LastFound +AlwaysOnTop +ToolWindow +Border +E0x08000000
Gui, Color, FEFEFE +LastFound
; WinSet, TransColor, FEFEFE 220

Gui, Add, Button, x200 y60 w40 h40 gCtrlEvent vButtonA, A
Gui, Add, Button, x242 y30 w40 h40 gCtrlEvent vButtonB, B
Gui, Add, Button, x284 y60 w40 h40 gCtrlEvent vButtonC, C

Gui, Add, Button, x200 y102 w40 h40 gCtrlEvent vButtonX, X
Gui, Add, Button, x242 y72 w40 h40 gCtrlEvent vButtonY, Y
Gui, Add, Button, x284 y102 w40 h40 gCtrlEvent vButtonZ, Z

Gui, Add, Button, x72 y30 w40 h40 gCtrlEvent vButtonKU, Up
Gui, Add, Button, x30 y50 w40 h40 gCtrlEvent vButtonKL, Left
Gui, Add, Button, x114 y50 w40 h40 gCtrlEvent vButtonKR, Right
Gui, Add, Button, x72 y72 w40 h40 gCtrlEvent vButtonKD, Down

Gui, Add, Button, x30 y100 w40 h40 gCtrlEvent vButtonSelect, Select
Gui, Add, Button, x114 y100 w40 h40 gCtrlEvent vButtonStart, Start

Gui, Show, x900 y320 w%Width% h%Height%

; I can't remember for what is this for
DllCall("SetClassLong","UInt",hWnd,"Int",-26,"UInt",0x8)

; They work but I can't trigger these fast
OnMessage(0x0202, "WM_LBUTTONUP")
OnMessage(0x201, "WM_LBUTTONDOWN")
return

Esc::ExitApp

WM_LBUTTONUP(wParam, lParam, msg, hwnd) {
	Send {blind}{%btnPressed% up}
}

WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) {
	btnVar := A_GuiControl
	btnPressed := btnList["" . btnVar]
	
	Send {blind}{%btnPressed% down}
}

; Just in case it would be needed
CtrlEvent(CtrlHwnd:=0, GuiEvent:="", EventInfo:="", ErrLvl:="") {
	GuiControlGet, controlName, Name, %CtrlHwnd%
}
This version works almost as intended, one can do even long presses or hold on any button, but It can't do fast clicks or double/triple clicks. I read once something related to OnMessage usage but I can't remember where I saw it. Also I don't know why it does strange things when clicked on the board (outside the buttons), is like pressing many buttons at once and random.

Version B

Code: Select all

#NoEnv
#SingleInstance force

SetKeyDelay, 20, 10
SetMouseDelay, 10
SetBatchLines,-1

; Set the size of the gamepad
Width := 440
Height := 200

; Gamepad variables
global btnPressed = ""
global btnList := {ButtonA: "z", ButtonB: "x", ButtonC: "c", ButtonX: "enter", ButtonY: "y", ButtonZ: "z", ButtonM: "q", ButtonN: "space", ButtonO: "e", ButtonTL: "e", ButtonTR: "r", ButtonStart: "enter", ButtonSelect: "backspace", ButtonKU: "Up", ButtonKD: "Down", ButtonKL: "Left", ButtonKR: "Right"}

; Create the GUI for the gamepad
Gui, +LastFound +AlwaysOnTop +ToolWindow +Border +E0x08000000
Gui, Color, FEFEFE +LastFound
; WinSet, TransColor, FEFEFE 220

Gui, Add, Text, 0x5 x10 y10 w205 h120 gCtrlEvent vButtonA cBlack, Button B
Gui, Add, Text, 0x5 x225 y10 w205 h120 gCtrlEvent vButtonB, Button A

Gui, Add, Text, 0x5 x135 y150 w80 h30 gCtrlEvent vButtonC, Select
Gui, Add, Text, 0x5 x225 y150 w80 h30 gCtrlEvent vButtonX, Start

Gui, Show, x1300 y400 w%Width% h%Height%

; I can't remember for what is this for
DllCall("SetClassLong","UInt",hWnd,"Int",-26,"UInt",0x8)

; They work but I can't trigger these fast
OnMessage(0x0202, "WM_LBUTTONUP")
OnMessage(0x201, "WM_LBUTTONDOWN")
return

Esc::ExitApp

; WM_LBUTTONUP(wParam, lParam, msg, hwnd) {
;	Send {blind}{%btnPressed% up}
; }

WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) {
	btnVar := A_GuiControl
	btnPressed := btnList["" . btnVar]
	
	Send {blind}{%btnPressed% down}
	KeyWait, LButton
	Send {blind}{%btnPressed% up}
}

; Just in case it would be needed
CtrlEvent(CtrlHwnd:=0, GuiEvent:="", EventInfo:="", ErrLvl:="") {
	GuiControlGet, controlName, Name, %CtrlHwnd%
}
In this version I tried to use text areas as buttons, fast clicks work a little better but it doesn't seem reliable. Aside that I don't know how to make the labels visible and centered. I've been using code from the forums, I'm sorry if I haven't given proper references as I didn't thought making it public, but if this work I would try to do it right as a script.

Thanks in advance!
User avatar
mikeyww
Posts: 28869
Joined: 09 Sep 2014, 18:38

Re: Gui buttons (can't double click)

Post by mikeyww » 18 Apr 2024, 07:43

Welcome to this AutoHotkey forum!

Ideas are below.

Code: Select all

#Requires AutoHotkey v1.1.33.11
Global ctl
Gui Font, s10
Gui Add, Button, w230, Test1
Gui Add, Button, wp  , Test2
Gui Show,, Buttons
OnMessage(0x201, "WM_LBUTTONDOWN")
OnMessage(0x202, "WM_LBUTTONUP")
Return

WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) {
 MouseGetPos,,,, ctl
 If !InStr(ctl, "Button")
  Return
 KeyWait LButton, T.4
 If ErrorLevel {
  ToolTip
  MsgBox 64, Status, % ctl "`n`nHeld!"
 }
}

WM_LBUTTONUP(wParam, lParam, msg, hwnd) {
 Static presses := 0
 If !InStr(ctl, "Button")
  Return
 presses++
 ToolTip % presses
 SetTimer Act, -400
 Return
 Act:
 ToolTip
 MsgBox 64, Status, % ctl "`n`nNumber of presses: " presses
 presses := 0
 Return
}
If you are new to AHK, I recommend using its current version, which is v2, instead of this older deprecated version that is no longer developed.
User avatar
Shoobis
Posts: 3
Joined: 15 Apr 2023, 15:51

Re: Gui buttons (can't double click)

Post by Shoobis » 19 Apr 2024, 22:44

You're the best Mikeyww! as always. Thank you very much.
I was able to find the way with your example and I even could use the little condition to see if I'm clicking the buttons only.

The solution was simple, I just added a DoubleClick listener and it was done, it even aids me to do faster clicks.

This is the working code sample, hoping it can help more people.

Code: Select all

#Requires AutoHotkey v1.1.33.11

Global ctl
Global btnPressed = ""
Global btnList := {ButtonA: "z", ButtonB: "x"}
	
; Create the GUI for the gamepad
Gui +LastFound +AlwaysOnTop +ToolWindow +Border +E0x08000000
Gui Color, FEFEFE +LastFound
Gui Font, s10
Gui Add, Button, w200 h60 vButtonA, Test1
Gui Add, Button, wp hp	  vButtonB, Test2
Gui Show, x1500 y320 w225 h145, Buttons

OnMessage(0x201, "WM_LBUTTONDOWN")
OnMessage(0x202, "WM_LBUTTONUP")
OnMessage(0x0203, "WM_LBUTTONDBLCLK") ; I didn't knew this existed!
Return

WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) {
	MouseGetPos,,,, ctl
	
	btnVar := A_GuiControl
	btnPressed := btnList["" . btnVar]
		
	If !InStr(ctl, "Button")
		Return
	
	Send {%btnPressed% down}
}

WM_LBUTTONUP(wParam, lParam, msg, hwnd) {
	Send {%btnPressed% up}
}

WM_LBUTTONDBLCLK() {
	Send {%btnPressed% down}
	Sleep 80
	Send {%btnPressed% up}
}

Esc::ExitApp
I'm relatively new in the forum but not using AHK.
I do still have some questions, can I use both AHK versions (v1 and v2) on the same Windows 10 account? if not, there's a place where I can look how to convert old code?
User avatar
mikeyww
Posts: 28869
Joined: 09 Sep 2014, 18:38

Re: Gui buttons (can't double click)

Post by mikeyww » 20 Apr 2024, 05:37

Good to hear!
  1. Yes, you can have both versions installed at the same time. This enables you to run a v1 script or a v2 script (any or all, at the same time). The syntax cannot be mixed within a single script.
  2. The documentation is always freely available to you.

    https://www.autohotkey.com/docs/v2/v2-changes.htm

    That site also names every v2 function. Many examples are included. One strategy for conversion is to find the v2 syntax for each of your v1 statements.
I don't think that your revised script actually works unless your intent is for the same key to be sent twice upon the double-click. If you examine the KeyHistory or use a MsgBox, you can see what is happening. Distinguishing single and double clicks typically entails waiting to see if a second click occurs after the first one. The distinction would matter only if you need different actions instead of sequential ones.
User avatar
Shoobis
Posts: 3
Joined: 15 Apr 2023, 15:51

Re: Gui buttons (can't double click)

Post by Shoobis » 22 Apr 2024, 21:07

That's awesome, thanks. I'm going to try to update and refine my currents scripts.

Yes, in fact it's more like a workaround than a real fix as it should've been, like a fallback, when I do a faster pressing and the regular Up listener doesn't catch that click the DoubleClick listener does it (doing one more click instead of nothing).

Currently is working great for mashing the hit buttons in retro games like Final Fight or TNMT Arcades games and still being able to do controlled jumps holding the jump button. It's responsive with one click, while holding it, and doing fast clicks, that twice even helps me as sometimes I can't do fast consecutive clicks on my own.

When I tried your example it worked nicely but for a different purpose, making the changes to it to send a (dynamic) key it showed again my initial problem. Anyhow I'm more than happy with the final outcome, now I can do little floating boards to use shortcuts in apps like photoshop, or buttons in games. :D

Thanks again!
Post Reply

Return to “Gaming Help (v1)”