初めて投稿させていただきます。 VB6で下記の方法でIMEの読みガナを取得していました。 VB.NET上でも同じ処理をしたいので、ご存知の方おられましたら教えて下さい。 IMEの読みガナを取得できさえすれば、どんな方法でも歓迎です。 '------------------------------------------------------------------------- 'テキストボックスのChangedイベントにて Sub txtBox_Change() Dim strRet As String strRet = IMEの読みガナを返す(txtBox)'txtBoxはテキストボックス ... ... ... End Sub '関数の宣言 Option Explicit ' ウィンドウに関連付けされた入力コンテキストを ' 取得する関数の宣言 Declare Function ImmGetContext Lib "imm32.dll" _ (ByVal hWnd As Long) As Long ' IMEの変換文字列を取得する定数の宣言 Public Const GCL_CONVERSION = &H1 Public Const GCL_REVERSECONVERSION = &H2 Public Const GCS_RESULTREADSTR = &H200 Public Const BEGIN_OFFSET = 6 ' 変換文字列に関する情報を取得する関数の宣言 Declare Function ImmGetCompositionString _ Lib "imm32.dll" _ Alias "ImmGetCompositionStringA" _ (ByVal hIMC As Long, _ ByVal dwIndex As Long, _ lpBuf As Any, _ ByVal dwBufLen As Long) As Long ' ウィンドウに関連付けされた入力コンテキストを ' 解放する関数の宣言 Declare Function ImmReleaseContext Lib "imm32.dll" _ (ByVal hWnd As Long, _ ByVal hIMC As Long) As Long '呼び出される関数 Function IMEの読みガナを返す(txtBox As TextBox) As String Dim lngImeContext As Long Dim strBuffer As String * 256 Dim strFurigana As String Dim lngResult As Long ' 入力コンテキストを取得 lngImeContext = ImmGetContext(txtBox.hWnd) ' 変換文字列に関する情報を取得 lngResult = _ ImmGetCompositionString( _ lngImeContext, _ GCS_RESULTREADSTR, _ ByVal strBuffer, _ Len(strBuffer)) ' 入力コンテキストを解放 lngResult = _ ImmReleaseContext( _ Text.hWnd, _ lngImeContext) ' 取得した文字列からNull文字を削除 strFurigana = Replace(strBuffer, vbNullChar, "") ' 取得した文字列からスペースを削除 strFurigana = Replace(strFurigana, " ", "") ' 結果を返す IMEの読みガナを返す = strFurigana End Function
濁音・破裂音・吃音を含む読み仮名を持つ文字列を入力すると、 その時あるいはそれ以降、返される文字列の右側が文字化け することがある(時々)。 同じ文字列を入力しても、その時々で現象は違ったりもします。 私の未熟さからか、あるいはIMEがらみのOS依存部分が原因なのか 、取得したコンテキストの解放ができていないのかもしれません。 ソースコードの該当部分を下記に示します。 お気づきの点があったらご指摘ください。幸いです。 '◇TextBox側の処理----------------------------------------------------- Private Sub TextBox1_TextChanged _ (ByVal sender As System.Object _ , ByVal e As System.EventArgs) Handles TextBox1.TextChanged Dim strRet As String strRet = modIME.IMEの読みガナを返す(TextBox1) ... ... ... End Sub '◇標準モジュール側の処理---------------------------------------------- Module modIME '------------------dllの宣言------------------ ' ウィンドウに関連付けされた入力コンテキストを ' 取得する関数の宣言 Declare Function ImmGetContext Lib "imm32.dll" _ (ByVal Handle As IntPtr) As IntPtr '-----IMEの変換文字列を取得する定数の宣言----- Public Const GCL_CONVERSION = &H1 Public Const GCL_REVERSECONVERSION = &H2 Public Const GCS_RESULTREADSTR = &H200 Public Const BEGIN_OFFSET = 6 '--変換文字列に関する情報を取得する関数の宣言-- Declare Function ImmGetCompositionString Lib "imm32.dll" _ Alias "ImmGetCompositionStringA" _ (ByVal hIMC As IntPtr, ByVal dwIndex As Integer, _ ByVal strBuffer As System.Text.StringBuilder, _ ByVal dwBufLen As Integer) As Integer ' ウィンドウに関連付けされた入力コンテキストを ' 解放する関数の宣言 Declare Function ImmReleaseContext Lib "imm32.dll" _ (ByVal Handle As IntPtr, ByVal hIMC As IntPtr) As Long '呼び出される関数 Function IMEの読みガナを返す(ByVal txtBox As TextBox) As String Dim lngImeContext As IntPtr Dim strBuffer As New System.Text.StringBuilder(256) Dim strFurigana As String Dim intResult As Integer
' 入力コンテキストを取得 lngImeContext = ImmGetContext(txtBox.Handle) Try '変換文字列に関する情報を取得 If 0 = txtBox.MaxLength Then 'TextBoxのMaxLength指定があるか? 'なければ、dwBufLenは64にする(この関数内でのデフォルト値) intResult = ImmGetCompositionString(lngImeContext _ , GCS_RESULTREADSTR, strBuffer, 64) Else 'あれば、それをdwBufLenに指定 intResult = ImmGetCompositionString(lngImeContext _ , GCS_RESULTREADSTR, strBuffer, txtBox.MaxLength) End If Catch ex As Exception MsgBox(ex.ToString) End Try ' 入力コンテキストを解放 ImmReleaseContext(txtBox.Handle, lngImeContext) If 0 <> intResult Then '読み仮名のバイト数が得られた ' 取得した文字列からNull文字を削除 strFurigana = Replace(strBuffer.ToString, vbNullChar, "") ' 取得した文字列からスペースを削除 strFurigana = Replace(strFurigana, " ", "") ' 左詰めにして結果を返す Return strFurigana.PadLeft(intResult) Else Return "" End If End Function
End Module ’-----------------------------------------------
> ' ウィンドウに関連付けされた入力コンテキストを > ' 解放する関数の宣言 > Declare Function ImmReleaseContext Lib "imm32.dll" _ > (ByVal Handle As IntPtr, ByVal hIMC As IntPtr) As Long
> '呼び出される関数 > Function IMEの読みガナを返す(ByVal txtBox As TextBox) As String > Dim lngImeContext As IntPtr > Dim strBuffer As New System.Text.StringBuilder(256)
ここでは宣言だけをしておいて、 Dim strBuffer As System.Text.StringBuilder
> Dim strFurigana As String > Dim intResult As Integer > > ' 入力コンテキストを取得 > lngImeContext = ImmGetContext(txtBox.Handle) > Try > '変換文字列に関する情報を取得 > If 0 = txtBox.MaxLength Then 'TextBoxのMaxLength指定があるか? > 'なければ、dwBufLenは64にする(この関数内でのデフォルト値) > intResult = ImmGetCompositionString(lngImeContext _ > , GCS_RESULTREADSTR, strBuffer, 64) > Else 'あれば、それをdwBufLenに指定 > intResult = ImmGetCompositionString(lngImeContext _ > , GCS_RESULTREADSTR, strBuffer, txtBox.MaxLength) > End If
If 0 = txtBox.MaxLength Then 'TextBoxのMaxLength指定があるか? 'なければ、dwBufLenは64にする(この関数内でのデフォルト値) strBuffer = New System.Text.StringBuilder(64) Else strBuffer = New System.Text.StringBuilder(txtBox.MaxLength) End If
■No465に返信(よねKENさんの記事) #よねKENさん、再度のご指摘ありがとうございます。 #ご指摘のとおり修正し #呼び出される関数のソースは下記の通りとなりました。 '========================================================================= Module modIME '-------------------------dllの宣言----------------------- '------ウィンドウに関連付けされた入力コンテキストを------- ' 取得する関数の宣言 Declare Function ImmGetContext Lib "imm32.dll" _ (ByVal Handle As IntPtr) As IntPtr '-----------IMEの変換文字列を取得する定数の宣言----------- Public Const GCL_CONVERSION = &H1 Public Const GCL_REVERSECONVERSION = &H2 Public Const GCS_RESULTREADSTR = &H200 Public Const BEGIN_OFFSET = 6 '-------変換文字列に関する情報を取得する関数の宣言-------- Declare Function ImmGetCompositionString Lib "imm32.dll" _ Alias "ImmGetCompositionStringA" _ (ByVal hIMC As IntPtr, ByVal dwIndex As Integer, _ ByVal strBuffer As System.Text.StringBuilder, _ ByVal dwBufLen As Integer) As Integer '------ウィンドウに関連付けされた入力コンテキストを------- ' 解放する関数の宣言 Declare Function ImmReleaseContext Lib "imm32.dll" _ (ByVal Handle As IntPtr, ByVal hIMC As IntPtr) As Integer '--------------------------------------------------------- '◇◇◇◇◇◇◇◇TextBoxでのIMEの読みガナを返す◇◇◇◇◇◇◇◇ Function IMEの読みガナを返す(ByVal txtBox As TextBox) As String 'txtBox:IMEによる変換が行われたTextBox Dim lngImeContext As IntPtr '入力コンテキストの取得用 Dim strBuffer As New System.Text.StringBuilder '読み仮名格納用 Dim intResult As Integer '
' 入力コンテキストを取得 lngImeContext = ImmGetContext(txtBox.Handle) '変換文字列に関する情報を取得 Try If 0 = txtBox.MaxLength Then 'TextBoxのMaxLength指定があるか? 'なければ、dwBufLenは64にする(この関数内でのデフォルト値) strBuffer = New System.Text.StringBuilder(64) Else 'あれば、それをdwBufLenに指定 strBuffer = New System.Text.StringBuilder(txtBox.MaxLength) End If intResult = ImmGetCompositionString(lngImeContext _ , GCS_RESULTREADSTR, strBuffer, strBuffer.Capacity) Catch ex As Exception MsgBox(ex.ToString) End Try ' 入力コンテキストを解放 ImmReleaseContext(txtBox.Handle, lngImeContext) If 0 <> intResult Then '読み仮名のバイト数が得られたか? ' 結果を返す Return strBuffer.ToString Else ' 長さ0の文字列を返す Return "" End If End Function
End Module '========================================================================= #残念ながら、問題は解決しませんでした。 #ソースコードが原因ではなさそうですね。
'-------------------------dllの宣言----------------------- '------ウィンドウに関連付けされた入力コンテキストを------- ' 取得する関数の宣言 Declare Function ImmGetContext Lib "imm32.dll" _ (ByVal Handle As IntPtr) As IntPtr '-----------IMEの変換文字列を取得する定数の宣言----------- Public Const GCL_CONVERSION = &H1 Public Const GCL_REVERSECONVERSION = &H2 Public Const GCS_RESULTREADSTR = &H200 Public Const BEGIN_OFFSET = 6 '-------変換文字列に関する情報を取得する関数の宣言-------- Declare Function ImmGetCompositionString Lib "imm32.dll" _ Alias "ImmGetCompositionStringA" _ (ByVal hIMC As IntPtr, ByVal dwIndex As Integer, _ ByVal strBuffer As Byte(), _ ByVal dwBufLen As Integer) As Integer '------ウィンドウに関連付けされた入力コンテキストを------- ' 解放する関数の宣言 Declare Function ImmReleaseContext Lib "imm32.dll" _ (ByVal Handle As IntPtr, ByVal hIMC As IntPtr) As Integer '--------------------------------------------------------- '◇◇◇◇◇◇◇◇TextBoxでのIMEの読みガナを返す◇◇◇◇◇◇◇◇ Function GetImePhonetic(ByVal txtBox As TextBox) As String 'txtBox:IMEによる変換が行われたTextBox Dim lngImeContext As IntPtr '入力コンテキストの取得用 'Dim strBuffer As New System.Text.StringBuilder '読み仮名格納用 Dim strBuffer As Byte() Dim intResult As Integer '
' 入力コンテキストを取得 lngImeContext = ImmGetContext(txtBox.Handle) '変換文字列に関する情報を取得 Try If 0 = txtBox.MaxLength Then 'TextBoxのMaxLength指定があるか? 'なければ、dwBufLenは64にする(この関数内でのデフォルト値) 'strBuffer = New System.Text.StringBuilder(64) strBuffer = New Byte(64) {} Else 'あれば、それをdwBufLenに指定 'strBuffer = New System.Text.StringBuilder(txtBox.MaxLength) strBuffer = New Byte(txtBox.MaxLength) {} End If intResult = ImmGetCompositionString(lngImeContext _ , GCS_RESULTREADSTR, strBuffer, strBuffer.Length) Catch ex As Exception MsgBox(ex.ToString) End Try ' 入力コンテキストを解放 ImmReleaseContext(txtBox.Handle, lngImeContext) If 0 <> intResult Then '読み仮名のバイト数が得られたか? ' 結果を返す Return System.Text.Encoding.GetEncoding("Shift_JIS").GetString(strBuffer, 0, intResult) Else ' 長さ0の文字列を返す Return "" End If End Function
初めて投稿させていただきます。
VB6で下記の方法でIMEの読みガナを取得していました。
VB.NET上でも同じ処理をしたいので、ご存知の方おられましたら教えて下さい。
IMEの読みガナを取得できさえすれば、どんな方法でも歓迎です。
'-------------------------------------------------------------------------
'テキストボックスのChangedイベントにて
Sub txtBox_Change()
Dim strRet As String
strRet = IMEの読みガナを返す(txtBox)'txtBoxはテキストボックス
...
...
...
End Sub
'関数の宣言
Option Explicit
' ウィンドウに関連付けされた入力コンテキストを
' 取得する関数の宣言
Declare Function ImmGetContext Lib "imm32.dll" _
(ByVal hWnd As Long) As Long
' IMEの変換文字列を取得する定数の宣言
Public Const GCL_CONVERSION = &H1
Public Const GCL_REVERSECONVERSION = &H2
Public Const GCS_RESULTREADSTR = &H200
Public Const BEGIN_OFFSET = 6
' 変換文字列に関する情報を取得する関数の宣言
Declare Function ImmGetCompositionString _
Lib "imm32.dll" _
Alias "ImmGetCompositionStringA" _
(ByVal hIMC As Long, _
ByVal dwIndex As Long, _
lpBuf As Any, _
ByVal dwBufLen As Long) As Long
' ウィンドウに関連付けされた入力コンテキストを
' 解放する関数の宣言
Declare Function ImmReleaseContext Lib "imm32.dll" _
(ByVal hWnd As Long, _
ByVal hIMC As Long) As Long
'呼び出される関数
Function IMEの読みガナを返す(txtBox As TextBox) As String
Dim lngImeContext As Long
Dim strBuffer As String * 256
Dim strFurigana As String
Dim lngResult As Long
' 入力コンテキストを取得
lngImeContext = ImmGetContext(txtBox.hWnd)
' 変換文字列に関する情報を取得
lngResult = _
ImmGetCompositionString( _
lngImeContext, _
GCS_RESULTREADSTR, _
ByVal strBuffer, _
Len(strBuffer))
' 入力コンテキストを解放
lngResult = _
ImmReleaseContext( _
Text.hWnd, _
lngImeContext)
' 取得した文字列からNull文字を削除
strFurigana = Replace(strBuffer, vbNullChar, "")
' 取得した文字列からスペースを削除
strFurigana = Replace(strFurigana, " ", "")
' 結果を返す
IMEの読みガナを返す = strFurigana
End Function