〜 インプット 〜
入力モード・変換モードを設定

Windowsには「nputethodditor(=IME)」と呼ばれる
「nputethodanager(=IMM)」で管理された文字入力補助ソフトウェアが入ってます。
Windowsでのキーボードから入力された文字は全てIMMの管理下にあり、
提供されているIME用のAPIを使って制御することができるようになっています。

IMEを開いている時、言語バーに「あ」「カ」「A」等と書かれているものが入力モードで、
言語バーに「般」「名」「話」と書かれているものが変換モードと呼ばれています。
入力モードはキーを押した時に入力される文字に影響するので直感的にわかりやすいのですが、
変換モードは変換する時に効果のあるものでイメージしにくいですね。
例えば、顔文字辞書は話し言葉優先にしている時のみ有効なもので、
それ以外の変換モードにしている時に「かおもじ」で変換しても顔文字辞書の顔文字はリストに出ませんし、
ハイフン付き7桁の郵便コードで変換しても変換モードが人名/地名以外だと地名が表示されません。
今回はこれらのモードをプログラムから変更するサンプルです。

モードを設定するAPI関数はImmSetConversionStatusで、
引数に指定するのは、状態の設定でも使った入力コンテキストハンドルと、
下記の設定する入力モードの組み合わせと変換モードの組み合わせの3つとなります。
定数コード意味
16進10進
IME_CMODE_ALPHANUMERIC0x00000英数字
IME_CMODE_NATIVE
IME_CMODE_CHINESE
IME_CMODE_HANGEUL
IME_CMODE_JAPANESE
0x00011言語依存
IME_CMODE_KATAKANA0x00022カタカナ(OFF時はひらがな)
IME_CMODE_LANGUAGE0x00033言語
IME_CMODE_FULLSHAPE0x00088全角(OFF時は半角)
IME_CMODE_ROMAN0x001016ローマ字
IME_CMODE_CHARCODE0x002032文字コード
IME_CMODE_HANJACONVERT0x004064ハングル文字変換
IME_CMODE_SOFTKBD0x0080128ソフトキーボード
IME_CMODE_NOCONVERSION0x0100256無変換
IME_CMODE_EUDC0x0200512外字
IME_CMODE_SYMBOL0x04001024記号
変換モードは下記の値を指定してください。
定数コード意味旧IME
16進10進
IME_SMODE_NONE0x00000無変換無変換
IME_SMODE_PLAURALCLAUSE0x00011人名/地名複合語
IME_SMODE_SINGLECONVERT0x00022 単語
IME_SMODE_AUTOMATIC0x00044自動変換自動変換
IME_SMODE_PHRASEPREDICT0x00088 連文節
IME_SMODE_CONVERSATION0x001016話し言葉優先

initime
[パラメータなし]モジュール内部で共通使用する情報をセットするだけである為、パラメータは必要ない。

exitime
[パラメータなし]モジュール内部で共通使用した情報を開放するだけである為、パラメータは必要ない。
尚、プログラム終了時に自動的に呼び出されるものなので明示的に呼び出さなくても良い。

setimestat 状態
状態変換状態(0:無変換, 1:変換)を指定する。

getimemode 入力モード, 変換モード
入力モード現在の入力モード受取先の数値型変数を指定する。
変換モード現在の変換モード受取先の数値型変数を指定する。

setimemode 入力モード, 変換モード
入力モード設定する入力モード値を指定する。
変換モード設定する変換モード値を指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
	ll_libload imm, "imm32.dll"
	ll_getproc ImmGetContext, "ImmGetContext", imm
	ll_getproc ImmGetConversionStatus, "ImmGetConversionStatus", imm
	ll_getproc ImmReleaseContext, "ImmReleaseContext", imm
	ll_getproc ImmSetConversionStatus, "ImmSetConversionStatus", imm
	ll_getproc ImmSetOpenStatus, "ImmSetOpenStatus", imm

#module
#deffunc initime
	mref bmscr, 67
	ll_callfunc bmscr.13, 1, ImmGetContext@ : ll_ret himc
	return

