51

Re: AHK: Замена стандартного элемента управления "Hotkey"

Проблема точно не в коде. Попробовал принудительно подставлять эти значения, добавив в LowLevelKeyboardProc()

   if key not in LCtrl,RCtrl,LAlt,RAlt,LShift,RShift,LWin,RWin
      sc := 0x100,  vk := 0xad,  key := "Volume_Mute"

то всё работает нормально. То есть, какая-то "аппаратная" проблема. Кстати, не единственная. Например, если перевести NumLock в положение On и нажать Shift+клавиша на цифровой клавиатуре, то тоже сбрасывается. Так же себя ведёт и обычный контрол Hotkey. У меня так, по-крайней мере.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

52

Re: AHK: Замена стандартного элемента управления "Hotkey"

Возможно, проблема в том, что такие клавиши в сочетании с модификаторами не посылают при отпускании WM_KEYUP (или WM_SYSKEYUP). Это можно проверить, добавив в секцию

if (Message = WM_KEYUP || Message = WM_SYSKEYUP)

SoundBeep.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

53

Re: AHK: Замена стандартного элемента управления "Hotkey"

С ММ клавишами проблем нет в моём варианте. Единственно в сочетаниях с Win некоторые не определяются, как будто их не нажимаешь.

Например, если перевести NumLock в положение On и нажать Shift+клавиша на цифровой клавиатуре, то тоже сбрасывается

Да а такое действительно в любых вариантах кодов.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

54

Re: AHK: Замена стандартного элемента управления "Hotkey"

В общем, дело тёмное

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

55

Re: AHK: Замена стандартного элемента управления "Hotkey"

Ага. А ты говоришь - ТЗ

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

56

Re: AHK: Замена стандартного элемента управления "Hotkey"

Если моё предположение верное, вот так должно работать с медийными клавишами, проверьте:

Gui, Add, Edit, hwndhEdit1 gHotkey w150 h20 Center
fn := HotkeyInit(hEdit1)   ; fn — ссылка на функцию, которая будет получать строку с горячей клавишей

Gui, Add, Edit, vShowHotkey w150 h20 Center
Gui, Show
return

Hotkey:
   GuiControl, %A_Gui%:, ShowHotkey, % HotkeyString := fn.()
;  Hotkey, % HotkeyString, HKLabel, On UseErrorLevel ; раскомментировать для установки хоткея
   return

HKLabel:
   MsgBox, Вы нажали горячую клавишу %A_ThisHotkey%
   return

GuiClose:
   ExitApp

HotkeyInit(handle)
{
   if !IsObject(Create.array.handles)
      SetWinEventHook(0x8005, 0x8005, 0, RegisterCallback("HookProc", "F"),0,0,0)   ; EVENT_OBJECT_FOCUS := 0x8005
         , Create.array.handles := []
   
   Create.array.handles.Insert(handle)
   ControlSetText,, Нет, % "ahk_id" handle
   
   return Func("GetHkString")
}

Class Create
{
   static array := {}
}

GetHkString()
{
   HotkeyString := Create.array.HK
   Create.array.HK := ""
   return HotkeyString
}

SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags)
{
   return DllCall("SetWinEventHook" , UInt, eventMin
                                    , UInt, eventMax
                                    , Ptr, hmodWinEventProc
                                    , Ptr, lpfnWinEventProc
                                    , UInt, idProcess
                                    , UInt, idThread
                                    , UInt, dwFlags, Ptr)
}

HookProc(hWinEventHook, event, hwnd)
{
   for k,v in Create.array.handles
      if (hwnd = v)
         IsValue := 1, Create.array.hControl := v
   
   if (IsValue && !Create.array.hHook)
      Create.array.hHook := SetWindowsHookEx()
   else if (!IsValue && Create.array.hHook)
   {
      DllCall("UnhookWindowsHookEx", Ptr, Create.array.hHook)
      Create.array.keys := Create.array.hHook := ""
   }
   
   for k,v in Create.array.handles
   {
      ControlGetText, Text,, ahk_id %v%
      if SubStr(Text, -1) = "+ "
         ControlSetText,, Нет, ahk_id %v%
   }
}

