1 (изменено: zmey78, 2018-05-10 13:53:23)

Тема: AHK: Разное поведение LControl на разных машинах

У меня прекрасно работает этот скрипт на ноутбуке:


~LControl Up::
if (A_PriorKey = "LControl" and (A_TimeSincePriorHotkey > 400 or A_PriorHotkey <> A_ThisHotkey))
{
    Send {Control Down}{Shift}{Control Up}
	SoundBeep, 5000, 100
}
return

Смысл такой, что переключаем язык по Ctrl (как было в DOS), но только если не была нажата еще какая то клавиша, т.е. фильтруем обычные хоткеи.

Попробовал на стационарном компе, нажатие и удержание Ctrl превращается в бесконечный повтор Ctrl Down:

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

A2  01D d 2.48 LControl       
01  000 d 0.06 LButton       
A2  01D d 0.19 LControl        *new 1 - Notepad++
A2  01D d 0.03 LControl       
A2  01D d 0.03 LControl       
A2  01D d 0.03 LControl       
A2  01D d 0.03 LControl       
A2  01D d 0.03 LControl       
A2  01D d 0.03 LControl       
A2  01D d 0.05 LControl       
A2  01D d 0.03 LControl       
A2  01D d 0.03 LControl       
A2  01D d 0.03 LControl       
A2  01D d 0.03 LControl       
A2  01D d 0.03 LControl       
A2  01D d 0.03 LControl       
A2  01D d 0.03 LControl       
A2  01D d 0.03 LControl       
01  000 u 0.02 LButton       
A2  01D d 0.02 LControl       
A2  01D d 0.03 LControl       
A2  01D d 0.05 LControl       
A2  01D d 0.03 LControl       
A2  01D d 0.03 LControl       
A2  01D d 0.03 LControl       
A2  01D d 0.03 LControl       
A2  01D d 0.03 LControl       
A2  01D h u 0.01 LControl       
11  01D i d 0.00 Control       
10  02A i d 0.00 Shift         
10  02A i u 0.00 Shift         
11  01D i u 0.00 Control

Плохо тем, что мой скрипт не видит, например, что я между нажатием и отжатием Ctrl нажимаю кнопку мыши для перетаскивания текста. Соответственно, язык переключается когда не нужно.

Пока придумал вариант, но еще не написал код для него, возможно не будет работать. Хочу послушать советы, как лучше и правильно сделать. А потом приведу свой вариант, чтобы сравнить. Подскажите, пожалуйста!!!

2

Re: AHK: Разное поведение LControl на разных машинах

Попробуйте так:

~LControl Up:: ( A_PriorKey = "LControl" && ChangeLocale() )

ChangeLocale()  {
   ControlGetFocus, CtrlFocus, A
   PostMessage, WM_INPUTLANGCHANGEREQUEST := 0x50, INPUTLANGCHANGE_FORWARD := 0x2,, %CtrlFocus%, A
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3 (изменено: stealzy, 2018-05-10 23:24:51)

Re: AHK: Разное поведение LControl на разных машинах

TimeSincePriorHotkey != TimeSincePriorKey, встроенной переменной для TimeSincePriorKey не предусмотрено. Выконечно можете создать пустой хоткей на нажатие и тогда использовать A_TimeSincePriorHotkey , но системный автоповтор нажатия убъет эту затею.

#MaxHotkeysPerInterval 1000 ; avoid reaction on ~LControl system autorepeat
~LControl:: keyPressed ? : (downTime := A_TickCount, keyPressed := true)
~LControl Up:: !(keyPressed := false) && A_PriorKey = "LControl" && (A_TickCount - downTime < 500) && SwitchLocale()

SwitchLocale()  {
	; ControlGetFocus CtrlFocus, A
	; PostMessage WM_INPUTLANGCHANGEREQUEST := 0x50, INPUTLANGCHANGE_FORWARD := 0x2,, % CtrlFocus, A
	PostMessage WM_INPUTLANGCHANGEREQUEST:=0x50, INPUTLANGCHANGE_FORWARD:=0x2,,, % "ahk_id" ((hWndOwn:=DllCall("GetWindow", Ptr, hWnd:=WinExist("A"), UInt, GW_OWNER:=4, Ptr)) ? hWndOwn : hWnd)
}

Если нужно чтобы работало на панели задач или конкретные языки, загляните сюды:
http://forum.script-coding.com/viewtopic.php?id=12452

4 (изменено: zmey78, 2018-05-10 23:32:40)

Re: AHK: Разное поведение LControl на разных машинах

Спасибо.

Похоже, что оба этих варианта не учитывают, что:
а) системный повтор Ctrl прерывается при нажатии любой клавиши, но не прерывается при нажатии кнопки мышки;
б) при нажатии любой клавиши одновременно с Ctrl (в т.ч. и кнопок мышки), переключение языка не должно происходить.

Вот мой вариант. Он безусловно более примитивный, но учитывает эти 2 момента:


~LControl::
if (!PriorKey)
    PriorKey := "LControl"
else if (A_PriorKey <> "LControl")
    PriorKey := A_PriorKey
return
~LControl Up::
if (A_PriorKey = "LControl" and PriorKey = "LControl")
{
    Send {Control Down}{Shift}{Control Up}
	SoundBeep, 5000, 100
}
PriorKey =
return

Родился в результате ~3ч чтения мануала по AHK. Буду благодарен за критику.

5

Re: AHK: Разное поведение LControl на разных машинах

#MaxHotkeysPerInterval 1000 ; avoid reaction on ~LControl system autorepeat
#If Not (GetKeyState("LButton") || GetKeyState("RButton") || GetKeyState("MButton"))
~LControl:: keyPressed ? : (downTime := A_TickCount, keyPressed := true)
#If keyPressed And Not (GetKeyState("LButton") || GetKeyState("RButton") || GetKeyState("MButton"))
~LControl Up:: !(keyPressed := false) && A_PriorHotKey = "~LControl" && A_TickCount-downTime < 1000 && SwitchLocale()
#If
*~LButton::
*~RButton::
*~MButton::
Return

SwitchLocale()  {
	PostMessage 0x50, 0x2,,, % "ahk_id" ((hWndOwn:=DllCall("GetWindow", Ptr, hWnd:=WinExist("A"), UInt, 4, Ptr)) ? hWndOwn : hWnd)
}