http://hsp.tv/play/pforum.php?mode=all&num=4533
の内容をベースに改良したものです。
入力中の文字列が長くなりすぎると末尾が化けることがあるようですのでご注意下さい。
簡単に書いたので何か問題があるかも知れません。
実際にはもう少し工夫した方がいいと思います。
#uselib "user32.dll"
#func CallWindowProc "CallWindowProcA" var, int, int, int, int
#cfunc GetWindowLong "GetWindowLongA" int, int
#func SetWindowLong "SetWindowLongA" int, int, int
#func DestroyWindow "DestroyWindow" int
#func SendMessage "SendMessageA" int, int, int, int
#module
#uselib "imm32.dll"
#cfunc ImmGetCompositionString "ImmGetCompositionStringA" int, int, var, int
#cfunc ImmGetContext "ImmGetContext" int
#func ImmReleaseContext "ImmReleaseContext" int, int
#const GCS_COMPSTR 0x0008
; 入力中文字列の取得
#defcfunc GetImeStr int id, local hIMC, local size, local buf
hIMC = ImmGetContext(objinfo(id, 2))
size = ImmGetCompositionString(hIMC, GCS_COMPSTR, buf, 0)
sdim buf, size
size = ImmGetCompositionString(hIMC, GCS_COMPSTR, buf, size)
ImmReleaseContext objinfo(id, 2), hIMC
return buf
#global
; 定数の定義
#const GWL_WNDPROC -4
#const WM_IME_STARTCOMPOSITION 0x10d
#const WM_IME_ENDCOMPOSITION 0x10e
#const WM_IME_COMPOSITION 0x10f
#const WS_VISIBLE 0x10000000
#const WS_CHILD 0x40000000
; メッセージフック
oncmd gosub *OnImeStartComposition, WM_IME_STARTCOMPOSITION
oncmd gosub *OnImeComposition, WM_IME_COMPOSITION
oncmd gosub *OnImeEndComposition, WM_IME_ENDCOMPOSITION
; マシン語の作成
dim fncode, 26
fncode( 0) = 0x51ec8b55, 0x45c75756, 0x000000fc, 0xfc758b00, 0x830c7d8b
fncode( 5) = 0x2e7402ff, 0x7410ff83, 0x0cff811f, 0x76000001, 0x0fff812c
fncode(10) = 0x77000001, 0x1475ff24, 0x571075ff, 0xff1476ff, 0x15eb0c56
fncode(15) = 0xff0875ff, 0xc0330856, 0x76ff1aeb, 0xfffc6a10, 0x56ff0875
fncode(20) = 0x1475ff04, 0x571075ff, 0xff0875ff, 0x16ff1076, 0xc2c95e5f
fncode(25) = 0x00000010
; 関数のポインタを格納
pfn = varptr(fncode)
procdata(0) = varptr(CallWindowProc), varptr(SetWindowLong)
procdata(2) = varptr(DestroyWindow), varptr(SendMessage)
; インプットボックス作成
y = ginfo(13) / 2
sdim buf
mesbox buf, ginfo(12), y, 5
id = stat
; スタティックテキスト
winobj "static", "", 0, WS_VISIBLE | WS_CHILD, ginfo(12), y
msg = "ここに入力中の文字が表示されます。"
sid = stat
gosub *setmsg
; ウィンドウプロシージャを取得
inp_hwnd = objinfo(id, 2)
procdata(4) = GetWindowLong(inp_hwnd, GWL_WNDPROC)
procdata(5) = hwnd
p = varptr(procdata)
memcpy fncode, p, 4, 9
; サブクラス化
SetWindowLong inp_hwnd, GWL_WNDPROC, pfn
stop
; スタティックテキストの文字列を設定
*setmsg
sendmsg objinfo(sid, 2), 0xc, 0, msg
return
; IME 入力開始
*OnImeStartComposition
return
; IME 入力中
*OnImeComposition
msg = GetImeStr(id)
gosub *setmsg
return
; IME 入力終了
*OnImeEndComposition
msg = "ここに入力中の文字が表示されます。"
gosub *setmsg
return