@IT会議室は、ITエンジニアに特化した質問・回答コミュニティ「QA@IT」に生まれ変わりました。ぜひご利用ください。
- PR -

カナ変換

投稿者投稿内容
adtk
ベテラン
会議室デビュー日: 2004/02/06
投稿数: 75
投稿日時: 2004-05-13 12:40
漢字の逆変換で悩んでいます。

漢字→カナの変換を行いたいのですが、APIを使用しての変換がうまく動作せず悩んでおります。VB.NETからEXCELの関数getPhoneticを利用すれば実現できたのですが、EXCELを起動させるオーバーヘッドも気になるので。。。

<問題点>
VB6の時、以下のようにしていたAPIの宣言をどのように使用したら良いのでしょうか?

Declare Function ImmGetConversionList Lib "imm32" Alias "ImmGetConversionListW" ( _
ByVal hKL As Long, _
ByVal hIMC As Long, _
ByRef lpSrc As Byte, _
ByRef lpDst As Any, _
ByVal dwBufLen As Long, _
ByVal uFlag As Long _
) As Long

lpDstがAny型なのですがVB.NETでAny型に代わる型は?Object型?

VB6コーディングは以下のような感じでおこなっていたのですが(途中省略)

Type CANDIDATELIST
dwSize As Long
dwStyle As Long
dwCount As Long
dwSelection As Long
dwPageStart As Long
dwPageSize As Long
dwOffset(0) As Long
End Type

'変換結果を受け取るバッファサイズを取得
lngSize = ImmGetConversionList(hKL, hIMC, bySource(0), Null,
              0,GCL_REVERSECONVERSION)
'バッファサイズ分バイト配列を動的に取得
ReDim byCandiateArray(lngSize)
'変換結果を取得
lngSize = ImmGetConversionList(hKL, hIMC, bySource(0),
       byCandiateArray(0),lngSize, GCL_REVERSECONVERSION)


lpDstには構造体CANDIDATELISTを渡してバッファサイズを取得した後、結果取得時にはバイト配列を渡しています。これをVB.NETで実現できるのでしょうか?
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2004-05-13 16:10
諸農です。

C#では実現できています。
こちらのスレッドが参考になると思います。

http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=7712&forum=7


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

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2004-05-14 01:03
諸農です。