SetWindowsHookEx()
{
   Return DllCall("SetWindowsHookEx" . (A_IsUnicode ? "W" : "A")
      , Int, WH_KEYBOARD_LL := 13
      , Ptr, RegisterCallback("LowLevelKeyboardProc", "Fast")
      , Ptr, DllCall("GetModuleHandle", UInt, 0, Ptr)
      , UInt, 0, Ptr)
}

LowLevelKeyboardProc(nCode, wParam, lParam)
{
   static WM_KEYDOWN := 0x100, WM_KEYUP := 0x101, WM_SYSKEYDOWN := 0x104, WM_SYSKEYUP := 0x105
      , EndKey, prevMessage, prevKey
   
   SetBatchLines, -1
   SetFormat, IntegerFast, H
   Message := wParam, Extended := NumGet(lParam+0, 8, "UInt") & 1
   sc := Extended << 8 | NumGet(lParam+0, 4, "UInt")
   vk := NumGet(lParam+0, 0, "UInt")
   key := GetKeyName("vk" SubStr(vk, 3) "sc" SubStr(sc, 3))
   
   if (Message = prevMessage && key = prevKey)
      Return nCode < 0 ? DllCall("CallNextHookEx", Ptr, 0, Int, nCode, UInt, wParam, UInt, lParam) : 1
   prevMessage := Message, prevKey := key
   
   if key in LControl,RControl
      key := SubStr(key, 1, 1) . "Ctrl"
   if (sc = 0x145)
      key := "NumLock"
   
   if (Message = WM_KEYDOWN || Message = WM_SYSKEYDOWN)
   {
      if key in LCtrl,RCtrl,LAlt,RAlt,LShift,RShift,LWin,RWin
      {
         EndKey ? Create.array.keys := EndKey := ""
         
         if !InStr(Create.array.keys, key)
            Create.array.keys .= key . " + "
      }
      else
      {
         EndKey := 1
         if (SubStr(Create.array.keys, -1) = "+ " || Create.array.keys = "")
            Create.array.keys .= key
         else
            Create.array.keys := RegExReplace(Create.array.keys, "(.*?)\S+$", "$1" key)
         
         Create.array.LastKey := "vk" . SubStr(vk, 3)  . "sc" . SubStr(sc, 3)
      }
   }
   
   if (Message = WM_KEYUP || Message = WM_SYSKEYUP)
   {
      if key in LCtrl,RCtrl,LAlt,RAlt,LShift,RShift,LWin,RWin
         Create.array.keys := RegExReplace(Create.array.keys, key . " \+ ")
         
      if !EndKey
         SetTimer, SetText, -10
      
      Return DllCall("CallNextHookEx", Ptr, 0, Int, nCode, UInt, wParam, UInt, lParam)
   }

   SetTimer, SetText, -10
   Return nCode < 0 ? DllCall("CallNextHookEx", Ptr, 0, Int, nCode, UInt, wParam, UInt, lParam) : 1
   
SetText:
   keys := Create.array.keys, LastKey := Create.array.LastKey
   if (keys != "" && keys != "Нет" && Substr(keys, -1) != "+ ")
   {
      Loop, parse, keys, +, % " "
      {
         IsSym := ""
         for k,v in {Ctrl: "^", Alt: "!", Shift: "+", Win: "#"}
            if InStr(A_LoopField, k) && A_LoopField != "CtrlBreak"
               HKString .= (SubStr(A_LoopField, 1, 1) = "L" ? "<" : ">") . v, IsSym := 1
         
         if !IsSym
         {
            if StrLen(A_LoopField) > 1
               HKString .= InStr(A_LoopField, "Num") ? RegExReplace(LastKey, ".*(s.*)", "$1") : A_LoopField
            else
               HKString .= RegExReplace(LastKey, "(.*)s.*", "$1")
         }
      }
      Create.array.HK := HKString
   }
   ControlSetText,, % keys = "" ? "Нет" : keys, % "ahk_id" Create.array.hControl
   return
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

57 (изменено: serzh82saratov, 2013-08-21 00:41:09)

Re: AHK: Замена стандартного элемента управления "Hotkey"

Нет. Теперь при нажатии ММ кнопка мелькает. То есть исчезает до того как её отпустишь.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

58

Re: AHK: Замена стандартного элемента управления "Hotkey"

Это с модификаторами, или без?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

59

Re: AHK: Замена стандартного элемента управления "Hotkey"

Только с модификаторами.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

60

Re: AHK: Замена стандартного элемента управления "Hotkey"

А так?

Gui, Add, Edit, hwndhEdit1 gHotkey w150 h20 Center
fn := HotkeyInit(hEdit1)   ; fn — ссылка на функцию, которая будет получать строку с горячей клавишей

Gui, Add, Edit, vShowHotkey w150 h20 Center
Gui, Show
return

Hotkey:
   GuiControl, %A_Gui%:, ShowHotkey, % HotkeyString := fn.()
;  Hotkey, % HotkeyString, HKLabel, On UseErrorLevel ; раскомментировать для установки хоткея
   return

HKLabel:
   MsgBox, Вы нажали горячую клавишу %A_ThisHotkey%
   return

GuiClose:
   ExitApp

HotkeyInit(handle)
{
   if !IsObject(Create.array.handles)
      SetWinEventHook(0x8005, 0x8005, 0, RegisterCallback("HookProc", "F"),0,0,0)   ; EVENT_OBJECT_FOCUS := 0x8005
         , Create.array.handles := []
   
   Create.array.handles.Insert(handle)
   ControlSetText,, Нет, % "ahk_id" handle
   
   return Func("GetHkString")
}

Class Create
{
   static array := {}
}

GetHkString()
{
   HotkeyString := Create.array.HK
   Create.array.HK := ""
   return HotkeyString
}

SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags)
{
   return DllCall("SetWinEventHook" , UInt, eventMin
                                    , UInt, eventMax
                                    , Ptr, hmodWinEventProc
                                    , Ptr, lpfnWinEventProc
                                    , UInt, idProcess
                                    , UInt, idThread
                                    , UInt, dwFlags, Ptr)
}

