AutoHotkey Community

It is currently May 27th, 2012, 12:45 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: custom hotkey control
PostPosted: September 30th, 2005, 4:52 am 
Offline

Joined: September 25th, 2005, 4:31 pm
Posts: 610
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 February 17th, 2006, 7:13 pm, edited 8 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 30th, 2005, 5:23 am 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
Holy mackerel, my socks have been knocked off! :shock:

Thanks for sharing this amazing script. 8)


Report this post
Top
 Profile  
Reply with quote  
 Post subject: Update: 2005.10.04
PostPosted: October 4th, 2005, 9:28 am 
Offline

Joined: September 25th, 2005, 4:31 pm
Posts: 610
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)


Report this post
Top
 Profile  
Reply with quote  
PostPosted: October 9th, 2005, 9:20 am 
Offline

Joined: August 15th, 2005, 7:15 am
Posts: 107
Location: North Carolina
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. :D On the Win keys, I don't know. Does any key reset the hotkey to Null?)


Report this post
Top
 Profile  
Reply with quote  
PostPosted: October 9th, 2005, 9:48 pm 
Offline

Joined: September 25th, 2005, 4:31 pm
Posts: 610
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject: update: 2005.10.09
PostPosted: October 9th, 2005, 9:54 pm 
Offline

Joined: September 25th, 2005, 4:31 pm
Posts: 610
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.


Report this post
Top
 Profile  
Reply with quote  
PostPosted: October 10th, 2005, 8:31 am 
Offline

Joined: August 15th, 2005, 7:15 am
Posts: 107
Location: North Carolina
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 23rd, 2005, 9:48 am 
Offline

Joined: January 31st, 2005, 9:50 am
Posts: 3910
Location: Bremen, Germany
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
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 23rd, 2005, 10:29 am 
Offline

Joined: September 25th, 2005, 4:31 pm
Posts: 610
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)


Report this post
Top
 Profile  
Reply with quote  
 Post subject: update: 2005.11.23
PostPosted: November 23rd, 2005, 10:40 am 
Offline

Joined: September 25th, 2005, 4:31 pm
Posts: 610
Changes:

    * coexistance with other "Edit" controls


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 23rd, 2005, 10:10 pm 
Offline

Joined: September 25th, 2005, 4:31 pm
Posts: 610
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 24th, 2005, 7:55 am 
Offline

Joined: January 31st, 2005, 9:50 am
Posts: 3910
Location: Bremen, Germany
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
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 24th, 2005, 8:45 am 
Offline

Joined: September 25th, 2005, 4:31 pm
Posts: 610
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 24th, 2005, 3:10 pm 
Offline

Joined: August 15th, 2005, 7:15 am
Posts: 107
Location: North Carolina
@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. :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject: update: 2006.02.16
PostPosted: February 17th, 2006, 3:26 am 
Offline

Joined: September 25th, 2005, 4:31 pm
Posts: 610
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.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: Bon, maul.esel, Yahoo [Bot] and 18 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group