#deffunc exitime onexit
	if himc {
		mref bmscr, 67
		prm = bmscr.13, himc
		ll_callfunc prm, 2, ImmReleaseContext@
	}
	return

#deffunc setimestat int
	mref mode, 0
	prm = himc, (mode ! 0)
	ll_callfunc prm, 2, ImmSetOpenStatus@
	return

#deffunc getimemode val, val
	mref inputmode, 16 : mref changemode, 17
	prm = himc
	ll_getptr inputmode : ll_ret prm.1
	ll_getptr changemode : ll_ret prm.2
	ll_callfunc prm, 3, ImmGetConversionStatus@
	return

#deffunc setimemode int, int
	dim i, 2
	getimemode i.0, i.1
	mref inputmode, 0 : mref changemode, 1
	prm.1 = (inputmode = -1) * i.0 + ((inputmode ! -1) * inputmode)
	prm.2 = (changemode = -1) * i.1 + ((changemode ! -1) * changemode)
	ll_callfunc prm, 3, ImmSetConversionStatus@
	return
#global

	initime
	sdim txt, 16, 4
	txt = "全角英数", "全角ひらがな", "半角カナ", "無変換"
	repeat 4
		pos 10, cnt * 40 + 10 : input txt.cnt, 100, 25
	loop

*main
	setimestat 1
	objsel -1
	selid = stat
	switch selid
	case 0: setimemode 0x0008 : swbreak
	case 1: setimemode 0x0009 : swbreak
	case 2: setimemode 0x0003 : swbreak
	case 3: setimemode 0x0000 : swbreak
	swend
	repeat
		wait 1
		objsel -1
		if selid ! stat : break
	loop
	goto *main

initime
[パラメータなし]モジュール内部で共通使用する情報をセットするだけである為、パラメータは必要ない。

exitime
[パラメータなし]モジュール内部で共通使用した情報を開放するだけである為、パラメータは必要ない。
尚、プログラム終了時に自動的に呼び出されるものなので明示的に呼び出さなくても良い。

setimestat 状態
状態変換状態(0:無変換, 1:変換)を指定する。

getimemode 入力モード, 変換モード
入力モード現在の入力モード受取先の数値型変数を指定する。
変換モード現在の変換モード受取先の数値型変数を指定する。

setimemode 入力モード, 変換モード
入力モード設定する入力モード値を指定する。
変換モード設定する変換モード値を指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#uselib "imm32.dll"
#cfunc global ImmGetContext "ImmGetContext" int
#func  global ImmGetConversionStatus "ImmGetConversionStatus" int, var, var
#func  global ImmReleaseContext "ImmReleaseContext" int, int
#func  global ImmSetConversionStatus "ImmSetConversionStatus" int, int, int
#func  global ImmSetOpenStatus "ImmSetOpenStatus" int, int

#module
#deffunc initime
	himc = ImmGetContext(hwnd)
	return himc

#deffunc exitime onexit
	if himc : ImmReleaseContext hwnd, himc
	return

#deffunc setimestat int mode
	ImmSetOpenStatus himc, mode ! 0
	return

#deffunc getimemode var inputmode, var changemode
	ImmGetConversionStatus himc, inputmode, changemode
	return

#deffunc setimemode int inputmode, int changemode, local i
	dim i, 2
	getimemode i.0, i.1
	i.0 = (inputmode = -1) * i.0 + (inputmode ! -1) * inputmode
	i.1 = (changemode = -1) * i.1 + (changemode ! -1) * changemode
	ImmSetConversionStatus himc, i.0, i.1
	return
#global

	initime
	txt = "全角英数", "全角ひらがな", "半角カナ", "無変換"
	foreach txt
		pos 10, cnt * 40 + 10 : input txt.cnt, 100, 25
	loop

*main
	setimestat 1
	objsel -1
	selid = stat
	switch selid
	case 0: setimemode 0x0008 : swbreak
	case 1: setimemode 0x0009 : swbreak
	case 2: setimemode 0x0003 : swbreak
	case 3: setimemode 0x0000 : swbreak
	swend
	repeat
		wait 1
		objsel -1
		if selid ! stat : break
	loop
	goto *main