HookProc(hWinEventHook, event, hwnd)
{
   for k,v in Create.array.handles
      if (hwnd = v)
         IsValue := 1, Create.array.hControl := v
   
   if (IsValue && !Create.array.hHook)
      Create.array.hHook := SetWindowsHookEx()
   else if (!IsValue && Create.array.hHook)
   {
      DllCall("UnhookWindowsHookEx", Ptr, Create.array.hHook)
      Create.array.keys := Create.array.hHook := ""
   }
   
   for k,v in Create.array.handles
   {
      ControlGetText, Text,, ahk_id %v%
      if SubStr(Text, -1) = "+ "
         ControlSetText,, Нет, ahk_id %v%
   }
}

SetWindowsHookEx()
{
   Return DllCall("SetWindowsHookEx" . (A_IsUnicode ? "W" : "A")
      , Int, WH_KEYBOARD_LL := 13
      , Ptr, RegisterCallback("LowLevelKeyboardProc", "Fast")
      , Ptr, DllCall("GetModuleHandle", UInt, 0, Ptr)
      , UInt, 0, Ptr)
}

LowLevelKeyboardProc(nCode, wParam, lParam)
{
   static WM_KEYDOWN := 0x100, WM_KEYUP := 0x101, WM_SYSKEYDOWN := 0x104, WM_SYSKEYUP := 0x105
      , EndKey, prevMessage, prevKey
   
   SetBatchLines, -1
   SetFormat, IntegerFast, H
   Message := wParam, Extended := NumGet(lParam+0, 8, "UInt") & 1
   sc := Extended << 8 | NumGet(lParam+0, 4, "UInt")
   vk := NumGet(lParam+0, 0, "UInt")
   key := GetKeyName("vk" SubStr(vk, 3) "sc" SubStr(sc, 3))
   
   if key in LControl,RControl
      key := SubStr(key, 1, 1) . "Ctrl"
   if (sc = 0x145)
      key := "NumLock"
   
   if (Message = WM_KEYDOWN || Message = WM_SYSKEYDOWN)
   {
      if key in LCtrl,RCtrl,LAlt,RAlt,LShift,RShift,LWin,RWin
      {
         EndKey ? Create.array.keys := EndKey := ""
         if !InStr(Create.array.keys, key)
            Create.array.keys .= key . " + "
      }
      else
      {
         EndKey := 1
         if (SubStr(Create.array.keys, -1) = "+ " || Create.array.keys = "")
            Create.array.keys .= key
         else
            Create.array.keys := RegExReplace(Create.array.keys, "(.*?)\S+$", "$1" key)
         
         Create.array.LastKey := "vk" . SubStr(vk, 3)  . "sc" . SubStr(sc, 3)
      }
   }
   
   if (Message = WM_KEYUP || Message = WM_SYSKEYUP)
   {
      if key in LCtrl,RCtrl,LAlt,RAlt,LShift,RShift,LWin,RWin
         Create.array.keys := RegExReplace(Create.array.keys, key . " \+ ")
      else
         EndKey := 1
         
      if !EndKey
         SetTimer, SetText, -10
      
      Return DllCall("CallNextHookEx", Ptr, 0, Int, nCode, UInt, wParam, UInt, lParam)
   }

   SetTimer, SetText, -10
   Return nCode < 0 ? DllCall("CallNextHookEx", Ptr, 0, Int, nCode, UInt, wParam, UInt, lParam) : 1
   
SetText:
   keys := Create.array.keys, LastKey := Create.array.LastKey
   if (keys != "" && keys != "Нет" && Substr(keys, -1) != "+ ")
   {
      Loop, parse, keys, +, % " "
      {
         IsSym := ""
         for k,v in {Ctrl: "^", Alt: "!", Shift: "+", Win: "#"}
            if InStr(A_LoopField, k) && A_LoopField != "CtrlBreak"
               HKString .= (SubStr(A_LoopField, 1, 1) = "L" ? "<" : ">") . v, IsSym := 1
         
         if !IsSym
         {
            if StrLen(A_LoopField) > 1
               HKString .= InStr(A_LoopField, "Num") ? RegExReplace(LastKey, ".*(s.*)", "$1") : A_LoopField
            else
               HKString .= RegExReplace(LastKey, "(.*)s.*", "$1")
         }
      }
      Create.array.HK := HKString
   }
   ControlSetText,, % keys = "" ? "Нет" : keys, % "ahk_id" Create.array.hControl
   return
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

61

Re: AHK: Замена стандартного элемента управления "Hotkey"

А так ещё хуже. Мелькает теперь очень быстро и через раз.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

62

Re: AHK: Замена стандартного элемента управления "Hotkey"

Ну ладно, последний вариант, или придётся новую клаву покупать

Gui, Add, Edit, hwndhEdit1 gHotkey w150 h20 Center
fn := HotkeyInit(hEdit1)   ; fn — ссылка на функцию, которая будет получать строку с горячей клавишей

Gui, Add, Edit, vShowHotkey w150 h20 Center
Gui, Show
return

Hotkey:
   GuiControl, %A_Gui%:, ShowHotkey, % HotkeyString := fn.()
;  Hotkey, % HotkeyString, HKLabel, On UseErrorLevel ; раскомментировать для установки хоткея
   return

HKLabel:
   MsgBox, Вы нажали горячую клавишу %A_ThisHotkey%
   return

GuiClose:
   ExitApp

HotkeyInit(handle)
{
   if !IsObject(Create.array.handles)
      SetWinEventHook(0x8005, 0x8005, 0, RegisterCallback("HookProc", "F"),0,0,0)   ; EVENT_OBJECT_FOCUS := 0x8005
         , Create.array.handles := []
   
   Create.array.handles.Insert(handle)
   ControlSetText,, Нет, % "ahk_id" handle
   
   return Func("GetHkString")
}

Class Create
{
   static array := {}
}

GetHkString()
{
   HotkeyString := Create.array.HK
   Create.array.HK := ""
   return HotkeyString
}

SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags)
{
   return DllCall("SetWinEventHook" , UInt, eventMin
                                    , UInt, eventMax
                                    , Ptr, hmodWinEventProc
                                    , Ptr, lpfnWinEventProc
                                    , UInt, idProcess
                                    , UInt, idThread
                                    , UInt, dwFlags, Ptr)
}

