情况
我有2 种语言输入法,
- 一个是普通的内置美式键盘,用于英语
- 一种是第三方软件输入法,用于语言 LANG_A
我在“高级键盘设置”中允许“让我为每个应用窗口使用不同的输入法”
我有win + space
切换输入法的热键
。前
我按win + space
一次 -> 输入法在英语和 LANG_A 之间切换(一切正常)
问题
。现在
我按win + space
一次 -> 输入法是未切换在英语和 LANG_A 之间,
相反,只弹出输入法切换面板(像往常一样),但不进行任何切换
我必须不释放 win
键,然后按space
再一次这样它就知道该切换了。
笔记::
如果你决定发布键
win
,并希望再按win + space
一次,这样它就可以工作了-- 不会,它永远只会停留在同一个输入法中
-- 如上所述 >“仅弹出输入法切换面板(像往常一样),但不进行任何切换”
这种情况偶尔会发生,但并非每次都会发生
这通常发生在你之后从一个窗口切换到另一个窗口
这种情况以前从未发生过,但只是在最近的 Windows 更新之后(三周内?)
当我从一个窗口切换到另一个窗口时,我可以看到第三方输入法面板闪烁很多
额外的问题
切换到 Google Chrome 时,第三方输入法面板会变得不可见,
仅当您将插入符号放在输入区域时才显示
(我认为它以前不会有这样的表现)
问题
为何以及如何解决这个问题?
(这样我就不需要按两次键了。)
解决方案(解决方法)
当我使用时Win7
,我无法使用它win + space
来切换键盘。
但我确实知道啊,我找到了一个ahk 邮报可以做到这一点。
当我使用时Win10
,那就不需要了。
但现在,我需要使用它作为解决 Win10 中该问题的解决方法。
使用 ahk(来自那个 ahk 帖子):
#NoEnv
#SingleInstance Force
#Space::LangSwitch(1)
#Space up::LangSwitch(2)
getKeyboardLanguID() {
SetFormat, Integer, H
WinGet, WinID,, A
ThreadID:=DllCall("GetWindowThreadProcessId", "UInt", WinID, "UInt", 0)
InputLocaleID:=DllCall("GetKeyboardLayout", "UInt", ThreadID, "UInt")
return %InputLocaleID%
}
LangSwitch( iKeyDownUp=0 )
{
static tickLast
IfEqual,iKeyDownUp,1
{ tickLast=%A_TickCount%
return
}
IfEqual,iKeyDownUp,2
If( A_TickCount-tickLast>200 )
return
HKL:=DllCall("GetKeyboardLayout", "uint",GetThreadOfWindow(), "uint")
HKLnum:=DllCall("GetKeyboardLayoutList","uint",0,"uint",0)
VarSetCapacity( HKLlist, HKLnum*4, 0 )
DllCall("GetKeyboardLayoutList","uint",HKLnum,"uint",&HKLlist)
loop,%HKLnum%
{ if( NumGet( HKLlist, (A_Index-1)*4 ) = HKL )
{ HKL:=NumGet( HKLlist, mod(A_Index,HKLnum)*4 )
break
}
}
ControlGetFocus,ctl,A
SendMessage,0x50,0,HKL,%ctl%,A ;WM_INPUTLANGCHANGEREQUEST
/*
;show traytip
LOCALE_SENGLANGUAGE=0x1001
LOCALE_SENGCOUNTRY=0x1002
VarSetCapacity( sKbd, 260, 0 )
VarSetCapacity( sCountry, 260, 0 )
DllCall("GetLocaleInfo","uint",HKL>>16,"uint",LOCALE_SENGLANGUAGE, "str",sKbd, "uint",260)
DllCall("GetLocaleInfo","uint",HKL & 0xFFFF,"uint",LOCALE_SENGCOUNTRY, "str",sCountry, "uint",260)
traytip,%sKbd%,%sCountry%
SetTimer,REMOVE_TOOLTIP,500 ;0.5 second
return
REMOVE_TOOLTIP:
SetTimer,REMOVE_TOOLTIP,off
traytip
return
*/
}
;returns first thread for the <processID>
;sets optional <List> to pipe | separated thread list for the <processID>
GetProcessThreadOrList( processID, byRef list="" )
{
;THREADENTRY32 {
THREADENTRY32_dwSize=0 ; DWORD
THREADENTRY32_cntUsage = 4 ;DWORD
THREADENTRY32_th32ThreadID = 8 ;DWORD
THREADENTRY32_th32OwnerProcessID = 12 ;DWORD
THREADENTRY32_tpBasePri = 16 ;LONG
THREADENTRY32_tpDeltaPri = 20 ;LONG
THREADENTRY32_dwFlags = 24 ;DWORD
THREADENTRY32_SIZEOF = 28
TH32CS_SNAPTHREAD=4
hProcessSnap := DllCall("CreateToolhelp32Snapshot","uint",TH32CS_SNAPTHREAD, "uint",0)
ifEqual,hProcessSnap,-1, return
VarSetCapacity( thE, THREADENTRY32_SIZEOF, 0 )
NumPut( THREADENTRY32_SIZEOF, thE )
ret=-1
if( DllCall("Thread32First","uint",hProcessSnap, "uint",&thE ))
loop
{
if( NumGet( thE ) >= THREADENTRY32_th32OwnerProcessID + 4)
if( NumGet( thE, THREADENTRY32_th32OwnerProcessID ) = processID )
{ th := NumGet( thE, THREADENTRY32_th32ThreadID )
IfEqual,ret,-1
ret:=th
list .= th "|"
}
NumPut( THREADENTRY32_SIZEOF, thE )
if( DllCall("Thread32Next","uint",hProcessSnap, "uint",&thE )=0)
break
}
DllCall("CloseHandle","uint",hProcessSnap)
StringTrimRight,list,list,1
return ret
}
; Returns thread owning specified window handle
; default = Active window
GetThreadOfWindow( hWnd=0 )
{
IfEqual,hWnd,0
hWnd:=WinExist("A")
DllCall("GetWindowThreadProcessId", "uint",hWnd, "uintp",id)
GetProcessThreadOrList( id, threads )
IfEqual,threads,
return 0
CB:=RegisterCallback("GetThreadOfWindowCallBack","Fast")
lRet=0
lParam:=hWnd
loop,parse,threads,|
{ NumPut( hWnd, lParam )
DllCall("EnumThreadWindows", "uint",A_LoopField, "uint",CB, "uint",&lParam)
if( NumGet( lParam )=true )
{ lRet:=A_LoopField
break
}
}
DllCall("GlobalFree", "uint", CB)
return lRet
}
GetThreadOfWindowCallBack( hWnd, lParam )
{
IfNotEqual,hWnd,% NumGet( 0+lParam )
return true
NumPut( true, 0+lParam )
return 0
}