Gui form to define hotkeys

Post your working scripts, libraries and tools
User avatar
JnLlnd
Posts: 295
Joined: 29 Sep 2013, 21:29
GitHub: JnLlnd
Location: Montreal, Quebec, Canada
Contact:

Gui form to define hotkeys

03 Dec 2013, 23:19

For one of my projects, I needed a Gui form to give the user the choice of 3 hotkeys/mouse buttons shortcuts. It uses the "Gui, Add, Hotkey" control with the addition of check boxes to accept any modifiers, including the Win key (#) modifier normally inaccessible to the hotkey control. I also use a dropdown list to make the choice of a mouse button easy for users not familiar with AHK syntax.

In this proof-of-concept developed for a future version of my FoldersPopup project (http://www.code.jeanlalonde.ca/folderspopup), the script defines three hotkeys. Hotkey definitions are read and saved to an .ini file.

This is not new stuff but this script make it easy to define multiple hotkeys in a loop, avoiding code repetition (this could be taken a step further using objects, but I stopped before going there). You can find other examples and approaches for this kind of functions in this thread: http://www.autohotkey.com/board/topic/4 ... c-hotkeys/

This is gui-hotkey.akh version 1.0. Updates (if any) will be posted here: https://raw.github.com/JnLlnd/CherryPic ... hotkey.ahk

Code: Select all

;===============================================
/*
	Gui-Hotkey
	Proof of concept for a future version of FoldersPopup (www.code.jeanlalonde.ca/folderspopup)
	Written using AutoHotkey_L v1.1.09.03+ (http://l.autohotkey.net/)
	By Jean Lalonde (JnLlnd on AHKScript.org forum)
*/
#NoEnv
#SingleInstance force
#KeyHistory 0
ListLines, Off

;---------------------------------------
SplitPath, A_ScriptName, , , , strIniFilename
strIniFilename := strIniFilename . ".ini"
strIniPathFilename := A_ScriptDir . "\" . strIniFilename
strMouseButtons := " |LButton|MButton|RButton|XButton1|XButton2|WheelUp|WheelDown|WheelLeft|WheelRight|" ; leave last | to enable default value

;---------------------------------------
; Ini key names, matching hotkey variables names and default values for hotkeys
strIniKeyNames := "PopupHotkey|NewExplorerHotkey|SettingsHotkey"
StringSplit, arrIniKeyNames, strIniKeyNames, |
strHotkeyVarNames := "strHotkeyPopup|strHotkeyNewExplorer|strHotkeySettings"
StringSplit, arrHotkeyVarNames, strHotkeyVarNames, |
strHotkeyDefaults := "MButton|+MButton|^#f"
StringSplit, arrHotkeyDefaults, strHotkeyDefaults, |

;---------------------------------------
; Gui hotkey titles and descriptions
strTitles := "Folders Popup|New Explorer|Settings"
StringSplit, arrTitles, strTitles, |
arrDescriptions1 := "Choose the hotkey or mouse button combination that will open the folders popup menu in Windows Explorer or file dialog boxes. By default, this is the middle mouse button (MButton) without any modifier key."
arrDescriptions2 := "Choose the hotkey or mouse button combination that will open the folders popup menu over any window and navigate to the selected folder in a new Windows Explorer window."
arrDescriptions3 := "Choose the hotkey or mouse button combination that will open the Folders Popup setting dialog box. By default, this is Control+Windows+F."
; Need more hotkey? Add it above...

;---------------------------------------
; Build Gui header
Gui, Font, s8 w700
Gui, Add, Text, x5 y10, GUI-HOTKEY Demo
Gui, Font
; Build Hotkey gui lines
loop, % arrIniKeyNames%0%
{
	; Read the first hotkey in the ini file
	IniRead, arrHotkeyVarNames%A_Index%, %strIniPathFilename%, Global, % arrIniKeyNames%A_Index%, % arrHotkeyDefaults%A_Index%
	; Prepare global arrays used by GuiHotkey function
	SplitHotkey(arrHotkeyVarNames%A_Index%, strMouseButtons
		, strModifiers%A_Index%, strKey%A_Index%, strMouseButton%A_Index%, strMouseButtonsWithDefault%A_Index%)
	; Code it
	GuiHotkey(A_Index)
}
;---------------------------------------
; Gui footer
Gui, Add, Button, x170 vbtnSave gButtonSave, Save to %strIniFilename%
Gui, Add, Text
GuiControl, Focus, btnSave

;---------------------------------------
; Show until user click Save
Gui, Show
return
; End of script startup
;---------------------------------------



;---------------------------------------
GuiHotkey(intIndex)
;---------------------------------------
{
	global

	; Hotkey Header
	Gui, Add, Text, y+20 x98 w25 center, Shift
	Gui, Add, Text, yp x+11 w25 center, Ctrl
	Gui, Add, Text, yp x+10 w25 center, Alt
	Gui, Add, Text, yp x+10 w25 center, Win
	Gui, Add, Text, yp x+10 w100 center, Keyboard
	Gui, Add, Text, yp x+30 w80 center, Mouse

	Gui, Font, s8 w700
	Gui, Add, Text, x5 y+5 w90 right, % arrTitles%intIndex%
	Gui, Font
	Gui, Add, CheckBox, yp x+10 vblnShift%intIndex%, %A_Space%
		; if we have no text to put at the right of the ckeckbox
		; would it be possible to eliminate the dotted area ?
		; intIndex put a space becauyse this is what intIndex found the less visible.
	GuiControl, , blnShift%intIndex%, % InStr(strModifiers%intIndex%, "+") ? 1 : 0
	Gui, Add, CheckBox, yp x+10 vblnCtrl%intIndex%, %A_Space%
	GuiControl, , blnCtrl%intIndex%, % InStr(strModifiers%intIndex%, "^") ? 1 : 0
	Gui, Add, CheckBox, yp x+10 vblnAlt%intIndex%, %A_Space%
	GuiControl, , blnAlt%intIndex%, % InStr(strModifiers%intIndex%, "!") ? 1 : 0
	Gui, Add, CheckBox, yp x+10 vblnWin%intIndex%, %A_Space%
	GuiControl, , blnWin%intIndex%, % InStr(strModifiers%intIndex%, "#") ? 1 : 0
	Gui, Add, Hotkey, yp x+10 w100 vstrKey%intIndex% gHotkeyChanged
	GuiControl, , strKey%intIndex%, % strKey%intIndex%
	Gui, Add, Text, yp x+5, %A_Space%%A_Space%or
	Gui, Add, DropDownList, yp x+10 w80 vstrMouse%intIndex% gMouseChanged, % strMouseButtonsWithDefault%intIndex%
	Gui, Add, Text, x5 y+5 w440, % arrDescriptions%intIndex%
}
;---------------------------------------



;---------------------------------------
ButtonSave:
;---------------------------------------
Gui, Submit

strIniVarNames := "PopupHotkey|NewExplorerHotkey|SettingsHotkey"
StringSplit, arrIniVarNames, strIniVarNames, |

Loop, % arrIniVarNames%0%
{
	strHotkey%A_Index% := Trim(strKey%A_Index% . strMouse%A_Index%)
	if StrLen(strHotkey%A_Index%)
	{
		if (blnWin%A_Index%)
			strHotkey%A_Index% := "#" . strHotkey%A_Index%
		if (blnAlt%A_Index%)
			strHotkey%A_Index% := "!" . strHotkey%A_Index%
		if (blnShift%A_Index%)
			strHotkey%A_Index% := "+" . strHotkey%A_Index%
		if (blnCtrl%A_Index%)
			strHotkey%A_Index% := "^" . strHotkey%A_Index%
		IniWrite, % strHotkey%A_Index%, %strIniPathFilename%, Global, % arrIniVarNames%A_Index%
	}
	else ; decide if you want to delete the key or keep the existing one - here we delete it
		IniDelete, %strIniPathFilename%, Global, % arrIniVarNames%A_Index%
}
ExitApp
return
;---------------------------------------



;---------------------------------------
HotkeyChanged:
;---------------------------------------
strHotkeyControl := A_GuiControl ; hotkey var name
strHotkey := %strHotkeyControl% ; hotkey content

if !StrLen(strHotkey)
	return

SplitModifiersFromKey(strHotkey, strModifiers, strKey)

if StrLen(strModifiers) ; we have a modifier and we dont want it, reset keyboard to none and return
	GuiControl, , %A_GuiControl%, None
else ; we have a valid key, empty the mouse dropdown and return
{
	StringReplace, strMouseControl, strHotkeyControl, Key, Mouse ; get the matching mouse dropdown var
	GuiControl, ChooseString, %strMouseControl%, %A_Space%
}
return
;---------------------------------------



;---------------------------------------
MouseChanged:
;---------------------------------------
strMouseControl := A_GuiControl ; mouse dropdown var name
StringReplace, strHotkeyControl, strMouseControl, Mouse, Key ; get the hotkey var
; we have a mouse button, empty the hotkey control
GuiControl, , %strHotkeyControl%, % ""
return
;---------------------------------------



;---------------------------------------
SplitHotkey(strHotkey, strMouseButtons, ByRef strModifiers, ByRef strKey, ByRef strMouseButton, ByRef strMouseButtonsWithDefault)
;---------------------------------------
{
	SplitModifiersFromKey(strHotkey, strModifiers, strKey)

	if InStr(strMouseButtons . "|", "|" . strKey . "|") ;  we have a mouse button
	{
		strMouseButton := strKey
		strKey := ""
		StringReplace, strMouseButtonsWithDefault, strMouseButtons, %strMouseButton%|, %strMouseButton%|| ; with default value
	}
	else ; we have a key
		strMouseButtonsWithDefault := strMouseButtons ; no default value
}
;---------------------------------------



;---------------------------------------
SplitModifiersFromKey(strHotkey, ByRef strModifiers, ByRef strKey)
;---------------------------------------
{
	intModifiersEnd := GetFirstNotModifier(strHotkey)
	StringLeft, strModifiers, strHotkey, %intModifiersEnd%
	StringMid, strKey, strHotkey, % (intModifiersEnd + 1)
}
;---------------------------------------



;---------------------------------------
GetFirstNotModifier(strHotkey)
;---------------------------------------
{
	intPos := 0
	loop, Parse, strHotkey
		if (A_LoopField = "^") or (A_LoopField = "!") or (A_LoopField = "+") or (A_LoopField = "#")
			intPos := intPos + 1
		else
			return intPos
	return intPos
}
;---------------------------------------
2013-12-04 arrDescriptions bug fixed
Last edited by JnLlnd on 04 Dec 2013, 23:02, edited 1 time in total.
Author of freeware apps Quick Access Popup (http://www.quickaccesspopup.com),
FoldersPopup and CSV Buddy (http://code.jeanlalonde.ca)
guest3456
Posts: 2573
Joined: 09 Oct 2013, 10:31

Re: Gui form to define hotkeys

04 Dec 2013, 02:28

just for reference, and in case you haven't seen it

this is pretty much the go-to self contained function for defining hotkeys:

jballi's HotkeyGUI
http://www.autohotkey.com/board/topic/1 ... eygui-v04/

User avatar
JnLlnd
Posts: 295
Joined: 29 Sep 2013, 21:29
GitHub: JnLlnd
Location: Montreal, Quebec, Canada
Contact:

Re: Gui form to define hotkeys

04 Dec 2013, 06:58

guest3456 wrote:this is pretty much the go-to self contained function for defining hotkeys:

jballi's HotkeyGUI
http://www.autohotkey.com/board/topic/1 ... eygui-v04/
Sad that the search I did on the old forum did not show up this topic :-(

Looks very well done. Thanks for pointing it.
Author of freeware apps Quick Access Popup (http://www.quickaccesspopup.com),
FoldersPopup and CSV Buddy (http://code.jeanlalonde.ca)

Return to “Scripts and Functions”

Who is online

Users browsing this forum: No registered users and 64 guests