HookProc(hWinEventHook, event, hwnd)
{
   for k,v in Create.array.handles
      if (hwnd = v)
         IsValue := 1, Create.array.hControl := v
   
   if (IsValue && !Create.array.hHook)
      Create.array.hHook := SetWindowsHookEx()
   else if (!IsValue && Create.array.hHook)
   {
      DllCall("UnhookWindowsHookEx", Ptr, Create.array.hHook)
      Create.array.keys := Create.array.hHook := ""
   }
   
   for k,v in Create.array.handles
   {
      ControlGetText, Text,, ahk_id %v%
      if SubStr(Text, -1) = "+ "
         ControlSetText,, Нет, ahk_id %v%
   }
}

SetWindowsHookEx()
{
   Return DllCall("SetWindowsHookEx" . (A_IsUnicode ? "W" : "A")
      , Int, WH_KEYBOARD_LL := 13
      , Ptr, RegisterCallback("LowLevelKeyboardProc", "Fast")
      , Ptr, DllCall("GetModuleHandle", UInt, 0, Ptr)
      , UInt, 0, Ptr)
}

LowLevelKeyboardProc(nCode, wParam, lParam)
{
   static WM_KEYDOWN := 0x100, WM_KEYUP := 0x101, WM_SYSKEYDOWN := 0x104, WM_SYSKEYUP := 0x105
      , EndKey, prevMessage, prevKey
   
   SetBatchLines, -1
   SetFormat, IntegerFast, H
   Message := wParam, Extended := NumGet(lParam+0, 8, "UInt") & 1
   sc := Extended << 8 | NumGet(lParam+0, 4, "UInt")
   vk := NumGet(lParam+0, 0, "UInt")
   key := GetKeyName("vk" SubStr(vk, 3) "sc" SubStr(sc, 3))
   
   if (Message = prevMessage && key = prevKey)
      Return nCode < 0 ? DllCall("CallNextHookEx", Ptr, 0, Int, nCode, UInt, wParam, UInt, lParam) : 1
   prevMessage := Message, prevKey := key
   
   if key in LControl,RControl
      key := SubStr(key, 1, 1) . "Ctrl"
   if (sc = 0x145)
      key := "NumLock"
   
   if (Message = WM_KEYDOWN || Message = WM_SYSKEYDOWN)
   {
      if key in LCtrl,RCtrl,LAlt,RAlt,LShift,RShift,LWin,RWin
      {
         EndKey ? Create.array.keys := EndKey := ""
         if !InStr(Create.array.keys, key)
            Create.array.keys .= key . " + "
      }
      else
      {
         EndKey := 1
         if (SubStr(Create.array.keys, -1) = "+ " || Create.array.keys = "")
            Create.array.keys .= key
         else
            Create.array.keys := RegExReplace(Create.array.keys, "(.*?)\S+$", "$1" key)
         
         Create.array.LastKey := "vk" . SubStr(vk, 3)  . "sc" . SubStr(sc, 3)
      }
   }
   
   if (Message = WM_KEYUP || Message = WM_SYSKEYUP)
   {
      if key in LCtrl,RCtrl,LAlt,RAlt,LShift,RShift,LWin,RWin
         Create.array.keys := RegExReplace(Create.array.keys, key . " \+ ")
      else
         EndKey := 1
         
      if !EndKey
         SetTimer, SetText, -10
      
      Return DllCall("CallNextHookEx", Ptr, 0, Int, nCode, UInt, wParam, UInt, lParam)
   }

   SetTimer, SetText, -10
   Return nCode < 0 ? DllCall("CallNextHookEx", Ptr, 0, Int, nCode, UInt, wParam, UInt, lParam) : 1
   
SetText:
   keys := Create.array.keys, LastKey := Create.array.LastKey
   if (keys != "" && keys != "Нет" && Substr(keys, -1) != "+ ")
   {
      Loop, parse, keys, +, % " "
      {
         IsSym := ""
         for k,v in {Ctrl: "^", Alt: "!", Shift: "+", Win: "#"}
            if InStr(A_LoopField, k) && A_LoopField != "CtrlBreak"
               HKString .= (SubStr(A_LoopField, 1, 1) = "L" ? "<" : ">") . v, IsSym := 1
         
         if !IsSym
         {
            if StrLen(A_LoopField) > 1
               HKString .= InStr(A_LoopField, "Num") ? RegExReplace(LastKey, ".*(s.*)", "$1") : A_LoopField
            else
               HKString .= RegExReplace(LastKey, "(.*)s.*", "$1")
         }
      }
      Create.array.HK := HKString
   }
   ControlSetText,, % keys = "" ? "Нет" : keys, % "ahk_id" Create.array.hControl
   return
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

63

Re: AHK: Замена стандартного элемента управления "Hotkey"

Тоже самое.
Придётся покупать

И джойстик заодно

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

64

Re: AHK: Замена стандартного элемента управления "Hotkey"

Не, джойстик ни за что.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

65

Re: AHK: Замена стандартного элемента управления "Hotkey"

Эхх. А я всё надеюсь на хуко - джой от teadrinker.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

66 (изменено: serzh82saratov, 2013-08-21 19:35:37)

Re: AHK: Замена стандартного элемента управления "Hotkey"

Что скажете про работоспособность такого варианта? Вроде бы как, все переменные локальны.

+ открыть спойлер


#SingleInstance Force
Gui, Add, Edit, Center w300 gWriteIni vMyHotkey1
Gui, Add, Edit, Center wp gWriteIni vMyHotkey2
Gui, Add, Edit, wp vEdit
Hotkey_Init("MyHotkey1|MyHotkey2")
Gui, Show
return
 
WriteIni:
    GuiControl, , Edit, % A_GuiControl " = " %A_GuiControl%
    return

GuiClose:
    ExitApp



Hotkey_Init(Control, Read = 0)  {
    Static ControlArr := {}, IsStart
    If (Read)
        Return ControlArr["H" Control]    
    SaveFormat := A_FormatInteger
    SetFormat, IntegerFast, H
    Loop, Parse, Control, |
    {
        RegExMatch(A_LoopField, "S)(.*:)?\s*(.*)", D)  
        GuiControlGet, Hwnd, % D1 "Hwnd", % D2
        ControlArr.Insert("H" Hwnd, D2)
    }
    ControlGetFocus, IsFocus, A
    ControlGet, FocusHwnd, Hwnd,, %IsFocus%, A
    If ControlArr.HasKey("H" FocusHwnd)
        Hotkey_Main("", "", FocusHwnd)
    If (!IsStart)
        Hotkey_SetWinEventHook(0x8005, 0x8005, 0, RegisterCallback("Hotkey_Main", "F"),0,0,0)
        , IsStart := 1   ; EVENT_OBJECT_FOCUS := 0x8005 
    SetFormat, IntegerFast, %SaveFormat%
}

Hotkey_Main(Param1, Param2, Param3) {
    Static Hook, DelStr, VarName, ControlHandle, PrHandle, Hotkey, KeyName
        , MCtrl, MAlt, MShift, MWin, PCtrl, PAlt, PShift, PWin, Prefix
        , Pref := {"Alt":"!","Ctrl":"^","Shift":"+","Win":"#"}
        , Symbols := "|vkBA|vkBB|vkBC|vkBD|vkBE|vkBF|vkC0|vkDB|vkDC|vkDD|vkDE|vk41|vk42|"
                        . "vk43|vk44|vk45|vk46|vk47|vk48|vk49|vk4A|vk4B|vk4C|vk4D|vk4E|"
                        . "vk4F|vk50|vk51|vk52|vk53|vk54|vk55|vk56|vk57|vk58|vk59|vk5A|" 
    SetBatchLines, -1
    If (Param3)
    {
        SaveFormat := A_FormatInteger
        SetFormat, IntegerFast, H
        If ((Name := Hotkey_Init(Param3, 1)) != "")
        {
            If (DelStr)
                SendMessage, 0xC, 0, "Нет", , ahk_id %PrHandle%
            DelStr := 0, VarName := Name, ControlHandle := PrHandle := Param3, Hotkey := " "
            If !Hook
                Hook := Hotkey_SetWindowsHookEx()
            Send {LButton Up} 
            PostMessage,0x00B1,,,, ahk_id %ControlHandle%    ;    EM_SETSEL := 0x00B1
        }
        else If Hook
        {
            DllCall("UnhookWindowsHookEx" , Ptr, Hook)
            MCtrl := MAlt := MShift := MWin := Hook := "", Hotkey := " "
            PCtrl := PAlt := PShift := PWin := Prefix := ""
            If (DelStr)
                SendMessage, 0xC, 0, "Нет", , ahk_id %ControlHandle%
        }
        SetFormat, IntegerFast, %SaveFormat%
        Return
    }
    If (Param1 = "Mod")
    {
        IsMod := Param2 
        If (M%IsMod% != "")
            Return 
        M%IsMod% := IsMod "+", P%IsMod% := Pref[IsMod]
    }
    Else If (Param1 = "ModUp")
    {
        IsMod := Param2, M%IsMod% := P%IsMod% := "" 
        If (Hotkey != "")
            Return 
    }
    (IsMod != "") ? (KeyName := Hotkey := Prefix := "", DelStr := 1)
    : ( KeyName := GetKeyName(Param1 Param2), DelStr := 0
    , Hotkey := InStr(Symbols, "|" Param1 "|") ? Param1 : KeyName
    , Prefix := PCtrl PAlt PShift PWin)
    Hotkey_SetVarName(VarName, Prefix Hotkey)
    WriteText := MCtrl MAlt MShift MWin KeyName = ""
    ? "Нет" : MCtrl MAlt MShift MWin KeyName
    SendMessage, 0xC, 0, &WriteText, , ahk_id %ControlHandle%
    Return 
}

Hotkey_LowLevelKeyboardProc(nCode, wParam, lParam)  {
    Static Mods := {"vkA4":"Alt","vkA5":"Alt","vkA2":"Ctrl","vkA3":"Ctrl"
                ,"vkA0":"Shift","vkA1":"Shift","vk5B":"Win","vk5C":"Win"}
    SetBatchLines, -1
    SaveFormat := A_FormatInteger
    SetFormat, IntegerFast, H
    VkCode := "vk" SubStr( NumGet(lParam+0, 0, "UInt"), 3)
        D := NumGet(lParam+0, 8, "UInt") & 1
        D := D << 8 | NumGet(lParam+0, 4, "UInt")
    SCCode := "sc" SubStr(D, 3)
    SetFormat, IntegerFast, %SaveFormat%
    IF (wParam = 0x100 || wParam = 0x104)    ;    WM_KEYDOWN := 0x100, WM_SYSKEYDOWN := 0x104
    {
        IF IsMod := Mods[VkCode]
            Hotkey_Main("Mod", IsMod, "")
        Else
            Hotkey_Main(VkCode, SCCode, "")
        Return nCode < 0 ? DllCall("CallNextHookEx", Ptr, 0, Int, nCode, UInt, wParam, UInt, lParam) : 1
    }
   IF ((wParam = 0x101 || wParam = 0x105) && VkCode != "vk5D") ;  WM_KEYUP := 0x101, WM_SYSKEYUP := 0x105, AppsKey = "vk5D"
   {
        IF IsMod := Mods[VkCode]
            Hotkey_Main("ModUp", IsMod, "")
        Return DllCall("CallNextHookEx", Ptr, 0, Int, nCode, UInt, wParam, UInt, lParam)
    }
    Return nCode < 0 ? DllCall("CallNextHookEx", Ptr, 0, Int, nCode, UInt, wParam, UInt, lParam) : 1
}

Hotkey_SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags) {
    Return DllCall("SetWinEventHook" , UInt, eventMin
                                    , UInt, eventMax
                                    , Ptr, hmodWinEventProc
                                    , Ptr, lpfnWinEventProc
                                    , UInt, idProcess
                                    , UInt, idThread
                                    , UInt, dwFlags, Ptr)
}

