- PR -

カナ変換

投稿者投稿内容
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2004-05-20 07:31
諸農です。

引用:

成功しました。



おおっ、良かったです。
是非、www.pinvoke.netに登録してください。

引用:

以下の3点の変更で実現できました。
1.ImmGetConvertListAを使用
2.ImmGetConvertListAの引数をすべて値渡しに変更
3.ImmGetConvertListの3番目の引数をバイト配列とし、
  シフトJISのバイトコードに変換した後で処理する。



VBでの宣言の方法が良くわかっていないのですが、
関数エイリアス(エントリポイント)は
ImmGetConvertListA/Wと言ったようにどちらか決めうち
でないとダメなんでしょうか?

また、関数の3番目の引数をバイト配列に変更とありますが、
ちょっと変な感じというか無駄な作業を関数呼び側に強いて
いる感がありますね。。

引用:

まだ、これがWIN98で動作するかどうかは分かりませんが。。。



確かに。。

_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-05-20 09:24
imm32.dllの呼び出しを、属性を使うようにしました。
コード:

Public Class WR_Imm32

Public Enum GCL As Integer
CONVERSION = &H1
REVERSECONVERSION = &H2
REVERSE_LENGTH = &H3
End Enum

<DllImport("Imm32.dll", CharSet:=CharSet.Auto, entrypoint:="ImmGetContext")> _
Public Shared Function ImmGetContext(ByVal hWnd As IntPtr) As IntPtr
End Function

<DllImport("User32.dll", CharSet:=CharSet.Auto, entrypoint:="GetKeyboardLayout")> _
Public Shared Function GetKeyboardLayout(ByVal idThread As Integer) As IntPtr
End Function

<DllImport("Imm32.dll", CharSet:=CharSet.Auto, entrypoint:="ImmGetConversionList")> _
Public Shared Function ImmGetConversionList(ByVal hKL As IntPtr, ByVal hIMC As IntPtr, ByVal lpSrc As String, ByVal lpDst As IntPtr, ByVal dwBufLen As Integer, ByVal uFlag As Integer) As Integer
End Function

<DllImport("Imm32.dll", CharSet:=CharSet.Auto, entrypoint:="ImmReleaseContext")> _
Public Shared Function ImmReleaseContext(ByVal hWnd As IntPtr, ByVal hIMC As IntPtr) As Boolean
End Function

<StructLayout(Runtime.InteropServices.LayoutKind.Sequential)> _
Public Class CANDIDATELIST
Public dwSize As Integer
Public dwStyle As Integer
Public dwCount As Integer
Public dwSelection As Integer
Public dwPageStart As Integer
Public dwPageSize As Integer
Public dwOffset As Integer
End Class

End Class

Public Function GetReverseConversion(ByVal AText As String) As String()
Dim hIMC As IntPtr = WR_Imm32.ImmGetContext(Me.Handle)
Dim hKL As IntPtr = WR_Imm32.GetKeyboardLayout(0)
Dim list As New WR_Imm32.CANDIDATELIST
Dim dwSize As Integer = WR_Imm32.ImmGetConversionList(hKL, hIMC, AText, IntPtr.Zero, 0, WR_Imm32.GCL.REVERSE_LENGTH)
Dim BufList As IntPtr = Marshal.AllocHGlobal(dwSize)
WR_Imm32.ImmGetConversionList(hKL, hIMC, AText, BufList, dwSize, WR_Imm32.GCL_REVERSECONVERSION)
Marshal.PtrToStructure(BufList, list)
Dim buf(dwSize) As Byte
Marshal.Copy(BufList, buf, 0, dwSize)
Marshal.FreeHGlobal(BufList)
Dim os As Integer = list.dwOffset
Dim str As String = System.Text.Encoding.Unicode.GetString(buf, os, buf.Length - os - 3) ' 注意
' Dim par() As Char = "\0".ToCharArray() 削除
' Dim strList() As String = str.Split(par) ↓変更
Dim strList() As String = str.Split(New Char() {ControlChars.NullChar})
WR_Imm32.ImmReleaseContext(Me.Handle, hIMC)
Return strList
End Function




 エンコーディングは、Defaultでは文字化けしていました。ここの部分だけ、9x系、NT系で、エンコーダーを分ければいいと思います。


 ついでに、取得できる「読み仮名」は、使用しているIMEに依存するようです。“重複”を入力した時の戻り値は、ATOK17で「チョウフク」「ジュウフク」(半角カナ)、MS-IME2002で「じゅうふく」「ちょうふく」「しげふく」(全角かな)(その後にゴミがいっぱい・・・)でした。


