Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

[Function] HotkeyGUI v0.4


  • Please log in to reply
25 replies to this topic
rbrtryn
  • Members
  • 1177 posts
  • Last active: Sep 11 2013 08:04 PM
  • Joined: 22 Jun 2011
I would suggest that you disable Shift + numpad combinations. I don't know if it is a bug in AutoHotkey or a bug in Windows, but using the Shift key in combination with most of numpad keys gives odd and unpredictable results in my experience.

Thanks for keeping this updated, I'll test it some with AutoHotkey_L let you know if I have any problem.

jballi
  • Members
  • 1029 posts
  • Last active:
  • Joined: 01 Oct 2005

I would suggest that you disable Shift + numpad combinations. I don't know if it is a bug in AutoHotkey or a bug in Windows, but using the Shift key in combination with most of numpad keys gives odd and unpredictable results in my experience.

I had never tried these key combinations. :shock: Excellent catch! But as you observed, some of the Shift-key/Numpad combinations give odd and unpredictable results whereas others work fine. Since we are not exactly sure what is causing the problem, excluding the Shift-key modifier from this key range is probably out of scope for this project. If you have time, it might be a good idea to report this problem/observation in the "Ask for Help" and/or the "Bug Reports" forum. Thanks for your feedback.

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
What results do you see? "Unpredictable" is a bit vague.

rbrtryn
  • Members
  • 1177 posts
  • Last active: Sep 11 2013 08:04 PM
  • Joined: 22 Jun 2011
Let's say we define a hotkey as {Shift} + Numpad0, i.e +Numpad0.

That Hotkey will never fire! The reason does not fire is that pressing down the Shift key will temporarly reverse the Numlock state. Numpad 0 becomes NumpadIns, Numpad4 becomes NumpadLeftArrow, etc. So instead of receiving +Numpad0, the script will receive NumpadIns.

This a "feature" of the Windows OS that seems to be too deeply buied for AutoHotkey to get its hooks into, pardon the pun :lol:

@jballi The only way I could see to do it is to just outlaw the use of shift with all the Numpad keys, but as you say it's probably outside the scope of the project.

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
Oh, this behavior is actually new to me!

TheDewd
  • Members
  • 842 posts
  • Last active: Jun 10 2016 06:55 PM
  • Joined: 28 Mar 2010
Wow, excellent! Great idea.

jballi
  • Members
  • 1029 posts
  • Last active:
  • Joined: 01 Oct 2005

Let's say we define a hotkey as {Shift} + Numpad0, i.e +Numpad0.

That Hotkey will never fire! The reason does not fire is that pressing down the Shift key will temporarly reverse the Numlock state. Numpad 0 becomes NumpadIns, Numpad4 becomes NumpadLeftArrow, etc. So instead of receiving +Numpad0, the script will receive NumpadIns.

This a "feature" of the Windows OS that seems to be too deeply buied for AutoHotkey to get its hooks into, pardon the pun :lol:

I think I can provide some additional insight. Maybe...

On keyboards that have a Numeric Keypad, the numbered keys ("0" through "9") and the Dot key (".") are toggle keys. They produce values based on the current state of the NumLock key. If NumLock is On, the "Numpad0" through "Numpad9" and "NumpadDot" keys are returned. If NumLock is Off, the "NumpadIns", "NumpadEnd", "NumpadDown", etc. keys are returned.

As you have discovered, the Shift key reverses the NumLock state. So "Numpad0" becomes "NumpadIns", "Numpad1" becomes "NumpadEnd" and so on. I'm not sure if this Shift characteristic occurs on all keyboards.

On my keyboard (maybe all keyboards?), the Shift key only reverses the NumLock state if NumLock is On. So Shift+NumpadIns is interpreted as "+NumpadIns" not "Numpad0".