Hotkey_SetWindowsHookEx() {
   Return DllCall("SetWindowsHookEx" . (A_IsUnicode ? "W" : "A")
      , Int, 13 ; WH_KEYBOARD_LL := 13
      , Ptr, RegisterCallback("Hotkey_LowLevelKeyboardProc", "Fast")
      , Ptr, DllCall("GetModuleHandle", UInt, 0, Ptr)
      , UInt, 0, Ptr)
}

Hotkey_SetVarName(Name, Value) {
    Global
    %Name% := Value
}

Ещё вопрос:
может ли библиотека считаться библиотекой, если в ней присутствует метка?

Например, если перевести NumLock в положение On и нажать Shift+клавиша на цифровой клавиатуре, то тоже сбрасывается

Я так понял что Shift является аппаратным модификаторов Num-цифр.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

67

Re: AHK: Замена стандартного элемента управления "Hotkey"

В целом всё работает,такие мелкие недостатки:
Клавиши цифровой клавиатуры определяются в зависимости от NumLock-статуса, соответственно, и срабатывать будут также. Можно, конечно, сказать, что это фича, но на практике лишь внесёт путаницу.
Неправильно определяется Ctrl+NumLock.

Глобальная переменная всё же есть:

Hotkey_SetVarName(Name, Value) {
    Global
    %Name% := Value
}

