Autohotkey:在激活某些窗口时打开/关闭大写锁定

时间:2013-11-12 17:26:26

标签: autohotkey

我想编写一个脚本,当我激活一个包含标题中特定关键字的窗口(如SQL)时,它会打开大写锁定。当我切换到标题不包含我指定的任何关键字的窗口时,我还希望关闭大写锁定。

我该怎么办?我已经考虑#Persistent定时器来定期检查活动窗口。但是,我认为应该有更好的方法。

6 个答案:

答案 0 :(得分:2)

如果您想在不使用SetTimer的情况下执行此操作,最好的方法是使用context-sensitive个热键。例如:

SetTitleMatchMode, 2

#If WinActive("SQL") or WinActive("Notepad")
    a::A
    b::B
    c::C
    d::D
    e::E
    ;; etc.

如果您想避免使用非常长的WinActive行,也可以使用#If函数与Window Groups代替标题。

编辑:不区分大小写的示例

SetTitleMatchMode, Regex

GroupAdd, Editor, (?i).*sql ; Regular expression for window title
GroupAdd, Editor, (?i).*ahk

#IfWinActive ahk_group Editor
    a::A
    b::B
    c::C
    d::D
    e::E
    ;; etc.

答案 1 :(得分:2)

由于您的代码中有自动功能,因此以下是自动执行功能的方法。

Opt("SendCapslockMode", 0)

While 1

    Sleep(200)
    $title = WinGetTitle("", ""); will get the title of the active window

    If StringInStr($title, "sql") Then
        Send("{CAPSLOCK ON}")
    Else
        Send("{CAPSLOCK OFF}")
    EndIf

WEnd

答案 2 :(得分:2)

检查答案:http://www.reddit.com/r/AutoHotkey/comments/1qjf83/force_specific_program_to_use_caps/。特别是G33kDude的答案。这是一个聪明而有效的解决方案:检查当前窗口仅绑定到Windows激活。

=======================

编辑:下面插入的代码。 请注意,这不是一个完整的解决方案,您需要根据自己的需要进行一些编辑。但不是很大。

#Persistent ; Don't close when the auto-execute ends

SetTitleMatchMode, 2 ; Partial title matching
WinGet, myHwnd, ID, Notepad ; Get the handle to the your window

; Listen for activation messages to all windows
DllCall("CoInitialize", "uint", 0)
if (!hWinEventHook := DllCall("SetWinEventHook", "uint", 0x3, "uint",     0x3, "uint", 0, "uint", RegisterCallback("HookProc"), "uint", 0, "uint", 0,     "uint", 0))
{
    MsgBox, Error creating shell hook
    Exitapp
}

;MsgBox, Hook made
;DllCall("UnhookWinEvent", "uint", hWinEventHook) ; Remove the     message listening hook
return

; Handle the messages we hooked on to
HookProc(hWinEventHook, event, hwnd, idObject, idChild,     dwEventThread, dwmsEventTime)
{
    global myHwnd
    static lastHwnd
    WinGetTitle, title, ahk_id %hwnd%

    if (hwnd == myHwnd) ; If our window was just activated
    {
        tooltip, Gained focus
    }
    else if (lastHwnd == myHwnd) ; If our window was just     deactivated
    {
        tooltip, Lost focus
    }

    lastHwnd := hwnd
}

答案 3 :(得分:1)

Milos'答案很简单,但它错过了一个重要的观点。您需要将SendCapslockMode设置为0。否则Send命令的效果将毫无用处,因为在命令之后将恢复原始状态。

接下来就是,你不需要使用带有Sleep的无限循环,它将每隔几毫秒执行一次完整的循环体,但你可以等待活动窗口不再活动,这是CPU密集度较低。因此,AutoIt中一个完全可行的解决方案是:

Opt("SendCapslockMode", 0)

While True
   $win = WinGetHandle("[ACTIVE]")

   If StringInStr(WinGetTitle($win), "sql") Then
      Send("{CAPSLOCK ON}")
   Else
      Send("{CAPSLOCK OFF}")
   EndIf

   WinWaitNotActive($win)
WEnd

答案 4 :(得分:0)

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.


; This script solves the problem of forgetting to turn on or off the capslock when using specific programs
; I for one ALWAYS use capital letters when typing things in CAD. My problem was when switching to another
; program, usually e-mail, I'd start typing and then have to erase it. Problem solved!

; The beauty of this script is that you don't lose the ability to manually turn the capslock on or off 
; My first few interations of this script would turn it on when in the CAD window but then
; I'd never be able to turn it on wihtout it being forced off again.


Loop    {

state := GetKeyState("Capslock", "T")        ; check toggle state, save in variable 'state'

if state = 0
    status = Off                ; this block converts the 1 or 0 of variable 'state'
if state = 1                    ; into the word ON or OFF and stores it in variable 'status'
    status = On


Beginsub:

WinGetTitle, Title, A                ; retreive current window title, store in Title


if title contains AutoCAD 2012            ; if title contains "AutoCAD" turn on capslock
                        ; then go back to the BeginSub subroutine and see if the title 
{    SetCapsLockState, on            ; still matches "AutoCAD 2012" if it does not...\/\/\/
    goto, BeginSub
            }

SetCapsLockState, %status%            ; ...Put caps lock back to the state it was when we started.

                        ; 'SetCapsLockState'  doesn't recognize a 1/0 variable
                        ; therefore the use of 'status' and ON/OFF words

Sleep, 1000                    ; only check every second


}

答案 5 :(得分:0)

#Persistent

SetTitleMatchMode, 2   ; use RegEx for finer control

Loop
{
    WinWaitActive, Notepad
    {
        WinGet, opVar, ID
        SetCapsLockState, On
    }

    WinWaitNotActive, ahk_id %opVar%
        SetCapsLockState, Off
}