So... if all keyboards work the same as yours and mine (I certainly don't think this is the case), we could safely convert from/to the following (including all variations):
From         To
----         --
+Numpad0     NumpadIns
+Numpad1     NumpadEnd
+Numpad2     NumpadDown
...
+Numpad9     NumpadPgUp
+NumpadDot   NumpadDel
Them be my thoughts.

rbrtryn
  • Members
  • 1177 posts
  • Last active: Sep 11 2013 08:04 PM
  • Joined: 22 Jun 2011
Looks like the latest update to AHK ( v1.1.04.00 ) has broken your code. I had no problems in v1.1.03.00, but since I updated I get the following error:

---------------------------
CMenu.ahk
---------------------------
Error in #include file "C:\Users\Developer\Documents\AutoHotkey\Lib\HotkeyGui.ahk":
Invalid option. The current thread will exit.

Specifically: ||

Line#
378: {
379: Gui,%p_Owner%:+Disabled
380: Gui,%s_GUI%:+Owner%p_Owner%
381: }
382: Else
383: Gui,%s_GUI%:+Owner
386: Gui,%s_GUI%:Margin,6,6
---> 387: Gui,%s_GUI%:-MinimizeBox || +LabelHotkeyGUI_
390: if not p_Owner
391: Gui,%s_GUI%:+AlwaysOnTop
398: Gui,%s_GUI%:Add,GroupBox,xm y10 w170 h10 || vHG_ModifierGB,Modifier
405: Gui,%s_GUI%:Add,CheckBox,xp+10 yp+20 || Section || vHG_CtrlModifier || gHotkeyGUI_UpdateHotkey,Ctrl
414: Gui,%s_GUI%:Add,CheckBox,xs || vHG_ShiftModifier || gHotkeyGUI_UpdateHotkey,Shift
422: Gui,%s_GUI%:Add,CheckBox,xs || vHG_WinModifier || gHotkeyGUI_UpdateHotkey,Win
430: Gui,%s_GUI%:Add,CheckBox,xs || vHG_AltModifier || gHotkeyGUI_UpdateHotkey,Alt

---------------------------
OK
---------------------------

It looks like the continuation method you use for the gui options parameter is no longer valid.

Edit: I fixed this by removing the offending characters and placing all of the Gui options on a single line. Do you think this should be reported as an AHK_L bug?
;-----------------------------
;
; Function: HotkeyGUI
;
; Description:
;
;   This function displays a dialog that will allow the user to select a hotkey
;   without using the keyboard.  See the "Processing and Usage Notes" section
;   for more information.
;
;
; Parameters:
;
;   p_Owner - The GUI owner of the HotkeyGUI window. [Optional] The default is
;       0 (no owner).  If not defined, the AlwaysOnTop attribute is added to the
;       HotkeyGUI window to make sure that the window is not lost.
;
;   p_Hotkey - The default hotkey value. [Optional] The default is blank.  To
;       only preselect modifiers and/or optional attributes, enter only the
;       associated characters.  For example, to only have the Ctrl and Shift
;       modifiers set as the default, enter "^+".
;
;   p_Limit - Hotkey limit. [Optional] The default is 0.  See the "Hotkey
;       Limits" section below for more information.
;
;   p_OptionalAttrib - Optional hotkey attributes. [Optional]  The default is
;       FALSE.  If set to TRUE, all items in the Optional Attributes group are
;       enabled and the user is allowed to add or remove optional attributes.
;
;   p_Title - Window title. [Optional]  The default is the current script name
;       (sans the extention) plus "Select Hotkey".
;
;
; Processing And Usage Notes:
;
; Stuff to know...
;
;    *  The function does not return until the HotkeyGUI window is closed
;       (Accept or Cancel).
;
;    *  A shift-only key (Ex: ~!@#$%^&*()_+{}|:"<>?) cannot be directly selected
;       as a key by this function.  To use a shift-only key, select the Shift
;       modifier and then select the non-shift version of the key.  For example,
;       to set the "(" key as a hotkey, select the Shift modifier and then
;       select the "9" key.  The net result is the "(" key.  In addition,
;       shift-only keys are not supported as values for the p_Hotkey parameter
;       as a default hotkey.  If a shift-only key is used, no default key will
;       be selected.
;
;    *  To resolve a minor AutoHotkey inconsistency, the "Pause" key and the
;       "Break" keys are automatically converted to the "CtrlBreak" key if the
;       Ctrl modifier is selected.  The "CtrlBreak" key is automatically
;       converted to the "Pause" key if the Ctrl modifier is not selected.
;
;
; Hotkey Limits:
;
;   The p_Limit parameter allows the developer to restrict the types of keys
;   that are selected.  The following limit values are available:
;
;       (start code)
;       Limit   Description
;       -----   -----------
;       1       Prevent unmodified keys
;       2       Prevent Shift-only keys
;       4       Prevent Ctrl-only keys
;       8       Prevent Alt-only keys
;       16      Prevent Win-only keys
;       32      Prevent Shift-Ctrl keys
;       64      Prevent Shift-Alt keys
;       128     Prevent Shift-Win keys
;       256     Prevent Shift-Ctrl-Alt keys
;       512     Prevent Shift-Ctrl-Win keys
;       1024    Prevent Shift-Win-Alt keys
;       (end)
;
;   To use a limit, enter the sum of one or more of these limit values.  For
;   example, a limit value of 1 will prevent unmodified keys from being used.
;   A limit value of 31 (1 + 2 + 4 + 8 + 16) will require that at least two
;   modifier keys be used.
;
;
; Returns:
;
;   If the function ends after the user has selected a valid key and the
;   "Accept" button is pressed, the function returns the selected key in the
;   standard AutoHotkey hotkey format and ErrorLevel is set to 0.
;   Example: Hotkey=^a  ErrorLevel=0
;
;   If the HotkeyGUI window is canceled (Cancel button, Close button, or Escape
;   key), the function returns the original hotkey value (p_Hotkey) and
;   Errorlevel is set to 1.
;
;   If the function is unable to create a HotkeyGUI window for any reason,
;   ErrorLevel is set to the word FAIL.
;
;
; Calls To Other Functions:
;
;   PopupXY (optional)
;
;
; Hotkey Support:
;
;   AutoHotkey is a very robust program and can accept hotkey definitions in an
;   multitude of formats.  Unfortunately, this function is not that robust and
;   there are a couple of important limitations:
;
;    1.  The p_Limit parameter restricts the type of keys that can be supported.
;       For this reason, the following keys are not supported:
;
;        * *Modifier keys* (as hotkeys). Example: Alt, Shift, LWin, etc.
;        * *Joystick keys*. Example: Joy1, Joy2, etc.
;        * *Custom combinations*. Example: Numpad0 & Numpad1.
;
;    2.  Shift-only keys (Ex: "~","!","@","#",etc.) are not supported.  See the
;       "Processing and Usage Notes" section for more information.
;
;
; Programming Notes:
;
;   To keep the code as friendly as possible, static variables (in lieu of
;   global variables) are used whenever a GUI object needs a variable. Object
;   variables are defined so that a single "gui Submit" command can be used to
;   collect the GUI values instead of having to execute a "GUIControlGet"
;   command on every GUI control. For the few GUI objects that are
;   programmatically updated, the ClassNN (class name and instance number of the
;   object  Ex: Static4) is used.
;
;   Important: Any changes to the GUI (additions, deletions, etc.) may change
;   the ClassNN of objects that are updated.  Use Window Spy (or similar
;   program) to identify any changes.
;
;-------------------------------------------------------------------------------
HotkeyGUI(p_Owner="",p_Hotkey="",p_Limit="",p_OptionalAttrib=False,p_Title="")
    {
    ;[====================]
    ;[  Static variables  ]
    ;[====================]
    Static s_GUI:=0
                ;-- This variable stores the currently active GUI.  If not zero
                ;   when entering the function, the GUI is currently showing.

          ,s_StartGUI:=53
                ;-- Default starting GUI window number for HotkeyGUI window.
                ;   Change if desired.

          ,s_PopupXY_Function:="PopupXY"
                ;-- Name of the PopupXY function.  Defined as a variable so that
                ;   function will use if the "PopupXY" function is included but
                ;   will not fail if it's not.

    ;[===========================]
    ;[  Window already showing?  ]
    ;[===========================]
    if s_GUI
        {
        Errorlevel:="FAIL"
        outputdebug,
           (ltrim join`s
            End Func: %A_ThisFunc% -
            A %A_ThisFunc% window already exists.  Errorlevel=FAIL
           )

        Return
        }

    ;[==============]
    ;[  Initialize  ]
    ;[==============]
    SplitPath A_ScriptName,,,,l_ScriptName
    l_ErrorLevel  :=0

    ;-------------
    ;-- Key lists
    ;-------------
    ;-- Standard keys
    l_StandardKeysList=
       (ltrim join|
        A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z
        0|1|2|3|4|5|6|7|8|9|0
        ``|-|=|[|]|`\|;
        '|,|.|/
        Space
        Tab
        Enter
        Escape
        Backspace
        Delete
        ScrollLock
        CapsLock
        NumLock
        PrintScreen
        CtrlBreak
        Pause
        Break
        Insert
        Home
        End
        PgUp
        PgDn
        Up
        Down
        Left
        Right
       )

    ;-- Function keys
    l_FunctionKeysList=
       (ltrim join|
        F1|F2|F3|F4|F5|F6|F7|F8|F9|F10
        F11|F12|F13|F14|F15|F16|F17|F18|F19|F20
        F21|F22|F23|F24
       )

    ;-- Numpad
    l_NumpadKeysList=
       (ltrim join|
        NumLock
        NumpadDiv
        NumpadMult
        NumpadAdd
        NumpadSub
        NumpadEnter
        NumpadDel
        NumpadIns
        NumpadClear
        NumpadUp
        NumpadDown
        NumpadLeft
        NumpadRight
        NumpadHome
        NumpadEnd
        NumpadPgUp
        NumpadPgDn
        Numpad0
        Numpad1
        Numpad2
        Numpad3
        Numpad4
        Numpad5
        Numpad6
        Numpad7
        Numpad8
        Numpad9
        NumpadDot
       )

    ;-- Mouse
    l_MouseKeysList=
       (ltrim join|
        LButton
        RButton
        MButton
        WheelDown
        WheelUp
        XButton1
        XButton2
       )

    ;-- Multimedia
    l_MultimediaKeysList=
       (ltrim join|
        Browser_Back
        Browser_Forward
        Browser_Refresh
        Browser_Stop
        Browser_Search
        Browser_Favorites
        Browser_Home
        Volume_Mute
        Volume_Down
        Volume_Up
        Media_Next
        Media_Prev
        Media_Stop
        Media_Play_Pause
        Launch_Mail
        Launch_Media
        Launch_App1
        Launch_App2
       )

    ;-- Special
    l_SpecialKeysList:="Help|Sleep"

    ;[==================]
    ;[    Parameters    ]
    ;[  (Set defaults)  ]
    ;[==================]
    ;-- Owner
    p_Owner=%p_Owner%  ;-- AutoTrim
    if p_Owner is not Integer
        p_Owner:=0
     else
        if p_Owner not Between 1 and 99
            p_Owner:=0

    ;-- Owner window exists?
    if p_Owner
        {
        gui %p_Owner%:+LastFoundExist
        IfWinNotExist
            {
            outputdebug,
               (ltrim join`s
                Function: %A_ThisFunc% -
                Owner window does not exist.  p_Owner=%p_Owner%
               )

            p_Owner:=0
            }
        }

    ;-- Default hotkey
    l_Hotkey=%p_Hotkey%  ;-- AutoTrim

    ;-- Limit
    p_Limit=%p_Limit%  ;-- AutoTrim
    if p_Limit is not Integer
        p_Limit:=0
     else
        if p_Limit not between 0 and 2047
            p_Limit:=0

    ;-- Title
    p_Title=%p_Title%  ;-- AutoTrim
    if p_Title is Space
        p_Title:=l_ScriptName . " - Select Hotkey"
     else
        {
        ;-- Append to script name if p_title begins with "++"?
        if SubStr(p_Title,1,2)="++"
            {
            StringTrimLeft p_Title,p_Title,2
            p_Title:=l_ScriptName . A_Space . p_Title
            }
        }

    ;[==============================]
    ;[     Find available window    ]
    ;[  (Starting with s_StartGUI)  ]
    ;[==============================]
    s_GUI:=s_StartGUI
    Loop
        {
        ;-- Window available?
        gui %s_GUI%:+LastFoundExist
        IfWinNotExist
            Break

        ;-- Nothing available?
        if (s_GUI=99)
            {
            MsgBox
                ,262160
                    ;-- 262160=0 (OK button) + 16 (Error icon) + 262144 (AOT)
                ,%A_ThisFunc% Error,
                   (ltrim join`s
                    Unable to create a %A_ThisFunc% window.  GUI windows
                    %s_StartGUI% to 99 are already in use.  %A_Space%
                   )

            s_GUI:=0
            ErrorLevel:="FAIL"
            Return
            }

        ;-- Increment window
        s_GUI++
        }

    ;[=============]
    ;[  Build GUI  ]
    ;[=============]
    ;-- Assign ownership
    if p_Owner
        {
        gui %p_Owner%:+Disabled      ;-- Disable Owner window
        gui %s_GUI%:+Owner%p_Owner%  ;-- Set ownership
        }
     else
        gui %s_GUI%:+Owner           ;-- Gives ownership to the script window

    ;-- GUI options
    gui %s_GUI%:Margin,6,6
    gui %s_GUI%:-MinimizeBox +LabelHotkeyGUI_

    if not p_Owner
        gui %s_GUI%:+AlwaysOnTop

    ;---------------
    ;-- GUI objects
    ;---------------
    ;-- Modifiers
    Static HG_ModifierGB
    gui %s_GUI%:Add
       ,GroupBox
       , xm y10 w170 h10 vHG_ModifierGB
       ,Modifier

    Static HG_CtrlModifier
    gui %s_GUI%:Add
       ,CheckBox
       ,xp+10 yp+20 Section vHG_CtrlModifier gHotkeyGUI_UpdateHotkey
       ,Ctrl

    Static HG_ShiftModifier
    gui %s_GUI%:Add
       ,CheckBox
       ,xs vHG_ShiftModifier gHotkeyGUI_UpdateHotkey
       ,Shift

    Static HG_WinModifier
    gui %s_GUI%:Add
       ,CheckBox
       ,xs vHG_WinModifier gHotkeyGUI_UpdateHotkey
       ,Win

    Static HG_AltModifier
    gui %s_GUI%:Add
       ,CheckBox
       ,xs vHG_AltModifier gHotkeyGUI_UpdateHotkey
       ,Alt

    ;-- Optional Attributes
    Static HG_OptionalAttributesGB
    gui %s_GUI%:Add
       ,GroupBox
       ,xs+160 y10 w170 h10 vHG_OptionalAttributesGB
       ,Optional Attributes

    Static HG_NativeOption
    gui %s_GUI%:Add
       ,CheckBox
       ,xp+10 yp+20 Disabled Section vHG_NativeOption gHotkeyGUI_UpdateHotkey
       ,~ (Native)

    Static HG_WildcardOption
    gui %s_GUI%:Add
       ,CheckBox
       ,xs Disabled vHG_WildcardOption gHotkeyGUI_UpdateHotkey
       ,*  (Wildcard)

    Static HG_LeftPairOption
    gui %s_GUI%:Add                                                 ;-- Button9
       ,CheckBox
       ,xs Disabled vHG_LeftPairOption gHotkeyGUI_LeftPair
       ,< (Left pair only)

    Static HG_RightPairOption
    gui %s_GUI%:Add                                                 ;-- Button10
       ,CheckBox
       ,xs Disabled vHG_RightPairOption gHotkeyGUI_RightPair
       ,> (Right pair only)

    ;-- Enable "Optional Attributes"?
    if p_OptionalAttrib
        {
        GUIControl %s_GUI%:Enable,HG_NativeOption
        GUIControl %s_GUI%:Enable,HG_WildcardOption
        GUIControl %s_GUI%:Enable,HG_LeftPairOption
        GUIControl %s_GUI%:Enable,HG_RightPairOption
        }

    ;-- Resize the Modifier and Optional Attributes group boxes
    GUIControlGet $Group1Pos,%s_GUI%:Pos,HG_OptionalAttributesGB
    GUIControlGet $Group2Pos,%s_GUI%:Pos,HG_RightPairOption
    GUIControl
        ,%s_GUI%:Move
        ,HG_ModifierGB
        ,% "h" . ($Group2PosY-$Group1PosY)+$Group2PosH+10

    GUIControl
        ,%s_GUI%:Move
        ,HG_OptionalAttributesGB
        ,% "h" . ($Group2PosY-$Group1PosY)+$Group2PosH+10

    ;-- Keys
    YPos:=($Group2PosY-$Group1PosY)+$Group2PosH+20
    gui %s_GUI%:Add
       ,GroupBox
       ,xm y%YPos% w340 h180
       ,Keys

    Static HG_StandardKeysView
    gui %s_GUI%:Add
       ,Radio
       ,xp+10 yp+20 Checked Section vHG_StandardKeysView gHotkeyGUI_UpdateKeyList
       ,Standard

    Static HG_FunctionKeysView
    gui %s_GUI%:Add
       ,Radio
       ,xs vHG_FunctionKeysView gHotkeyGUI_UpdateKeyList
       ,Function keys

    Static HG_NumpadKeysView
    gui %s_GUI%:Add
       ,Radio
       ,xs vHG_NumpadKeysView gHotkeyGUI_UpdateKeyList
       ,Numpad

    Static HG_MouseKeysView
    gui %s_GUI%:Add
       ,Radio
       ,xs vHG_MouseKeysView gHotkeyGUI_UpdateKeyList
       ,Mouse

    Static HG_MultimediaKeysView
    gui %s_GUI%:Add
       ,Radio
       ,xs vHG_MultimediaKeysView gHotkeyGUI_UpdateKeyList
       ,Multimedia

    Static HG_SpecialKeysView
    gui %s_GUI%:Add
       ,Radio
       ,xs vHG_SpecialKeysView gHotkeyGUI_UpdateKeyList
       ,Special

    Static HG_Key
    gui %s_GUI%:Add
       ,ListBox                                                     ;-- ListBox1
       ,xs+140 ys w180 h150 vHG_Key gHotkeyGUI_UpdateHotkey

    ;-- Set initial values
    gosub HotkeyGUI_UpdateKeyList

    ;-- Hotkey display
    YPos+=190
    gui %s_GUI%:Add
       ,Text
       ,xm y%YPos% w70
       ,Hotkey:

    gui %s_GUI%:Add
       ,Edit                                                        ;-- Edit1
       ,x+0 w270 +ReadOnly

    gui %s_GUI%:Add
       ,Text
       ,xm y+5 w70 r2 hp
       ,Desc:

    gui %s_GUI%:Add
       ,Text                                                        ;-- Static3
       ,x+0 w270 hp +ReadOnly
       ,None

    ;-- Buttons
    Static HG_AcceptButton
    gui %s_GUI%:Add                                                 ;-- Button18
       ,Button
       ,xm y+5 Default Disabled vHG_AcceptButton gHotkeyGUI_AcceptButton
       ,%A_Space% &Accept %A_Space%
            ;-- Note: All characters are used to determine the button's W+H

    gui %s_GUI%:Add
       ,Button
       ,x+5 wp hp gHotkeyGUI_Close
       ,Cancel

    ;[================]
    ;[  Set defaults  ]
    ;[================]
    if l_Hotkey is not Space
        {
        ;-- Modifiers and optional attributes
        Loop
            {
            l_FirstChar:=SubStr(l_Hotkey,1,1)
            if l_FirstChar in ^,+,#,!,~,*,<,>
                {
                if (l_FirstChar="^")
                    GUIControl %s_GUI%:,HG_CtrlModifier,1
                else if (l_FirstChar="+")
                    GUIControl %s_GUI%:,HG_ShiftModifier,1
                else if (l_FirstChar="#")
                    GUIControl %s_GUI%:,HG_WinModifier,1
                else if (l_FirstChar="!")
                    GUIControl %s_GUI%:,HG_AltModifier,1
                else  if (l_FirstChar="~")
                    GUIControl %s_GUI%:,HG_NativeOption,1
                else if (l_FirstChar="*")
                    GUIControl %s_GUI%:,HG_WildcardOption,1
                else if (l_FirstChar="<")
                    GUIControl %s_GUI%:,HG_LeftPairOption,1
                else if (l_FirstChar=">")
                    GUIControl %s_GUI%:,HG_RightPairOption,1
    
                ;-- On to the next
                StringTrimLeft l_Hotkey,l_Hotkey,1
                Continue
                }
    
            ;-- We're done here
            Break
            }
    
        ;-- Find key in key lists
        if l_Hotkey is not Space
            {
            ;-- Standard keys
            if Instr("|" . l_StandardKeysList . "|","|" . l_Hotkey . "|")
                GUIControl %s_GUI%:,HG_StandardKeysView,1
            ;-- Function keys
            else if Instr("|" . l_FunctionKeysList . "|","|" . l_Hotkey . "|")
                GUIControl %s_GUI%:,HG_FunctionKeysView,1
            ;-- Numpad keys
            else if Instr("|" . l_NumpadKeysList . "|","|" . l_Hotkey . "|")
                GUIControl %s_GUI%:,HG_NumpadKeysView,1
            ;-- Mouse keys
            else if Instr("|" . l_MouseKeysList . "|","|" . l_Hotkey . "|")
                GUIControl %s_GUI%:,HG_MouseKeysView,1
            ;-- Multimedia keys
            else if Instr("|" . l_MultimediaKeysList . "|","|" . l_Hotkey . "|")
                GUIControl %s_GUI%:,HG_MultimediaKeysView,1
            ;-- Special keys
            else if Instr("|" . l_SpecialKeysList . "|","|" . l_Hotkey . "|")
                GUIControl %s_GUI%:,HG_SpecialKeysView,1
    
            ;-- Update keylist and select it
            gosub HotkeyGUI_UpdateKeyList
            GUIControl %s_GUI%:ChooseString,HG_Key,%l_Hotkey%
            }

        ;-- Update Hotkey field and description
        gosub HotkeyGUI_UpdateHotkey
        }

    ;[=============]
    ;[  Set focus  ]
    ;[=============]
    GUIControl %s_GUI%:Focus,HG_AcceptButton
        ;-- Note: This only works when the Accept button is enabled

    ;[================]
    ;[  Collect hWnd  ]
    ;[================]
    gui %s_GUI%:+LastFound
    WinGet l_HotkeyGUI_hWnd,ID

    ;[===============]
    ;[  Show window  ]
    ;[===============]
     if p_Owner and IsFunc(s_PopupXY_Function)
        {
        gui %s_GUI%:Show,Hide,%p_Title%   ;-- Render but don't show
        %s_PopupXY_Function%(p_Owner,"ahk_id " . l_HotkeyGUI_hWnd,PosX,PosY)
        gui %s_GUI%:Show,x%PosX% y%PosY%  ;-- Show in the correct location
        }
     else
        gui %s_GUI%:Show,,%p_Title%

    ;[=====================]
    ;[  Loop until window  ]
    ;[      is closed      ]
    ;[=====================]
    WinWaitClose ahk_id %l_HotkeyGUI_hWnd%

    ;[====================]
    ;[  Return to sender  ]
    ;[====================]
    ErrorLevel:=l_ErrorLevel
    Return HG_HotKey  ;-- End of function



    ;*****************************
    ;*                           *
    ;*                           *
    ;*        Subroutines        *
    ;*        (HotkeyGUI)        *
    ;*                           *
    ;*                           *
    ;*****************************
    ;***********************
    ;*                     *
    ;*    Update Hotkey    *
    ;*                     *
    ;***********************
    HotkeyGUI_UpdateHotkey:

    ;-- Collect form values
    gui %s_GUI%:Submit,NoHide

    ;-- Enable/Disable Accept button
    if HG_Key
        GUIControl %s_GUI%:Enable,Button18
     else
        GUIControl %s_GUI%:Disable,Button18

    ;-- Substitute Pause|Break for CtrlBreak?
    if HG_Key in Pause,Break
        if HG_CtrlModifier
            HG_Key:="CtrlBreak"

    ;-- Substitute CtrlBreak for Pause (Break would work OK too)
    if (HG_Key="CtrlBreak")
        if not HG_CtrlModifier
            HG_Key:="Pause"

    ;[================]
    ;[  Build Hotkey  ]
    ;[================]
    ;-- Initialize
    HG_Hotkey:=""
    HG_HKDesc:=""

    ;-- Options
    if HG_NativeOption
        HG_Hotkey.="~"

    if HG_WildcardOption
        HG_Hotkey.="*"

    if HG_LeftPairOption
        HG_Hotkey.="<"

    if HG_RightPairOption
        HG_Hotkey.=">"

    ;-- Modifiers
    if HG_CtrlModifier
        {
        HG_Hotkey.="^"
        HG_HKDesc.="Ctrl + "
        }

    if HG_ShiftModifier
        {
        HG_Hotkey.="+"
        HG_HKDesc.="Shift + "
        }

    if HG_WinModifier
        {
        HG_Hotkey.="#"
        HG_HKDesc.="Win + "
        }

    if HG_AltModifier
        {
        HG_Hotkey.="!"
        HG_HKDesc.="Alt + "
        }

    HG_Hotkey.=HG_Key
    HG_HKDesc.=HG_Key

    ;-- Update Hotkey and HKDescr fields
    GUIControl %s_GUI%:,Edit1,%HG_Hotkey%
    GUIControl %s_GUI%:,Static3,%HG_HKDesc%
    return


    ;**********************
    ;*                    *
    ;*    Pair options    *
    ;*                    *
    ;**********************
    HotkeyGUI_LeftPair:

    ;-- Deselect HG_RightPairOption
    GUIControl %s_GUI%:,Button10,0
    gosub HotkeyGUI_UpdateHotkey
    return


    HotkeyGUI_RightPair:

    ;-- Deselect HG_LeftPairOption
    GUIControl %s_GUI%:,Button9,0
    gosub HotkeyGUI_UpdateHotkey
    return


    ;*************************
    ;*                       *
    ;*    Update Key List    *
    ;*                       *
    ;*************************
    HotkeyGUI_UpdateKeyList:

    ;-- Collect form values
    gui %s_GUI%:Submit,NoHide

    ;-- Standard
    if HG_StandardKeysView
        l_KeysList:=l_StandardKeysList
     else
        ;-- Function keys
        if HG_FunctionKeysView
            l_KeysList:=l_FunctionKeysList
         else
            ;-- Numpad
            if HG_NumpadKeysView
                l_KeysList:=l_NumpadKeysList
             else
                ;-- Mouse
                if HG_MouseKeysView
                    l_KeysList:=l_MouseKeysList
                 else
                    ;-- Multimedia
                    if HG_MultimediaKeysView
                        l_KeysList:=l_MultimediaKeysList
                     else
                        ;-- Special
                        if HG_SpecialKeysView
                            l_KeysList:=l_SpecialKeysList

    ;-- Update l_KeysList
    GUIControl %s_GUI%:-Redraw,ListBox1
    GUIControl %s_GUI%:,ListBox1,|%l_KeysList%
    GUIControl %s_GUI%:+Redraw,ListBox1

    ;--- Reset HG_Hotkey and HG_HKDesc
    HG_Key:=""
    gosub HotkeyGUI_UpdateHotkey
    return


    ;***********************
    ;*                     *
    ;*    Accept Button    *
    ;*                     *
    ;***********************
    HotkeyGUI_AcceptButton:

    ;-- (The following test is now redundant but it is retained as a fail-safe)
    ;-- Any key?
    if HG_Key is Space
        {
        gui %s_GUI%:+OwnDialogs
        MsgBox
            ,16         ;-- Error icon
            ,%p_Title%
            ,A key must be selected.  %A_Space%

        return
        }

    ;[===============]
    ;[  Limit tests  ]
    ;[===============]
    l_Limit:=p_Limit
    l_LimitFailure:=False

    ;-- Loop until failure or until all tests have been performed
    Loop
        {
        ;-- Are we done here?
        if (l_limit<=0)
            Break

        ;-----------------
        ;-- Shift+Win+Alt
        ;-----------------
        if (l_limit>=1024)
            {
            if (HG_ShiftModifier and HG_WinModifier and HG_AltModifier)
                {
                l_Message:="SHIFT+WIN+ALT keys are not allowed."
                l_LimitFailure:=True
                Break
                }

            l_limit-=1024
            Continue
            }

        ;------------------
        ;-- Shift+Ctrl+Win
        ;------------------
        if (l_limit>=512)
            {
            if (HG_ShiftModifier and HG_CtrlModifier and HG_WinModifier)
                {
                l_Message:="SHIFT+CTRL+WIN keys are not allowed."
                l_LimitFailure:=True
                Break
                }

            l_limit-=512
            Continue
            }

        ;------------------
        ;-- Shift+Ctrl+Alt
        ;------------------
        if (l_limit>=256)
            {
            if (HG_ShiftModifier and HG_CtrlModifier and HG_AltModifier)
                {
                l_Message:="SHIFT+CTRL+ALT keys are not allowed."
                l_LimitFailure:=True
                Break
                }

            l_limit-=256
            Continue
            }

        ;-------------
        ;-- Shift+Win
        ;-------------
        if (l_limit>=128)
            {
            if (HG_ShiftModifier and HG_WinModifier)
                {
                l_Message:="SHIFT+WIN keys are not allowed."
                l_LimitFailure:=True
                Break
                }

            l_limit-=128
            Continue
            }

        ;-------------
        ;-- Shift+Alt
        ;-------------
        if (l_limit>=64)
            {
            if (HG_ShiftModifier and HG_AltModifier)
                {
                l_Message:="SHIFT+ALT keys are not allowed."
                l_LimitFailure:=True
                Break
                }

            l_limit-=64
            Continue
            }

        ;--------------
        ;-- Shift+Ctrl
        ;--------------
        if (l_limit>=32)
            {
            if (HG_ShiftModifier and HG_CtrlModifier)
                {
                l_Message:="SHIFT+CTRL keys are not allowed."
                l_LimitFailure:=True
                Break
                }

            l_limit-=32
            Continue
            }

        ;------------
        ;-- Win only
        ;------------
        if (l_limit>=16)
            {
            if (HG_WinModifier
            and not (HG_CtrlModifier or HG_ShiftModifier or HG_AltModifier))
                {
                l_Message:="WIN-only keys are not allowed."
                l_LimitFailure:=True
                Break
                }

            l_limit-=16
            Continue
            }

        ;------------
        ;-- Alt only
        ;------------
        if (l_limit>=8)
            {
            if (HG_AltModifier
            and not (HG_CtrlModifier or HG_ShiftModifier or HG_WinModifier))
                {
                l_Message:="ALT-only keys are not allowed."
                l_LimitFailure:=True
                Break
                }

            l_limit-=8
            Continue
            }

        ;-------------
        ;-- Ctrl only
        ;-------------
        if (l_limit>=4)
            {
            if (HG_CtrlModifier
            and not (HG_ShiftModifier or HG_WinModifier or HG_AltModifier))
                {
                l_Message:="CTRL-only keys are not allowed."
                l_LimitFailure:=True
                Break
                }

            l_limit-=4
            Continue
            }

        ;--------------
        ;-- Shift only
        ;--------------
        if (l_limit>=2)
            {
            if (HG_ShiftModifier
            and not (HG_CtrlModifier or HG_WinModifier or HG_AltModifier))
                {
                l_Message:="SHIFT-only keys are not allowed."
                l_LimitFailure:=True
                Break
                }

            l_limit-=2
            Continue
            }

        ;--------------
        ;-- Unmodified
        ;--------------
        if (l_limit>=1)
            {
            if not (HG_CtrlModifier
                or  HG_ShiftModifier
                or  HG_WinModifier
                or  HG_AltModifier)
                {
                l_Message=
                   (ltrim join`s
                    At least one modifier must be used.  Other restrictions
                    may apply.
                   )

                l_LimitFailure:=True
                Break
                }

            l_limit-=1
            Continue
            }
        }

    ;[====================]
    ;[  Display message?  ]
    ;[====================]
    if l_LimitFailure
        {
        ;-- Display message
        gui %s_GUI%:+OwnDialogs
        MsgBox
            ,16         ;-- Error icon
            ,%p_Title%
            ,%l_Message%  %A_Space%

        ;-- Send 'em back
        return
        }

    ;[==================]
    ;[  Ok, We're done  ]
    ;[   Shut it done   ]
    ;[==================]
    gosub HotkeyGUI_Exit
    return


    ;***********************
    ;*                     *
    ;*    Close up shop    *
    ;*                     *
    ;***********************
    HotkeyGUI_Escape:
    HotkeyGUI_Close:
    HG_Hotkey:=p_Hotkey
    l_ErrorLevel:=1


    HotkeyGUI_Exit:

    ;-- Enable Owner window
    if p_Owner
        gui %p_Owner%:-Disabled

    ;-- Destroy the HotkeyGUI window so that the window can be reused
    gui %s_GUI%:Destroy
    s_GUI:=0
    return  ;-- End of subroutines
    }


rbrtryn
  • Members
  • 1177 posts
  • Last active: Sep 11 2013 08:04 PM
  • Joined: 22 Jun 2011
Another way to solve this is to use the expression mode and the dot operator:
gui %s_GUI%:Add
       , CheckBox
       , % "xp+10 yp+20 Disabled Section" 
       . "vHG_NativeOption gHotkeyGUI_UpdateHotkey" ; Note the dot begining this line
       , ~ (Native)
Now that you are using strings in an expression the dot operator is legal.
_________________________
Composed/Posted with WYSIWYG BBCode Editor

DataLife
  • Members
  • 1022 posts
  • Last active: Nov 27 2015 01:09 AM
  • Joined: 27 Apr 2008
I plan on using this in one of my scripts to enable dynamic mouse hotkeys.

I would like to be able to have the Apps key as a choice.

I have looked thru the code and I have not been able to figure out how to add it.

Anyone want to give it a try?
Check out my scripts.  (MyIpChanger) (XPSnap) (SavePictureAs) All my scripts are tested on Windows 7, AutoHotkey 32 bit Ansi unless otherwise stated.

hoangnam099999
  • Members
  • 1 posts
  • Last active: Dec 15 2015 09:24 AM
  • Joined: 15 Dec 2015

Thanks, I can confirm that v0.4 works with 120dpi windows fonts on winxp

 

 

 

 

song bai truc tuyen xoc dia online gai xinh coi thien thai