Метка не помешает.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

68

Re: AHK: Замена стандартного элемента управления "Hotkey"

Тут ещё проблема наших вариантов, если вызвать контекстное меню Edit, то хук снимается. А лучше как и в оригинале исключить меню совсем. Стиля Edit такого ненашёл. На ум приходит только хоткей правой кнопки

Метка не помешает.

А если название переклинется с пользовательским?

Глобальная переменная всё же есть:

Только та, которая уже существует у Edit-ов. Так что не в счёт.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

69

Re: AHK: Замена стандартного элемента управления "Hotkey"

У меня, вроде, не снимается. Можно делать пустой хоткей правой кнопки, когда нужный контрол в фокусе.

serzh82saratov пишет:

А если название переклинется с пользовательским?

Ну так и название функции может пересечься. Ничего, просто интерпретатор выдаст ошибку.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

70

Re: AHK: Замена стандартного элемента управления "Hotkey"

Неправильно определяется Ctrl+NumLock

Всё правильно,  хоткея ^NumLock нет. Есть ^Pause.

Клавиши цифровой клавиатуры определяются в зависимости от NumLock-статуса, соответственно, и срабатывать будут также. Можно, конечно, сказать, что это фича, но на практике лишь внесёт путаницу.

У меня мини клава. Ничего сказать немогу, но как я понял ты предлагаешь определять не все кнопки цифровой клавиатуры.
На виртуальной клаве в твоём коде также зависимость от NumLock.

