 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
shimanov
Joined: 25 Sep 2005 Posts: 610
|
Posted: Fri Sep 30, 2005 3:52 am Post subject: custom hotkey control |
|
|
The script contains code for implementation of a custom hotkey control. It follows, in principle, the grammar and semantics of AHk. The goal was to introduce an architecture to enable supplementing existing capabilities in as seamless and transparent manner as possible. In this regard, I decided to use functions to replace the Gui command, but retain its defined usage otherwise. In fact, the built-in Gui command and the Gui function can coexist, and the Gui function employs the Gui command for creation of Gui components.
Obviously, this is meant as a means to enhance AHk until desired capabilities are added natively. It also lends itself to research and development of enhancement concepts, which may provide Chris a shortcut when it comes time to update AHk.
This particular example is not quite complete, but sufficiently so that I decided to submit it for feedback. As a hotkey control it displays information for a single key, but provides the means to recognize combinations of keys. Technically, the method used is able recognize any number of keys depressed (e.g., Ctrl+1, Left Shift+Space+1+2+3+A, etc.); however, there are technical limitations (at the moment) which allow far less. Just watch the ToolTips. The codes in the "states" ToolTip can be interpreted with information from the MSDN Virtual -Key Codes page.
I have tested the code with Windows XP SP2, with an IBM notebook and Microsoft Natural keyboards, and the latest AHk v1.0.38.06. It should work.
Anyway... here is the code:
(Notice the coexistance of two "hotkey controls", and the similarity of their function and appearance)
| Code: |
#InstallKeybdHook
Gui, Add, Text, x5 y10, Custom Hotkey Control 1:
Gui( "Add", "Hotkey", "x5 y25 w300 h40 gSubGuiHotkey1 vVarGuiHotkey1", "Left Ctrl+Z" )
Gui, Add, Text, x5 y70, Custom Hotkey Control 2:
;Gui( "Add", "Hotkey", "x5 y85 w300 h40 gSubGuiHotkey2 vVarGuiHotkey2", "Left Shift+A" )
Gui, Add, Edit, x5 y85 w300 h40, or not
Gui, Add, Text, x5 y130, Default Hotkey Control:
Gui, Add, Hotkey, x5 y145 w300 h40 gSubGuiHotkeyD vVarGuiHotkeyD
Gui, Show, x100 y100 w310 h200, test window
Gui, 2:Add, Text, x5 y10, Custom Hotkey Control 3:
;Gui( "2:Add", "Hotkey", "x5 y25 w300 h40 gSubGuiHotkey3 vVarGuiHotkey3", "Left Ctrl+Right Shift+Z" )
Gui, 2:Add, Edit, x5 y25 w300 h40, another pretender
Gui, 2:Add, Text, x5 y70, Custom Hotkey Control 4:
Gui( "2:Add", "Hotkey", "x5 y85 w300 h40 gSubGuiHotkey4 vVarGuiHotkey4", "Left Shift+Left Alt+A" )
Gui, 2:Show, x100 y350 w310 h200, test window
return
GuiClose:
2GuiClose:
ExitApp
SubGuiHotkey1:
CoordMode, ToolTip, relative
text = VarGuiHotkey1 = %VarGuiHotkey1%
text := text "`nVarGuiHotkey1@name = " QueryComponent( "VarGuiHotkey1@name" )
ToolTip, %text%, 320, 75, 1
return
SubGuiHotkey2:
CoordMode, ToolTip, relative
text = VarGuiHotkey2 = %VarGuiHotkey2%
text := text "`nVarGuiHotkey2@name = " QueryComponent( "VarGuiHotkey2@name" )
ToolTip, %text%, 320, 115, 2
return
SubGuiHotkey3:
CoordMode, ToolTip, relative
text = VarGuiHotkey3 = %VarGuiHotkey3%
text := text "`nVarGuiHotkey3@name = " QueryComponent( "VarGuiHotkey3@name" )
ToolTip, %text%, 320, 75, 3
return
SubGuiHotkey4:
CoordMode, ToolTip, relative
text = VarGuiHotkey4 = %VarGuiHotkey4%
text := text "`nVarGuiHotkey4@name = " QueryComponent( "VarGuiHotkey4@name" )
ToolTip, %text%, 320, 115, 4
return
SubGuiHotkeyD:
CoordMode, ToolTip, relative
text = a_GuiControl = %a_GuiControl%
text = %text%`nVarGuiHotkeyD = %VarGuiHotkeyD%
ToolTip, %text%, 320, 175, 5
return
Gui( p_command, p_param2="", p_param3="", p_param4="" )
{
; -- identify window number --
StringGetPos, ix, p_command, :
if ( ix = -1 )
gui_num = 1
else
{
StringLeft, gui_num, p_command, ix
StringTrimLeft, p_command, p_command, ix+1
}
if ( p_command = "Add" )
{
if ( p_param2 = "Hotkey" )
{
ctrl_num := QueryComponent( gui_num ":Hotkey_Control" )
if ( ! ctrl_num )
RegisterComponent( gui_num ":Hotkey_Control" )
hw_script := FindWindowEx( 0, 0, "AutoHotkeyGUI", a_ScriptName )
loop,
{
ctrl_num++
if ( ! FindWindow( hw_script, "Edit", ctrl_num ) )
break
}
UpdateComponent( gui_num ":Hotkey_Control", ctrl_num )
; -- identify associated g(oSubroutine) --
StringGetPos, ix, p_param3, %a_Space%g
if ( ix = -1 )
StringGetPos, ix, p_param3, `,g
if ( ix != -1 )
{
pName := &p_param3+( ix+2-1 )
subName=
loop,
{
temp := *( pName+a_Index )
if ( temp = 0 or temp = 32 or temp = 44 )
break
subName := subName Chr( temp )
}
}
; -- identify associated v(ariable) --
StringGetPos, ix, p_param3, %a_Space%v
if ( ix = -1 )
StringGetPos, ix, p_param3, `,v
if ( ix != -1 )
{
pName := &p_param3+( ix+2-1 )
varName=
loop,
{
temp := *( pName+a_Index )
if ( temp = 0 or temp = 32 or temp = 44 )
break
varName := varName Chr( temp )
}
}
if p_param4=
Gui, %gui_num%:Add, Edit, %p_param3% -VScroll, None
else
Gui, %gui_num%:Add, Edit, %p_param3% -VScroll, %p_param4%
hw_control := FindWindow( hw_script, "Edit", QueryComponent( gui_num ":Hotkey_Control" ) )
RegisterControl( hw_control, "Hotkey_Control", subName, varName )
RegisterComponent( varName "@name" )
RegisterComponent( "WM_CONTEXTMENU", 0x7B )
RegisterComponent( "WM_KEYDOWN", 0x100 )
RegisterComponent( "WM_SYSKEYDOWN", 0x104 )
OnMessage( QueryComponent( "WM_CONTEXTMENU" ), "HandleMessage" )
OnMessage( QueryComponent( "WM_KEYDOWN" ), "HandleMessage" )
OnMessage( QueryComponent( "WM_SYSKEYDOWN" ), "HandleMessage" )
}
}
}
HandleMessage( p_w, p_l, p_m, p_hw )
{
if ( QueryControl( p_hw ) = "Hotkey_Control" )
{
if ( p_m = QueryComponent( "WM_CONTEXTMENU" ) )
return, 0
else if ( p_m = QueryComponent( "WM_KEYDOWN" )
or p_m = QueryComponent( "WM_SYSKEYDOWN" ) )
{
VarSetCapacity( key_name, 100 )
VarSetCapacity( kb_state, 256, 0 )
DllCall( "GetKeyboardState", "uint", &kb_state )
old_FormatInteger := a_FormatInteger
SetFormat, Integer, hex
kb_state_text=
loop, 256
if ( *( &kb_state+a_Index ) & 0x80 )
kb_state_text := kb_state_text "|" a_Index
SetFormat, Integer, %old_FormatInteger%
extended := p_l & 0x1000000
if ( extended )
kb_state_text = %kb_state_text%`nextended
if ( *( &kb_state+0x14 ) & 0x1 )
kb_state_text = %kb_state_text%`ncaps lock
if ( *( &kb_state+0x90 ) & 0x1 )
kb_state_text = %kb_state_text%`nnum lock
if ( *( &kb_state+0x91 ) & 0x1 )
kb_state_text = %kb_state_text%`nscroll lock
CoordMode, ToolTip, relative
ToolTip, %kb_state_text% , 320, 0, 6
hk_name=
hkc_var=
hkc_var_name=
; -- identify modifiers --
if ( *( &kb_state+0x5B ) & 0x80 )
{
hk_name = +Left Windows
hkc_var = <#
hkc_var_name = +LWin
Hotkey, LWin Up, hk_LWin_Up, on
}
else if ( *( &kb_state+0x5C ) & 0x80 )
{
hk_name = +Right Windows
hkc_var = >#
hkc_var_name = +RWin
Hotkey, RWin Up, hk_RWin_Up, on
}
if ( *( &kb_state+0x12 ) & 0x80 )
{
if ( *( &kb_state+0xA4 ) & 0x80 )
{
hk_name = %hk_name%+Left Alt
hkc_var = %hkc_var%<!
hkc_var_name = %hkc_var_name%+LAlt
}
else if ( *( &kb_state+0xA5 ) & 0x80 )
{
hk_name = %hk_name%+Right Alt
hkc_var = %hkc_var%>!
hkc_var_name = %hkc_var_name%+RAlt
}
else
{
hk_name = %hk_name%+Alt
hkc_var = %hkc_var%!
hkc_var_name = %hkc_var_name%+Alt
}
}
if ( ( *( &kb_state+0x11 ) & 0x80 )
and GetKeyState( "Control" ,"P" ) )
{
if ( *( &kb_state+0xA2 ) & 0x80 )
{
hk_name = %hk_name%+Left Ctrl
hkc_var = %hkc_var%<^
hkc_var_name = %hkc_var_name%+LControl
}
else if ( *( &kb_state+0xA3 ) & 0x80 )
{
hk_name = %hk_name%+Right Ctrl
hkc_var = %hkc_var%>^
hkc_var_name = %hkc_var_name%+RControl
}
else
{
hk_name = %hk_name%+Ctrl
hkc_var = %hkc_var%^
hkc_var_name := %hkc_var_name% "+Control"
}
}
if ( *( &kb_state+0x10 ) & 0x80 )
{
if ( *( &kb_state+0xA0 ) & 0x80 )
{
hk_name = %hk_name%+Left Shift
hkc_var = %hkc_var%<+
hkc_var_name = %hkc_var_name%+LShift
}
else if ( *( &kb_state+0xA1 ) & 0x80 )
{
hk_name = %hk_name%+Right Shift
hkc_var = %hkc_var%>+
hkc_var_name = %hkc_var_name%+RShift
}
else
{
hk_name = %hk_name%+Left Shift
hkc_var = %hkc_var%+
hkc_var_name = %hkc_var_name%+Shift
}
}
; -- identify key --
if ( *( &kb_state+0x3 ) & 0x80 )
{
hk_name = %hk_name%+Break
hkc_var = %hkc_var%CtrlBreak
hkc_var_name = %hkc_var_name%+CtrlBreak
}
else if ( *( &kb_state+0x90 ) & 0x80 )
{
hk_name = %hk_name%+Num Lock
hkc_var = %hkc_var%NumLock
hkc_var_name = %hkc_var_name%+NumLock
}
else if ( *( &kb_state+0x1B ) & 0x80 )
{
hk_name = %hk_name%+Esc
hkc_var = %hkc_var%Escape
hkc_var_name = %hkc_var_name%+Escape
}
else if ( *( &kb_state+0x14 ) & 0x80 )
{
hk_name = %hk_name%+Caps Lock
hkc_var = %hkc_var%CapsLock
hkc_var_name = %hkc_var_name%+CapsLock
}
else if ( *( &kb_state+0x5D ) & 0x80 )
{
hk_name = %hk_name%+Application
hkc_var = %hkc_var%AppsKey
hkc_var_name = %hkc_var_name%+AppsKey
}
else if ( *( &kb_state+0x91 ) & 0x80 )
{
hk_name = %hk_name%+Scroll Lock
hkc_var = %hkc_var%ScrollLock
hkc_var_name = %hkc_var_name%+ScrollLock
}
else if ( extended and *( &kb_state+0x21 ) & 0x80 )
{
hk_name = %hk_name%+Page Up
hkc_var = %hkc_var%PgUp
hkc_var_name = %hkc_var_name%+PgUp
}
else if ( extended and *( &kb_state+0x22 ) & 0x80 )
{
hk_name = %hk_name%+Page Down
hkc_var = %hkc_var%PgDn
hkc_var_name = %hkc_var_name%+PgDn
}
else if ( *( &kb_state+0x6F ) & 0x80 )
{
hk_name = %hk_name%+Num /
hkc_var = %hkc_var%NumpadDiv
hkc_var_name = %hkc_var_name%+NumpadDiv
}
else if ( *( &kb_state+0x6A ) & 0x80 )
{
hk_name = %hk_name%+Num *
hkc_var = %hkc_var%NumpadMult
hkc_var_name = %hkc_var_name%+NumpadMult
}
else if ( *( &kb_state+0x6B ) & 0x80 )
{
hk_name = %hk_name%+Num +
hkc_var = %hkc_var%NumpadAdd
hkc_var_name = %hkc_var_name%+NumpadAdd
}
else if ( *( &kb_state+0x6D ) & 0x80 )
{
hk_name = %hk_name%+Num -
hkc_var = %hkc_var%NumpadSub
hkc_var_name = %hkc_var_name%+NumpadSub
}
else if ( extended and *( &kb_state+0xD ) & 0x80 )
{
hk_name = %hk_name%+Num Enter
hkc_var = %hkc_var%NumpadEnter
hkc_var_name = %hkc_var_name%+NumpadEnter
}
else if ( ! extended and *( &kb_state+0x2E ) & 0x80 )
{
hk_name = %hk_name%+Num Del
hkc_var = %hkc_var%NumpadDel
hkc_var_name = %hkc_var_name%+NumpadDel
}
else if ( *( &kb_state+0x6E ) & 0x80 )
{
hk_name = %hk_name%+Num Dot
hkc_var = %hkc_var%NumpadDot
hkc_var_name = %hkc_var_name%+NumpadDot
}
else if ( ! extended and *( &kb_state+0x2D ) & 0x80 )
{
hk_name = %hk_name%+Num Ins
hkc_var = %hkc_var%NumpadIns
hkc_var_name = %hkc_var_name%+NumpadIns
}
else if ( *( &kb_state+0x60 ) & 0x80 )
{
hk_name = %hk_name%+Num 0
hkc_var = %hkc_var%Numpad0
hkc_var_name = %hkc_var_name%+Numpad0
}
else if ( ! extended and *( &kb_state+0x23 ) & 0x80 )
{
hk_name = %hk_name%+Num End
hkc_var = %hkc_var%NumpadEnd
hkc_var_name = %hkc_var_name%+NumpadEnd
}
else if ( *( &kb_state+0x61 ) & 0x80 )
{
hk_name = %hk_name%+Num 1
hkc_var = %hkc_var%Numpad1
hkc_var_name = %hkc_var_name%+Numpad1
}
else if ( ! extended and *( &kb_state+0x28 ) & 0x80 )
{
hk_name = %hk_name%+Num Down
hkc_var = %hkc_var%NumpadDown
hkc_var_name = %hkc_var_name%+NumpadDown
}
else if ( *( &kb_state+0x62 ) & 0x80 )
{
hk_name = %hk_name%+Num 2
hkc_var = %hkc_var%Numpad2
hkc_var_name = %hkc_var_name%+Numpad2
}
else if ( *( &kb_state+0x22 ) & 0x80 )
{
hk_name = %hk_name%+Num Page Down
hkc_var = %hkc_var%NumpadPgDn
hkc_var_name = %hkc_var_name%+NumpadPgDn
}
else if ( *( &kb_state+0x63 ) & 0x80 )
{
hk_name = %hk_name%+Num 3
hkc_var = %hkc_var%Numpad3
hkc_var_name = %hkc_var_name%+Numpad3
}
else if ( ! extended and *( &kb_state+0x25 ) & 0x80 )
{
hk_name = %hk_name%+Num Left
hkc_var = %hkc_var%NumpadLeft
hkc_var_name = %hkc_var_name%+NumpadLeft
}
else if ( *( &kb_state+0x64 ) & 0x80 )
{
hk_name = %hk_name%+Num 4
hkc_var = %hkc_var%Numpad4
hkc_var_name = %hkc_var_name%+Numpad4
}
else if ( *( &kb_state+0xC ) & 0x80 )
{
hk_name = %hk_name%+Num Clear
hkc_var = %hkc_var%NumpadClear
hkc_var_name = %hkc_var_name%+NumpadClear
}
else if ( *( &kb_state+0x65 ) & 0x80 )
{
hk_name = %hk_name%+Num 5
hkc_var = %hkc_var%Numpad5
hkc_var_name = %hkc_var_name%+Numpad5
}
else if ( ! extended and *( &kb_state+0x27 ) & 0x80 )
{
hk_name = %hk_name%+Num Right
hkc_var = %hkc_var%NumpadRight
hkc_var_name = %hkc_var_name%+NumpadRight
}
else if ( *( &kb_state+0x66 ) & 0x80 )
{
hk_name = %hk_name%+Num 6
hkc_var = %hkc_var%Numpad6
hkc_var_name = %hkc_var_name%+Numpad6
}
else if ( ! extended and *( &kb_state+0x24 ) & 0x80 )
{
hk_name = %hk_name%+Num Home
hkc_var = %hkc_var%NumpadHome
hkc_var_name = %hkc_var_name%+NumpadHome
}
else if ( *( &kb_state+0x67 ) & 0x80 )
{
hk_name = %hk_name%+Num 7
hkc_var = %hkc_var%Numpad7
hkc_var_name = %hkc_var_name%+Numpad7
}
else if ( ! extended and *( &kb_state+0x26 ) & 0x80 )
{
hk_name = %hk_name%+Num Up
hkc_var = %hkc_var%NumpadUp
hkc_var_name = %hkc_var_name%+NumpadUp
}
else if ( *( &kb_state+0x68 ) & 0x80 )
{
hk_name = %hk_name%+Num 8
hkc_var = %hkc_var%Numpad8
hkc_var_name = %hkc_var_name%+Numpad8
}
else if ( *( &kb_state+0x21 ) & 0x80 )
{
hk_name = %hk_name%+Num Page Up
hkc_var = %hkc_var%NumpadPgUp
hkc_var_name = %hkc_var_name%+NumpadPgUp
}
else if ( *( &kb_state+0x69 ) & 0x80 )
{
hk_name = %hk_name%+Num 9
hkc_var = %hkc_var%Numpad9
hkc_var_name = %hkc_var_name%+Numpad9
}
else if ( *( &kb_state+0xA6 ) & 0x80 )
{
hk_name = %hk_name%+Browser Back
hkc_var = %hkc_var%Browser_Back
hkc_var_name = %hkc_var_name%+Browser_Back
}
else if ( *( &kb_state+0xA7 ) & 0x80 )
{
hk_name = %hk_name%+Browser Forward
hkc_var = %hkc_var%Browser_Forward
hkc_var_name = %hkc_var_name%+Browser_Forward
}
else
{
sc := ( p_l >> 16 ) & 0xFF
if ( ! ( extended and ( sc = 0x5B or sc = 0x5C ) ) )
{
old_FormatInteger := a_FormatInteger
SetFormat, Integer, hex
vk := DllCall( "MapVirtualKey", "uint", sc, "uint", 1 )
SetFormat, Integer, %old_FormatInteger%
if vk not in 0x12,0xA4,0xA5,0x11,0xA2,0xA3,0x10,0xA0,0xA1
{
DllCall( "GetKeyNameText"
, "int", p_l
, "str", key_name
, "int", 100 )
hk_name = %hk_name%+%key_name%
hkc_var = %hkc_var%%key_name%
hkc_var_name = %hkc_var_name%+%key_name%
}
}
}
StringTrimLeft, hk_name, hk_name, 1
StringTrimLeft, hkc_var_name, hkc_var_name, 1
temp := QueryControl( p_hw, "var" )
GuiControl,, %temp%, %hk_name%
%temp% := hkc_var
UpdateComponent( temp "@name", hkc_var_name )
if ( ! RegisterComponent( "timer_HandleMessage#sub", QueryControl( p_hw, "sub" ) ) )
UpdateComponent( "timer_HandleMessage#sub", QueryControl( p_hw, "sub" ) )
SetTimer, timer_HandleMessage, 10
return, 0
}
}
return
timer_HandleMessage:
SetTimer, timer_HandleMessage, off
sub := QueryComponent( "timer_HandleMessage#sub" )
Gosub, %sub%
return
hk_LWin_Up:
Hotkey, LWin Up, off
Send, {Esc}
return
hk_RWin_Up:
Hotkey, RWin Up, off
Send, {Esc}
return
}
RegisterComponent( p_id, p_data="", p_command="" )
{
static components
if ( p_command = "query" )
{
loop, Parse, components, |
{
ix := InStr( a_LoopField, "," )
StringLeft, id, a_LoopField, ix-1
if ( id = p_id )
return, a_LoopField
}
return, false
}
else if ( p_command = "update" )
{
ix_1 := InStr( components, "|" p_id )
ix_2 := InStr( components, "|", false, ix_1+1 )
if ( ! ix_2 )
ix_2 := StrLen( components )+1
StringMid, prefix, components, 1, ix_1-1
StringMid, suffix, components, ix_2, StrLen( components )-ix_2+1
components = %prefix%|%p_id%,%p_data%%suffix%
return, true
}
else if ( ! QueryComponent( p_id ) )
{
components = %components%|%p_id%,%p_data%
return, true
}
return, false
}
UpdateComponent( p_id, p_data="" )
{
RegisterComponent( p_id, p_data, "update" )
QueryComponent( 0 )
}
QueryComponent( p_id )
{
static id, data
if ( p_id = 0 )
id = 0
else if ( id != p_id )
{
component := RegisterComponent( p_id, 0, "query" )
if ( ! component )
return, false
id := p_id
ix_1 := InStr( component, "," )
StringMid, data, component, ix_1+1, StrLen( component )-ix_1
}
return, data
}
RegisterControl( p_hw, p_type, p_sub="", p_var="", p_command="" )
{
return, RegisterComponent( p_hw, p_type "," p_sub "," p_var, p_command )
}
QueryControl( p_hw, p_field="" )
{
static hw, type, sub, var
if ( hw != p_hw )
{
control := RegisterControl( p_hw, 0, 0, 0, "query" )
if ( ! control )
return, false
hw := p_hw
ix_1 := InStr( control, "," )
ix_2 := InStr( control, ",", false, ix_1+1 )
ix_3 := InStr( control, ",", false, ix_2+1 )
StringMid, type, control, ix_1+1, ix_2-ix_1-1
StringMid, sub, control, ix_2+1, ix_3-ix_2-1
StringMid, var, control, ix_3+1, StrLen( control )-ix_3
}
if ( p_field = "type" or p_field = "" )
return, type
else if ( p_field = "sub" )
return, sub
else if ( p_field = "var" )
return, var
}
FindWindow( p_hw_parent, p_class, p_num=1, p_title=0 )
{
hw_child = 0
loop, %p_num%
hw_child := FindWindowEx( p_hw_parent, hw_child, p_class, p_title )
return, hw_child
}
FindWindowEx( p_hw_parent, p_hw_child, p_class, p_title=0 )
{
if ( p_title = 0 )
type_title = uint
else
type_title = str
return, DllCall( "FindWindowEx"
, "uint", p_hw_parent
, "uint", p_hw_child
, "str", p_class
, type_title, p_title )
}
|
Last edited by shimanov on Fri Feb 17, 2006 6:13 pm; edited 8 times in total |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10716
|
Posted: Fri Sep 30, 2005 4:23 am Post subject: |
|
|
Holy mackerel, my socks have been knocked off!
Thanks for sharing this amazing script.  |
|
| Back to top |
|
 |
shimanov
Joined: 25 Sep 2005 Posts: 610
|
Posted: Tue Oct 04, 2005 8:28 am Post subject: Update: 2005.10.04 |
|
|
Changes:
* display and assignment of key combinations (modifiers+key)
* assigned variable (var) contains modifiers+key (compatible with AHk?)
* var@name contains full text names of modifiers+key
* introduced concept of registered components and controls
- permits global, unique data storage (variant of a list)
|
|
| Back to top |
|
 |
Terrapin
Joined: 15 Aug 2005 Posts: 107 Location: North Carolina
|
Posted: Sun Oct 09, 2005 8:20 am Post subject: Re: custom hotkey control |
|
|
Shimanov, hello. I was interested in this as I am using hotkey controls in a helper app I'm writing. So I got around to trying it out. I'm not at all certain whether you intend it to be used, or used in it's current status?
In any case, I ran across two problems. Most likely they are due to my inability to use the function correctly, but I cannot figure out why.
One is very simple, and appears simply by running your script on my computer. If I press either Windows key, it seems to be duplicated or doubled, ie 'Left-Windows+Left-Windows'.
Next I attempted to incorporate the control in place of one of my hotkey controls from AHK (directly). I got the AHK error 'a control's variable must be global.' I tried making a very simple GUI in another script, and got the same message. I was able to declare my associated variable global, by name, at the appropriate location in your code (just after 'varName' is created and before the Edit control is called).
I noticed in your most recent post on this thread a comment about variables, but I don't understand it, I'm afraid. Nor do I understand why I don't get the error when running your script.
Again, I am a little unclear whether you are submitting your function for others to use or not. But, a comment on my part would be that in my app I don't want to distinguish between left & right 'shift' keys. I probably could filter out your < & >, but I wonder if another parameter to tell the function how you would like it to work would be appropriate?
It would also be very handy in either the AHK command or your function, if a key-combination keyed in could be intercepted before it can get to Windows, or any app, if it is already assigned. Possibly a 'warning' message could be displayed by the caller of your function in the case of an errorlevel code being returned.
In respect, I studied your code some and you are far advanced beyond my skills, so anything I've said above is intended very humbly.
I am also using WinXP SP2, on an Athlon 64 and an Asus mobo.
Thank You,
Bob
(Sometime later.... I figured out how to prevent the error, you probably guessed I neglected to include the lines from the g-label subroutine. I don't know how to construct those lines on my own though. But I - geek that I am - learned by poring through your code. On the Win keys, I don't know. Does any key reset the hotkey to Null?) |
|
| Back to top |
|
 |
shimanov
Joined: 25 Sep 2005 Posts: 610
|
Posted: Sun Oct 09, 2005 8:48 pm Post subject: Re: custom hotkey control |
|
|
| Terrapin wrote: | | Shimanov, hello. |
Hello.
| Quote: | | I'm not at all certain whether you intend it to be used, or used in it's current status? |
It was intended to be a proof of concept of a general architecture to enhance existing built-in GUI functionality. However, the primary purpose is to demonstrate the capabilities and flexibility of AHk to others.
| Quote: | | If I press either Windows key, it seems to be duplicated or doubled, ie 'Left-Windows+Left-Windows'. |
A bug, but not quite. Windows maps the scan code (sc) for each of the "Windows key"s to two virtual key codes (vkc) each. In addition to vkc = 0x5B and vkc = 0x5C, it also maps to 0xF1 and 0xEA (so called OEM specific keys). The original code design, did not make this evident.
| Quote: | | I noticed in your most recent post on this thread a comment about variables, but I don't understand it, I'm afraid. |
assigned variable (var) contains modifiers+key
This refers to the "associated variable" as defined for the AHk Gui command. It will contain hotkey information compatible with what would be assigned while using the default hotkey control.
var@name contains full text names of modifiers+key
This variable uses the name of the "assigned variable" with a literal suffix "@name". It will contain full names of keys pressed (e.g., LControl rather than <^).
| Quote: | | But, a comment on my part would be that in my app I don't want to distinguish between left & right 'shift' keys. |
Support for distinguishing between the left and right keys, and for extended keys was the primary purpose for introducing a custom hotkey control.
| Quote: | | I probably could filter out your < & > |
That approach is as good as any.
| Quote: | | but I wonder if another parameter to tell the function how you would like it to work would be appropriate? |
My intention was to provide the most information possible, in as usable a form as possible. There may be many exceptions to the default design, so it would probably be best to leave the control as is.
In addition, to minimize the learning curve, I set the criteria for the custom control to match, as much as possible, the default control in function and appearance. This included the GUI function call.
| Quote: | | It would also be very handy in either the AHK command or your function, if a key-combination keyed in could be intercepted before it can get to Windows, or any app, if it is already assigned. |
Check the update. It was on my to do, thanks for reminding me.
| Quote: | | In respect, ... so anything I've said above is intended very humbly. |
Fair criticism is always acceptable.
| Quote: | | I don't know how to construct those lines on my own though. |
You could send me a "private message" or post in the "Ask for Help" forum.
| Quote: | | learned by poring through your code. |
That is why I decided to share the code.
| Quote: | | Does any key reset the hotkey to Null? |
I thought to make this user-definable, but I have held off because it would require a change from the existing syntax. I decided not to choose a fixed key, because someone may want to use that particular key in their Hotkey. |
|
| Back to top |
|
 |
shimanov
Joined: 25 Sep 2005 Posts: 610
|
Posted: Sun Oct 09, 2005 8:54 pm Post subject: update: 2005.10.09 |
|
|
Changes:
* support for multiple hotkey controls in multiple windows
* support to mask L/RWin and AppsKey effects
Known issue:
* coexistance with other "Edit" controls
I am considering registering a custom class, to simplify distinguishing between "Edit" and custom hotkey controls. But this will be left for a later update. |
|
| Back to top |
|
 |
Terrapin
Joined: 15 Aug 2005 Posts: 107 Location: North Carolina
|
Posted: Mon Oct 10, 2005 7:31 am Post subject: Re: custom hotkey control |
|
|
Thank You. I worked with it more and have it working I think, but there are one or two things I could probably do a better way. I will work with it more, and as you suggest either pm you or post in the Help Forum.
I appreciate it!
Bob |
|
| Back to top |
|
 |
toralf
Joined: 31 Jan 2005 Posts: 3910 Location: Bremen, Germany
|
Posted: Wed Nov 23, 2005 8:48 am Post subject: |
|
|
Hi Shimanov,
I tested your script. It is brilliant. But I wonder what benefit it gives the general user? Does it have advantages over the default hotkey control?
I'm very sorry, I might be blind. As far as I understood, it dublicates the default hotkey control functionality and therefore gives the ability to test new abilities just by programming in AHK. Am I right? _________________ Ciao
toralf  |
|
| Back to top |
|
 |
shimanov
Joined: 25 Sep 2005 Posts: 610
|
Posted: Wed Nov 23, 2005 9:29 am Post subject: |
|
|
| toralf wrote: | | It is brilliant. |
Thank you.
| toralf wrote: | | But I wonder what benefit it gives the general user? Does it have advantages over the default hotkey control? |
It permits detection and provides information, which is a superset of the default control.
* detection/display of Pause, Ctrl-Break combination, Browser Back/Forward, etc.
* distinguishes between Left and Right key variants (e.g., Shift) |
|
| Back to top |
|
 |
shimanov
Joined: 25 Sep 2005 Posts: 610
|
Posted: Wed Nov 23, 2005 9:40 am Post subject: update: 2005.11.23 |
|
|
Changes:
* coexistance with other "Edit" controls |
|
| Back to top |
|
 |
shimanov
Joined: 25 Sep 2005 Posts: 610
|
Posted: Wed Nov 23, 2005 9:10 pm Post subject: |
|
|
| toralf wrote: | | But I wonder what benefit it gives the general user? |
... and, just as important, the enhancements were requested. But, I suppose, "Guest"s come and go. |
|
| Back to top |
|
 |
toralf
Joined: 31 Jan 2005 Posts: 3910 Location: Bremen, Germany
|
Posted: Thu Nov 24, 2005 6:55 am Post subject: |
|
|
Thank you very much for the expalnations. Maybe you should point out the benefits of your code in respect to the original hotkey command in your first post more clearly.
Thanks for sharing. _________________ Ciao
toralf  |
|
| Back to top |
|
 |
shimanov
Joined: 25 Sep 2005 Posts: 610
|
Posted: Thu Nov 24, 2005 7:45 am Post subject: |
|
|
| toralf wrote: | | Maybe you should point out the benefits of your code in respect to the original hotkey command in your first post more clearly. |
That would be too easy.
Fortunately, a few industrious individuals deciphered the code and made the determination as to the general purpose.
Honestly, the primary purpose was a concept demonstration. The general usefulness was simply icing.
| Quote: | | The goal was to introduce an architecture to enable supplementing existing capabilities in as seamless and transparent manner as possible. |
|
|
| Back to top |
|
 |
Terrapin
Joined: 15 Aug 2005 Posts: 107 Location: North Carolina
|
Posted: Thu Nov 24, 2005 2:10 pm Post subject: |
|
|
@Toralf:
My primary interest in the "enhanced" control was, I think, simply that it allows the Win keys. I was coding a helper app for another program, and the author of that program wanted Win keys available as shift/modifier keys.
However, I am mostly self-taught at coding, so working through some very well constructed code was helpful to me (I hope). I still can be pretty sloppy.
Bob _________________ When it comes to Binary, there are 10 types of people. Those who get it and those who don't.  |
|
| Back to top |
|
 |
shimanov
Joined: 25 Sep 2005 Posts: 610
|
Posted: Fri Feb 17, 2006 2:26 am Post subject: update: 2006.02.16 |
|
|
changes:
* ...@name is initialized with contents of fourth parameter
Thanks to incith for reporting this deficiency.
edit: 2006.02.17
The change was insufficient to correct the deficiency.
For those who are interested, modify the code to support the following syntax:
| Code: | | Gui( "Add", "Hotkey", "x5 y25 w300 h40 gSubGuiHotkey1 vVarGuiHotkey1", "Left Shift", "LShift" ) |
or something similar. |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|