そのままC#での実装です。
といっても、単に手順通りにしただけです。。(^^;

コード:

const int GCL_REVERSECONVERSION = 0x0002;

[DllImport("Imm32.dll")]
public static extern IntPtr ImmGetContext(IntPtr hWnd);

[DllImport("User32.dll")]
public static extern IntPtr GetKeyboardLayout(int idThread);

[DllImport("Imm32.dll")]
public static extern int ImmGetConversionList(
IntPtr hKL,
IntPtr hIMC,
string lpSrc,
IntPtr lpDst,
int dwBufLen,
int uFlag
);

[DllImport("Imm32.dll")]
public static extern bool ImmReleaseContext(IntPtr hWnd,IntPtr hIMC);

[StructLayout(LayoutKind.Sequential)]
public class CANDIDATELIST
{
public int dwSize;
public int dwStyle;
public int dwCount;
public int dwSelection;
public int dwPageStart;
public int dwPageSize;
public int dwOffset;
}

public string[] GetReverseConversion(string AText)
{
IntPtr hIMC = ImmGetContext(this.Handle);
IntPtr hKL = GetKeyboardLayout(0);
CANDIDATELIST list = new CANDIDATELIST();
int dwSize = ImmGetConversionList(hKL,hIMC,AText,IntPtr.Zero,0,GCL_REVERSECONVERSION);
IntPtr BufList = Marshal.AllocHGlobal(dwSize);
ImmGetConversionList(hKL,hIMC,AText,BufList,dwSize,GCL_REVERSECONVERSION);
Marshal.PtrToStructure(BufList,list);
byte[] buf = new byte[dwSize];
Marshal.Copy(BufList,buf,0,dwSize);
Marshal.FreeHGlobal(BufList);
int os = list.dwOffset;
string str = System.Text.Encoding.Default.GetString(buf,os,buf.Length-os-3);
char[] par = "\0".ToCharArray();
string[] strList = str.Split(par);
ImmReleaseContext(this.Handle,hIMC);
return strList;
}

private void button1_Click(object sender, System.EventArgs e)
{
listBox1.Items.Clear();
listBox1.Items.AddRange(GetReverseConversion(textBox1.Text));
}



--編集追加--
メモリ解放の追加(^^;

_________________
諸農和岳
Powered by Borland Delphi/C++Builder & Microsoft VS.NET

[ メッセージ編集済み 編集者: Jubei 編集日時 2004-05-14 01:26 ]
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2004-05-14 07:48
[quote]
そのままC#での実装です。
といっても、単に手順通りにしただけです。。(^^;
[/code]

是非、http://www.pinvoke.net/ への投稿することをお勧めします

_________________
// 渋木宏明 (Hiroaki SHIBUKI)
// http://hidori.jp/
// Microsoft MVP for Visual C#
//
// @IT会議室 RSS 配信中: http://hidori.jp/rss/atmarkIT/
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2004-05-15 08:31
諸農です。

引用:

是非、http://www.pinvoke.net/ への投稿することをお勧めします :wink:



こんな便利なサイトがあったんですね(^。^)

Imm32ページがなかったので、追加してもらえるように依頼しておきました。
とりあえずは、GetKeyboardLayout()のサンプルに突っ込んでおきました(^^;


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

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
adtk
ベテラン
会議室デビュー日: 2004/02/06
投稿数: 75
投稿日時: 2004-05-18 15:18
C#ですか。
VBへのコンバート、
がんばってみます。

ありがとうございました。
adtk
ベテラン
会議室デビュー日: 2004/02/06
投稿数: 75
投稿日時: 2004-05-18 17:28
下のような感じでVBに変換してみましたが、
PtrToStructure
のところで、
「'System.NullReferenceException' のハンドルされていない例外が mscorlib.dll で発生しました。
追加情報 : オブジェクト参照がオブジェクト インスタンスに設定されていません。」
というエラーが発生してしまいます。

一つ目のImmGetConversionListの後に
astrSourceの値から最後尾の1文字が消失してしまっているのも気になります。


Public Declare Function ImmGetContext Lib "imm32.dll" Alias "ImmGetContext" (ByVal hwnd As IntPtr) As IntPtr
Public Declare Function GetKeyboardLayout Lib "user32" Alias "GetKeyboardLayout" (ByVal dwLayout As Integer) As IntPtr
Public Declare Function ImmGetConversionList Lib "imm32.dll" Alias "ImmGetConversionListA" (ByVal hkl As IntPtr, ByVal himc As IntPtr, ByVal lpsz As String, ByRef lpCandidateList As IntPtr, ByVal dwBufLen As Integer, ByVal uFlag As Integer) As Integer
Public Declare Function ImmReleaseContext Lib "imm32.dll" Alias "ImmReleaseContext" (ByVal hwnd As IntPtr, ByVal himc As IntPtr) As Integer

<StructLayout(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 'CANDIDATELIST

Public Shared Function uConvKana(ByVal astrSource As String _
, ByVal aHWnd As IntPtr) As String
Dim hIMC As IntPtr = ImmGetContext(aHWnd)
Dim hKL As IntPtr = GetKeyboardLayout(0)
Dim list As New CANDIDATELIST
Dim dwSize As Integer = ImmGetConversionList(hKL, hIMC, astrSource, IntPtr.Zero, 0, &H2)
Dim BufList As IntPtr = Marshal.AllocHGlobal(dwSize)
ImmGetConversionList(hKL, hIMC, astrSource, BufList, dwSize, &H2)
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.Default.GetString(buf, os, buf.Length - os - 3)
Dim par As Char() = CType(ControlChars.NullChar, String).ToCharArray()
Dim strList As String() = str.Split(par)
ImmReleaseContext(aHWnd, hIMC)
Return strList(0)
End Function
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2004-05-18 18:33
諸農です。

時間が無いので。すみません。

dwSizeには必要なサイズが戻ってきていますか?

引用:

PtrToStructure
のところで、
「'System.NullReferenceException' のハンドルされていない例外が mscorlib.dll で発生しました。
追加情報 : オブジェクト参照がオブジェクト インスタンスに設定されていません。」
というエラーが発生してしまいます。

一つ目のImmGetConversionListの後に
astrSourceの値から最後尾の1文字が消失してしまっているのも気になります。



「KB:IME 2000 における下二桁がゼロの UNICODE 文字について」
http://support.microsoft.com/default.aspx?scid=kb;ja;417206

は参考になりますか?

あと、コードはコードタグで囲っていただけると読みやすいです。

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

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/

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