У меня, вроде, не снимается.

Поводи мышью по меню.

Можно делать пустой хоткей правой кнопки, когда нужный контрол в фокусе.

Не кашерно как-то. Там хотя бы определять что мышь именно над полем ввода надо, но тоже не айс.

Ну так и название функции может пересечься. Ничего, просто интерпретатор выдаст ошибку.

Насколько я знаю, при использовании библиотек учитывается только префикс названий функций.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

71

Re: AHK: Замена стандартного элемента управления "Hotkey"

Всё правильно,  хоткея ^NumLock нет. Есть ^Pause.

Да, точно.

На виртуальной клаве в твоём коде также зависимость от NumLock.

Не совсем понял. У меня они по сканкодам записываются, а сканкоды в любом статусе NumLock одинаковые.

Там хотя бы определять что мышь именно над полем ввода надо, но тоже не айс.

Почему?

Насколько я знаю, при использовании библиотек учитывается только префикс названий функций.

М-м-м... Учитывается для чего? Если в библиотеке MyLib.ahk есть две функции: одна с названием MyLib(), другая с названием Test(), то последнюю интерпретатор будет учитывать, если предварительно вызвана функция с названием MyLib(). Так что если в коде пользователя окажется определение функции Test(), интерпретатор выдаст ошибку.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

