为什么在win10中第一次按“win+space”键切换语言输入法没有切换?

为什么在win10中第一次按“win+space”键切换语言输入法没有切换?

情况

我有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
}


相关内容