blechmusikの日記

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

DvorakJ の処理の高速化の検討――IMEの状態の取得と設定版――

はじめに

DvorakJ の処理の高速化の検討――等価の判断処理テスト版―― - blechmusik2の日記のように、DvorakJ の処理の高速化を検討します。今回は IME の状態を取得する時間と、それを設定する処理の時間を計測します。

ソース

関数名にIEがつくものは、下駄配列のスレで公開された ahk のスクリプト*1を参考にしたものです。関数名にIEがないものは、IME.ahk*2 に記述されている関数です。前者の関数を使用すれば、Internet ExplorerIME の状態を取得できます。一方、後者の関数では、その状態を取得できません。現在 DvorakJ では前者の関数を使用しています。

VarSetCapacity(stGTI, 48)
DllCall("RtlFillMemory", "UInt", &stGTI, "UInt", 48, "UChar", 0)
DllCall("RtlFillMemory", "UInt", &stGTI, "UInt", 1, "UChar", 48)


Gui, Add, ListView,Grid,Name|Count|Time(ms)
Loop, 3
	LV_ModifyCol(A_Index, 80)
Gui, Show
count := 100 * 100
Tests = IME_GET|IME_GET_IE|IME_SET|IME_SET_IE
Loop, PARSE, Tests, |
{
	StartTime := A_TickCount
	Gosub, %A_LoopField%
	Time := A_TickCount - StartTime
	LV_Add("", A_LoopField, count, Time)
}
return
IME_GET:
	Loop, %count%
		IME_GET()
Return
IME_GET_IE:
	Loop, %count%
		IME_GET_IE()
Return
IME_SET:
	Loop, %count%
		IME_SET(1)
Return
IME_SET_IE:
	Loop, %count%
		IME_SET_IE(1)
Return


IME_GET(WinTitle="")
{
	ifEqual WinTitle,, SetEnv,WinTitle,A
	WinGet,hWnd,ID,%WinTitle%
	DefaultIMEWnd := DllCall("imm32\ImmGetDefaultIMEWnd", Uint,hWnd, Uint)
	;Message : WM_IME_CONTROL wParam:IMC_GETOPENSTATUS
	DetectSave := A_DetectHiddenWindows
	DetectHiddenWindows,ON
	SendMessage 0x283, 0x005,0,,ahk_id %DefaultIMEWnd%
	DetectHiddenWindows,%DetectSave%
	Return ErrorLevel
}

IME_GET_IE(WinTitle="")
{
	global stGTI

	; フォアグラウンドスレッドの情報を取得
	if( !DllCall("GetGUIThreadInfo", Uint,0, Uint, &stGTI) )
	{
		Return 0
	}
	; メニュー選択中なら帰る(このチェックは今ひとつ頼りにならない?)
	if( *(&stGTI+4) & 0x1E ){
		Return 0
	}
	; hwndFocus をとりだす
	hWnd:=*(&stGTI+15)<<24 | *(&stGTI+14)<<16 | *(&stGTI+12) | *(&stGTI+13)<<8

	; IME にメッセージを送って変換モードを教えてもらう
	; IMC_GETOPENSTATUS=5, IMC_GETCONVERSIONMODE=1
	hImeWnd:=DllCall("imm32\ImmGetDefaultIMEWnd", Uint,hWnd, Uint)

	DetectSave := A_DetectHiddenWindows
	DetectHiddenWindows,ON

	SendMessage 0x283, 0x005,"",,ahk_id %hImeWnd%
	DetectHiddenWindows,%DetectSave%

	Return ErrorLevel
}

IME_SET(setSts, WinTitle="")
{
	ifEqual WinTitle,, SetEnv,WinTitle,A
	WinGet,hWnd,ID,%WinTitle%
	DefaultIMEWnd := DllCall("imm32\ImmGetDefaultIMEWnd", Uint,hWnd, Uint)
	;Message : WM_IME_CONTROL wParam:IMC_SETOPENSTATUS
	DetectSave := A_DetectHiddenWindows
	DetectHiddenWindows,ON
	SendMessage 0x283, 0x006,setSts,,ahk_id %DefaultIMEWnd%
	DetectHiddenWindows,%DetectSave%
	Return ErrorLevel
}

IME_SET_IE(setSts, WinTitle="")
{
	global stGTI

	; hwndFocus をとりだす
	hWnd:=*(&stGTI+15)<<24 | *(&stGTI+14)<<16 | *(&stGTI+12) | *(&stGTI+13)<<8

	; IME にメッセージを送って変換モードを教えてもらう
	; IMC_GETOPENSTATUS=5, IMC_GETCONVERSIONMODE=1
	hImeWnd:=DllCall("imm32\ImmGetDefaultIMEWnd", Uint,hWnd, Uint)

	DetectSave := A_DetectHiddenWindows
	DetectHiddenWindows,ON

	SendMessage 0x283, 0x006,setSts,,ahk_id %hImeWnd%
	DetectHiddenWindows,%DetectSave%

	Return ErrorLevel
}

結果

まとめ

IME の状態を取得するか、それとも設定するのかによって、処理時間が厳密には差が出ることが解りました。とはいえ、Internet Explorer における IME の状態取得と設定に対応する関数を使用しても、実用上、体感するほどの速度の問題は生じないこともわかりました。
この結果より、Internet Explorer に対応しない高速化を追求する必要はないと結論づけます。

*1:"pc / 快適!下駄配列その1" < http://p2.chbox.jp/read.php?url=http%3A//pc11.2ch.net/test/read.cgi/pc/1201883108/199 >

*2:"AutoHotokeyを流行らせるアップローダ" < http://lukewarm.s101.xrea.com/up/ >の「089.zip Shift&Space + IME.ahk」所収。