72

Re: AHK: Замена стандартного элемента управления "Hotkey"

Почему?

Некрасиво. Может как то можно SetWinEventHook ето определять, и не снимать хук.

М-м-м... Учитывается для чего?

Я про либы, которые можно использовать по умолчанию из папки АНК.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

73

Re: AHK: Замена стандартного элемента управления "Hotkey"

Может как то можно SetWinEventHook ето определять, и не снимать хук.

Можно определять класс окна по параметру hwnd, в Win 7 класс меню ahk_class #32768. Но на XP как-то по-другому, вроде, не помню сейчас.

Я про либы, которые можно использовать по умолчанию из папки АНК.

Я про них же. В библиотеке не обязательно все функции должны быть с одним и тем же префиксом.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

74

Re: AHK: Замена стандартного элемента управления "Hotkey"

Можно определять класс окна по параметру hwnd, в Win 7 класс меню ahk_class #32768. Но на XP как-то по-другому, вроде, не помню сейчас.

EVENT_SYSTEM_MENUPOPUPSTART := 0x0006, EVENT_SYSTEM_MENUPOPUPEND := 0x0007

Так работает. Но WinHide ahk_id %id%, допускает мелькания меню. Думаю дальше что с этим делать.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

75

Re: AHK: Замена стандартного элемента управления "Hotkey"

Если хочешь совсем избавиться от появления меню, тогда либо хоткей на RButton, либо запускать ещё и мышиный хук.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg