読者です 読者をやめる 読者になる 読者になる

blechmusikの日記

キー・カスタマイズ・ソフトウェア "DvorakJ" の覚え書きをはじめとして様々なことを書いています。

AutoHotkeyで変換候補の窓と予想入力(推測入力)候補候補の窓の違いを判別できない

AutoHotkey

eamat @Cabinet - IME.ahkで配布されているIME.ahkIME_GetConverting関数を以下のように改変して、変換候補の窓と予想入力(推測入力)候補候補の窓の違いを判別しようとしたができなかった。
具体的には、通常の変換候補の窓の中に出てくる特徴的な色に注目して*1、その色が窓内部にあれば変換候補の窓が開いていると判定し、他方その色が窓内には見つからないときに予想入力(推測入力)候補候補の窓が開かれていると判定しようとしたがうまくいかなかった*2
何かしらの手段によってそれぞれの窓を別物として検出することはできないのだろうか。

;---------------------------------------------------------------------------
;  IMEの種類を選ぶかもしれない関数

;==========================================================================
;  IME 文字入力の状態を返す
;  (パクリ元 : http://sites.google.com/site/agkh6mze/scripts#TOC-IME- )
;    標準対応IME : ATOK系 / MS-IME2002 2007 / WXG / SKKIME
;    その他のIMEは 入力窓/変換窓を追加指定することで対応可能
;
;       WinTitle="A"   対象Window
;       ConvCls=""     入力窓のクラス名 (正規表現表記)
;       CandCls=""     候補窓のクラス名 (正規表現表記)
;       戻り値      1 : 文字入力中 or 変換中(推測変換の窓が出ている状態を含む)
;                   2 : 変換候補窓が出ている (Google IME 以外)
;                   3 : 変換候補窓が出ている (Google IME)
;                   0 : その他の状態
;
;   ※ MS-Office系で 入力窓のクラス名 を正しく取得するにはIMEのシームレス表示を
;      OFFにする必要がある
;      オプション-編集と日本語入力-編集中の文字列を文書に挿入モードで入力する
;      のチェックを外す
;==========================================================================
IME_GetConverting(WinTitle="A",ConvCls="",CandCls="") {

    ;IME毎の 入力窓/候補窓Class一覧 ("|" 区切りで適当に足してけばOK)
    ConvCls .= (ConvCls ? "|" : "")                 ;--- 入力窓 ---
            .  "ATOK\d+CompStr"                     ; ATOK系
            .  "|imejpstcnv\d+"                     ; MS-IME系
            .  "|WXGIMEConv"                        ; WXG
            .  "|SKKIME\d+\.*\d+UCompStr"           ; SKKIME Unicode
            .  "|MSCTFIME Composition"              ; Google日本語入力

    CandCls .= (CandCls ? "|" : "")                 ;--- 候補窓 ---
            .  "ATOK\d+Cand"                        ; ATOK系
            .  "|imejpstCandList\d+|imejpstcand\d+" ; MS-IME 2002(8.1)XP付属
            .  "|mscandui\d+\.candidate"            ; MS Office IME-2007
            .  "|WXGIMECand"                        ; WXG
            .  "|SKKIME\d+\.*\d+UCand"              ; SKKIME Unicode
   CandGCls := "GoogleJapaneseInputCandidateWindow" ;Google日本語入力

    ControlGet,hwnd,HWND,,,%WinTitle%
    if  (WinActive(WinTitle))   {
        ptrSize := !A_PtrSize ? 4 : A_PtrSize
        VarSetCapacity(stGTI, cbSize:=4+4+(PtrSize*6)+16, 0)
        NumPut(cbSize, stGTI,  0, "UInt")   ;   DWORD   cbSize;
        hwnd := DllCall("GetGUIThreadInfo", Uint,0, Uint,&stGTI)
                 ? NumGet(stGTI,8+PtrSize,"UInt") : hwnd
    }

    WinGet, pid, PID,% "ahk_id " hwnd
    tmm:=A_TitleMatchMode
    SetTitleMatchMode, RegEx
    ret := WinExist("ahk_class " . CandCls . " ahk_pid " pid) ? 2
        :  WinExist("ahk_class " . CandGCls                 ) ? 3 ; Google IME
        :  WinExist("ahk_class " . ConvCls . " ahk_pid " pid) ? 1
        :  0

        
    ;; マウスカーソル直下のPixelの色を取得する
    ;; MouseGetPos, X, Y
    ;; PixelGetColor, OutputVar, %X%, %Y%
    ;; ToolTip, %outputvar%, 100, 100, 2

    if (2 <= ret){
        if (2 == ret) {
            WinGetPos, X, Y, Width, Height, % "ahk_class " . CandCls . " ahk_pid " pid
        } else {
            WinGetPos, X, Y, Width, Height, % "ahk_class " . CandGCls
        }
        
        X1 := X
        Y1 := Y
        X2 := X + Width
        Y2 := Y + Height
    
        color := 0xF6E8CB       ; MSIME
        ;; color := 0xF2F2F2       ; ATOK
        PixelSearch, OutputVarX, OutputVarY, %X1%, %Y1%, %X2%, %Y2%, %color%, 0, Fast
        ;; if the color was found in the specified region, return 0
        ;; if it was not found, return 1
        ;; or if there was a problem that prevented the command from conducting the search, return 2
        ErrorLevel_of_PixelSearch := ErrorLevel

        ;; if the color was not found in the specified region
        if (0 != ErrorLevel_of_PixelSearch) {
            ret := 1
        }

        ToolTip, %X1%:%Y1%`n%X2%:%Y2%`n%Width%:%Height%`n%outputvarx%:%OutputVarY%`nErrorLevel:%ErrorLevel_of_PixelSearch%`nret:%ret%, 100, 100, 2
    }
        
    SetTitleMatchMode, %tmm%
    return ret
}

*1:WinGetPosコマンドとPixelSearchコマンドを使用する。

*2:特定の色が特定の範囲にあるかどうかはPixelSearchコマンド実行後にErrorLevelを確認すればよい。