'--変換文字列および読み文字列の文字、属性、または文節を設定 Private Declare Auto Function ImmSetCompositionString Lib "imm32" _ (ByVal hIMC As IntPtr, _ ByVal dwIndex As eSCS, _ ByVal lpComp As String, _ ByVal dwCompLen As Int32, _ ByVal lpRead As String, _ ByVal dwReadLen As Int32 _ ) As <MarshalAs(UnmanagedType.Bool)> Boolean
'--入力コンテキストの状態変更をIMEに通知 Private Declare Function ImmNotifyIME Lib "imm32" _ (ByVal hIMC As IntPtr, _ ByVal dwAction As Int32, _ ByVal dwIndex As Int32, _ ByVal dwValue As Int32 _ ) As <MarshalAs(UnmanagedType.Bool)> Boolean
'--入力コンテキストを解放する Private Declare Function ImmReleaseContext Lib "imm32" _ (ByVal hWnd As IntPtr, _ ByVal hIMC As IntPtr _ ) As <MarshalAs(UnmanagedType.Bool)> Boolean
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load TextBox1.Text = "" TextBox2.Text = "へんかんもじれつ" End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click TextBox2.Focus() '--Focusしないと変換したい文字列が消えてしまう
Dim strKana As String Dim length As Integer
strKana = TextBox2.Text TextBox2.Clear()
If Environment.OSVersion.Platform = PlatformID.Win32NT Then length = Encoding.Unicode.GetByteCount(strKana) Else length = Encoding.GetEncoding(0).GetByteCount(strKana) End If
'--テキストボックス2のコンテキストを取得 Dim hIMC As IntPtr = ImmGetContext(TextBox2.Handle) If hIMC.Equals(IntPtr.Zero) Then MsgBox("ハンドル取得できませんでした。") Exit Sub End If
分類:[.NET]
お世話になっております。
OS付属のスクリーンキーボード等を使用せず、
自前でソフトウェアキーボードを作成しているのですが、IME制御の部分で困っています。
参考させて頂いた記事
テキストボックスに入力された平仮名を漢字へ変換
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=3823&forum=7
IME変換前のテキストを入力する
http://dobon.net/vb/bbs/log3-44/26709.html
開発環境
WindowsXP SP3
Microsoft IME Standard 2003
Microsoft Visual Studio 2005 (VB.NETを使用)
.NET Framework2.0
フォーム上で使用するコントロールは以下の4つです。
・文字変換後の出力用テキストボックス(TextBox1)
・変換したい文字入力用のテキストボックス(TextBox2)
・変換ボタン(Button1)
・変換文字を出力テキストボックスへ送る確定ボタン(Button2)
操作の流れは以下を想定しています。
1.文字入力用テキストボックスに文字を入力
2.変換ボタンを押下して変換して一旦TextBox2に表示
3.確定ボタンを押下して出力テキストボックスに表示
困っている点は変換ボタンを押下した際、文字列自体は下に破線付きの状態になっているのですが
変換候補の一覧が表示されません。
キーボードのスペースキーを押下すると一覧が表示されるのですが、
変換ボタンで候補表示して確定ボタンで変換終了という流れにしたいです。
製作中ではありますが、ソースコードを張ります
'--入力コンテキストを取得する
Private Declare Function ImmGetContext Lib "imm32" _
(ByVal hWnd As IntPtr _
) As IntPtr
'--IMEを開く
Private Declare Function ImmSetOpenStatus Lib "imm32" _
(ByVal hIMC As IntPtr, _
<MarshalAs(UnmanagedType.Bool)> ByVal fOpen As Boolean _
) As <MarshalAs(UnmanagedType.Bool)> Boolean
'--ImmSetCompositionString APIのdwIndex
Private Enum eSCS As Integer
SCS_SETSTR = &H9 '--変換文字列か読み文字列のいずれか、またはその両方を設定
SCS_CHANGEATTR = &H11 '--変換文字列か読み文字列のいずれか、またはその両方の属性を設定
SCS_CHANGECLAUSE = &H24 '--変換文字列か読み文字列のいずれか、またはその両方の文節情報を設定
SCS_SETRECONVERTSTRING = &H10000 '--IMEにRECONVERTSTRING 構造体に格納された文字列を逆変換するよう指示
SCS_QUERYRECONVERTSTRING = &H20000 '--IMEにRECONVERTSTRING構造体を調整するよう指示
End Enum
'--ImmNotifyIME APIのdwAction
Private Enum eNI As Integer
NI_OPENCANDIDATE = &H10 '--IMEに候補一覧を開くように指示
NI_CLOSECANDIDATE = &H11 '--IMEに候補一覧を閉じるように指示
NI_SELECTCANDIDATESTR = &H12 '--変換候補の1つを選択
NI_CHANGECANDIDATELIST = &H13 '--選択されている候補一覧を変更
NI_FINALIZECONVERSIONRESULT = &H14 '--
NI_COMPOSITIONSTR = &H15 '--IMEに変換文字列に対する処理を実行するように指示
NI_SETCANDIDATE_PAGESTART = &H16 '--候補リストのページ開始インデックスを変更
NI_SETCANDIDATE_PAGESIZE = &H17 '--候補リストのページサイズを変更
NI_IMEMENUSELECTED = &H18 '--IMEに指定したメニューを処理する事をアプリケーションに許可するよう指示
End Enum
'--ImmNotifyIME APIのdwIndex
Private Enum eCPS As Integer
CPS_COMPLETE = &H1 '--編集文字列をクリアして、編集文字列がないようにする
CPS_CONVERT = &H2 '--編集文字列が確定したことにする
CPS_REVERT = &H3 '--編集文字列を変換する
CPS_CANCEL = &H4 '--現在の編集文字列をキャンセルして未変換文字列とする
End Enum
'--変換文字列および読み文字列の文字、属性、または文節を設定
Private Declare Auto Function ImmSetCompositionString Lib "imm32" _
(ByVal hIMC As IntPtr, _
ByVal dwIndex As eSCS, _
ByVal lpComp As String, _
ByVal dwCompLen As Int32, _
ByVal lpRead As String, _
ByVal dwReadLen As Int32 _
) As <MarshalAs(UnmanagedType.Bool)> Boolean
'--入力コンテキストの状態変更をIMEに通知
Private Declare Function ImmNotifyIME Lib "imm32" _
(ByVal hIMC As IntPtr, _
ByVal dwAction As Int32, _
ByVal dwIndex As Int32, _
ByVal dwValue As Int32 _
) As <MarshalAs(UnmanagedType.Bool)> Boolean
'--入力コンテキストを解放する
Private Declare Function ImmReleaseContext Lib "imm32" _
(ByVal hWnd As IntPtr, _
ByVal hIMC As IntPtr _
) As <MarshalAs(UnmanagedType.Bool)> Boolean
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
TextBox1.Text = ""
TextBox2.Text = "へんかんもじれつ"
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
TextBox2.Focus() '--Focusしないと変換したい文字列が消えてしまう
Dim strKana As String
Dim length As Integer
strKana = TextBox2.Text
TextBox2.Clear()
If Environment.OSVersion.Platform = PlatformID.Win32NT Then
length = Encoding.Unicode.GetByteCount(strKana)
Else
length = Encoding.GetEncoding(0).GetByteCount(strKana)
End If
'--テキストボックス2のコンテキストを取得
Dim hIMC As IntPtr = ImmGetContext(TextBox2.Handle)
If hIMC.Equals(IntPtr.Zero) Then
MsgBox("ハンドル取得できませんでした。")
Exit Sub
End If
Dim bRet As Boolean
'--IMEの状態をセット(True:On False:Off)
bRet = ImmSetOpenStatus(hIMC, True)
Debug.WriteLine("result of ImmSetOpenStatus : " & rRet.ToString)
'--文字列の属性等をセット
bRet = ImmSetCompositionString(hIMC, eSCS.SCS_SETSTR, strKana, length, Nothing, 0)
Debug.WriteLine("result of ImmSetCompositionString : " & rRet.ToString)
'--変換実行
bRet = ImmNotifyIME(hIMC, eNI.NI_COMPOSITIONSTR, eCPS.CPS_CONVERT, 0)
Debug.WriteLine("result of ImmNotifyIME COMPOSITIONSTR : " & rRet.ToString)
'--変換候補表示
bRet = ImmNotifyIME(hIMC, eNI.NI_OPENCANDIDATE, 0, 0)
Debug.WriteLine("result of ImmNotifyIME OPENCANDIDATE : " & rRet.ToString)
'--コンテキストを開放
bRet = ImmReleaseContext(TextBox2.Handle, hIMC)
Debug.WriteLine("result of ImmReleaseContext : " & rRet.ToString)
End Sub
'--ここはまだ製作途中です
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
TextBox2.Focus()
'--テキストボックス2のコンテキストを取得
Dim hIMC As IntPtr = ImmGetContext(TextBox2.Handle)
If hIMC.Equals(IntPtr.Zero) Then
MsgBox("ハンドル取得できませんでした。")
Exit Sub
End If
Dim bRet As Boolean
'--変換確定
bRet = ImmNotifyIME(hIMC, eNI.NI_COMPOSITIONSTR, eCPS.CPS_COMPLETE, 0)
Debug.WriteLine("result of ImmNotifyIME CPS_COMPLETE : " & rRet.ToString)
'--コンテキストを開放
bRet = ImmReleaseContext(TextBox2.Handle, hIMC)
Debug.WriteLine("result of ImmReleaseContext : " & rRet.ToString)
'--確定した内容をText1へ
End Sub
変換候補を表示するためImmNotifyIMEを使用しています。
戻り値を調べると0が返って来ているので
ここが問題だと分かっていますが、解決方法がわかりません。
IME関連のAPI名称で検索をかけたのですが、今の所解決に至っておりません。
解決方法をご存知の方がいらっしゃいましたらご教授お願い致します。