我想编写一个脚本,当我激活标题中包含特定关键字的窗口(如 SQL)时,该脚本将打开大写锁定。当我切换到标题不包含我指定的任何关键字的窗口时,我还希望关闭大写锁定。
我该怎么做?我考虑#Persistent
过使用计时器定期检查活动窗口。但是,我认为应该有更好的方法。
我想编写一个脚本,当我激活标题中包含特定关键字的窗口(如 SQL)时,该脚本将打开大写锁定。当我切换到标题不包含我指定的任何关键字的窗口时,我还希望关闭大写锁定。
我该怎么做?我考虑#Persistent
过使用计时器定期检查活动窗口。但是,我认为应该有更好的方法。
检查答案:http ://www.reddit.com/r/AutoHotkey/comments/1qjf83/force_specific_program_to_use_caps/ 。特别是 G33kDude 的回答。这是一个聪明而有效的解决方案:当前窗口的检查只绑定到窗口激活。
========================
编辑:下面插入的代码。请注意,这不是一个完整的解决方案,您需要根据需要进行一些编辑。不过也不算大。
#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
}
由于您的标签中有一个 Autoit,因此这是在 autoit 中轻松完成的方法。
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
如果您想在不使用SetTimer
的情况下执行此操作,最好的方法是使用上下文相关的热键。例如:
SetTitleMatchMode, 2
#If WinActive("SQL") or WinActive("Notepad")
a::A
b::B
c::C
d::D
e::E
;; etc.
如果你想避免很长的行,你也可以使用窗口组WinActive
而不是标题的功能。#If
编辑:不区分大小写的示例
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.
米洛斯的回答非常直截了当,但它错过了一个关键点。您需要设置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
#Persistent
SetTitleMatchMode, 2 ; use RegEx for finer control
Loop
{
WinWaitActive, Notepad
{
WinGet, opVar, ID
SetCapsLockState, On
}
WinWaitNotActive, ahk_id %opVar%
SetCapsLockState, Off
}
#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
}