テキストボックスから読み仮名を別のテキストボックスに自動的に入力したいことがあると思います。ありがたいことに無料で公開されているMicrosoft Visual Studio Internaltional Pack 2.0 に含まれるコントロールやExtenderを使用すると、Forms, WPF, ASP.NET でフリガナを求める機能を実現できます。

.NET 4.0 をサポートする Microsoft Visual Studio International Pack は公開されていないので、 IME の機能を使用して 入力された漢字から読み仮名を、 読み仮名から漢字を求めるプログラムを作成してみました。あくまでIMEの機能を利用して 第一候補の変換対象が取得されていると思うので、厳密の意味での変換ではないので注意してください。

厳密に今まさにテキストボックスに入力された漢字から読み仮名を取得するには Web上を調べたところ WM_IME_COMPOSITIONなどのメッセージをフックして処理する必要があるみたいです。@IT に記事があったので参考までにURLを記載します。

IMEで入力された日本語の読みを取得するには?[C#、VB]
http://www.atmarkit.co.jp/fdotnet/dotnettips/875imeyomi/imeyomi.html

検証した環境は次の通りです

  • Visual Studio 2012 Ultimate, .NET 4.5 でコンソールプログラム作成
  • Windows Server 2012 上で動作
  • 同PC上に Office 2013 がインストールされている。(あんまり関係ないと思いますが。)

本サンプルを作成するに当たり、次のサイトを参考にさせていただきました。ここで ActivatorのCreateInstance メソッドで  COMのProgIDからCOMオブジェクト作れること知りました。参考になります。

漢字の読みを得るには C#版 - Marshalで遊ぼう
http://tu3.jp/0964

1. サンプルプログラム

コンソールプロジェクトを作成し、 Program.cs を次のように編集します。 Activator.CreateInstance で ProgID から COMオブジェクトのインスタンスを作成します。GetPhonetic メソッドで漢字から読み仮名に変換しています。GetConversion メソッドで 漢字をフリガナに変換しています。IMEの機能を使用しています。厳密な変換ではなく第一候補を求めているだけなので注意してください。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace MsImeTest
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            const int S_OK = 0;
            IFELanguage ifelang = null;
            try
            {
                ifelang = Activator.CreateInstance(Type.GetTypeFromProgID("MSIME.Japan")) as IFELanguage;
                int hr = ifelang.Open();
                if (hr != 0)
                {
                    throw Marshal.GetExceptionForHR(hr);
                }
                string yomigana;
                hr = ifelang.GetPhonetic("東京は昨日雪が降りました。", 1, -1, out yomigana);
                if (hr != 0)
                {
                    throw Marshal.GetExceptionForHR(hr);
                }
                Console.WriteLine("漢字の読み仮名:" + yomigana);

                string henkankouho;
                hr = ifelang.GetConversion("どようのひるはうなぎ", 1, -1, out henkankouho);
                if (hr != 0)
                {
                    throw Marshal.GetExceptionForHR(hr);
                }
                Console.WriteLine("平仮名の変換候補:" + henkankouho);
                //uint mode = 0;
                //ifelang.GetConversionModeCaps(ref mode);
                ifelang.Close();

                Console.ReadLine();
            }
            catch (COMException ex)
            {
                if (ifelang != null) ifelang.Close();
            }
        }
    }
    // IFELanguage2 Interface ID
    //[Guid("21164102-C24A-11d1-851A-00C04FCC6B14")]
    [ComImport]
    [Guid("019F7152-E6DB-11d0-83C3-00C04FDDB82E")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IFELanguage
    {
        int Open();
        int Close();
        int GetJMorphResult(uint dwRequest, uint dwCMode, int cwchInput, [MarshalAs(UnmanagedType.LPWStr)] string pwchInput, IntPtr pfCInfo, out object ppResult);
        int GetConversionModeCaps(ref uint pdwCaps);
        int GetPhonetic([MarshalAs(UnmanagedType.BStr)] string @string, int start, int length, [MarshalAs(UnmanagedType.BStr)] out string result);
        int GetConversion([MarshalAs(UnmanagedType.BStr)] string @string, int start, int length, [MarshalAs(UnmanagedType.BStr)] out string result);
    }
}

カタカナに変換などより細かい変換は GetJMOrphResult メソッドを使用すれば実現できそうですが、今回は詳しく調べませんでした。誰か教えてください。

IFElanguage については次のURLを参照してください。また、IFELanguage Interface の定義も下記ページからダウンロードできる msime.h を参考に定義しています。

Input Method Editor Reference
http://msdn.microsoft.com/en-us/library/office/ee828920(v=office.12).aspx

2. 動作確認

プログラムの実行結果です。

3. まとめ

今回の説明は以上です。簡単に 漢字から読み仮名、読み仮名から漢字を取得できないかなぁと思ってちょっと作成してみました。