しまったぁ・・・「Imm32.Dllのラッパークラス」の意味でWR_Imm32なのだが、User32.Dllが混ざっている・・・

[ メッセージ編集済み 編集者: Jitta 編集日時 2004-05-20 09:56 ]
adtk
ベテラン
会議室デビュー日: 2004/02/06
投稿数: 75
投稿日時: 2004-05-20 09:35
こんな方法でAPI関数が宣言できるのですか。。

僕が今までやっていた、VB6譲りの宣言方法だとImmGetConversionListA/Wを明確に宣言しなければならなかったのですが、これならCのように「ImmGetConversionList」で使用できるのですね。
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2004-05-20 11:06
諸農です。

引用:

 ついでに、取得できる「読み仮名」は、使用しているIMEに依存するようです。“重複”を入力した時の戻り値は、ATOK17で「チョウフク」「ジュウフク」(半角カナ)、MS-IME2002で「じゅうふく」「ちょうふく」「しげふく」(全角かな)(その後にゴミがいっぱい・・・)でした。



今、ATOK17の環境で試してみました。
確かに、IMEの違いで戻りが変わってきますね。。

あ、それと、ゴミがいっぱいの現象ですけど、最初にアップした私の
コードに不具合があるんです。。すみませんm(__)m

関数から戻ってきた構造体のdwCountを確認して、逆変換文字列が
いくつ含まれているかを確認する必要がありました。

戻りのバッファには、タイミングによっては何故かnullやらゴミやらが
続く事があるようです。。

この現象、最初に思ったのが、SHFileOperationの様にバッファの最後に
はNull文字が連続して続くのかな、と思い「-3」なんていうとんでもない
決めうちをしていたんですが。。(^^;

コード:
    if (list.dwCount > 0)
    {
        int os = list.dwOffset;
        string str = System.Text.Encoding.Default.GetString(buf,os,buf.Length-os);
        char[] par = "\0".ToCharArray();
        string[] temp = str.Split(par);
        strList = new string[list.dwCount];
        Array.Copy(temp,strList,list.dwCount);
    }



と言う事で修正しました。
pinvokeの方も直しておきましたm(__)m

_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
liujun
会議室デビュー日: 2006/03/11
投稿数: 5
投稿日時: 2006-03-11 22:03
こんにちは!
vb.netの中に実行するのは正確です。
何故Asp中にエラーが出ましたか。
皆さんお願いいたします。



[ArgumentOutOfRangeException: 負の値ではない数値が必要です。
パラメータ名 : index]
System.Text.UnicodeEncoding.GetCharCount(Byte[] bytes, Int32 index, Int32 count) +182
System.Text.Encoding.GetChars(Byte[] bytes, Int32 index, Int32 count) +28
System.Text.Encoding.GetString(Byte[] bytes, Int32 index, Int32 count) +15
vbImeConvert.vbImeConvert.GetReverseConversion(String AText)
houshi.Meibo_add.ImeConvert2_Click(Object sender, EventArgs e)
System.Web.UI.WebControls.Button.OnClick(EventArgs e)
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
System.Web.UI.Page.ProcessRequestMain()
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-03-12 00:09
引用:

liujunさんの書き込み (2006-03-11 22:03) より:

[ArgumentOutOfRangeException: 負の値ではない数値が必要です。パラメータ名 : index]


引数 index が有効でない値です。
デバッグしてください。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
liujun
会議室デビュー日: 2006/03/11
投稿数: 5
投稿日時: 2006-03-12 01:08
VB.net中できますが、ASP中何故できない?

スキルアップ/キャリアアップ(JOB@IT)