CandidateListを取得する
IMEのCandidateListを取得する方法
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfApp1 { /// <summary> /// Interaction logic for Page3.xaml /// </summary> public partial class Page3 : Page { public Page3() { InitializeComponent(); } public class Win32 { [DllImport("user32.dll")] public static extern IntPtr DefWindowProc(IntPtr hWnd, uint Msg, uint wParam, IntPtr lPara); [DllImport("imm32.dll", SetLastError = true)] public static extern IntPtr ImmGetContext(IntPtr hWnd); [DllImport("Imm32.dll")] public static extern long ImmReleaseContext(IntPtr hWnd, IntPtr hIMC); [DllImport("imm32.dll")] public static extern int ImmGetCandidateList(IntPtr hIMC, int iIndex, byte[] lpCandidateList, int iBuffLen); [DllImport("Imm32.dll")] public static extern int ImmNotifyIME(IntPtr hIMC, IntPtr dwAction, IntPtr dwIndex, IntPtr dwValue); } const int WM_APP = 0x8000; const int WM_CLOSE = 0x0010; const int GWL_WNDPROC = -4; // WM_IME_ const int WM_IME_CHAR = 0x0286; const int WM_IME_COMPOSITION = 0x010f; const int WM_IME_COMPOSITIONFULL = 0x0284; const int WM_IME_CONTROL = 0x0283; const int WM_IME_ENDCOMPOSITION = 0x010e; const int WM_IME_KEYDOWN = 0x0290; // const int WM_IME_KEYLAST = 0x010f; const int WM_IME_KEYUP = 0x0291; const int WM_IME_NOTIFY = 0x0282; const int WM_IME_REPORT = 0x0280; const int WM_IME_REQUEST = 0x0288; const int WM_IME_SELECT = 0x0285; const int WM_IME_SETCONTEXT = 0x0281; const int WM_IME_STARTCOMPOSITION = 0x010d; // WM_IME_SETCONTEXT lParam const int ISC_SHOWUICOMPOSITIONWINDOW = -2147483648; const int ISC_SHOWUIGUIDWINDOW = -2147483648; const int ISC_SHOWUISOFTKBD = -2147483648; const int ISC_SHOWUICANDIDATEWINDOW = 0x0001; const int ISC_SHOWUIALLCANDIDATEWINDOW = 0x000F; // WM_IME_NOTIFY wParam const int IMN_CHANGECANDIDATE = 0x0003; const int IMN_OPENCANDIDATE = 0x0005; const int IMN_SETCONVERSIONMODE = 0x0006; const int IMN_SETOPENSTATUS = 0x0008; const int IMN_SETCOMPOSITIONFONT = 0x000A; // 10 const int IMN_SETCOMPOSITIONWINDOW = 0x000B; // 11 const int GCS_COMPSTR = 0x0008; const int GCS_RESULTSTR = 0x0800; const int GCS_RESULTREADSTR = 0x0200; const int GCS_COMPREADSTR = 0x0001; // ImmNotifyIMe dwAction const int NI_CHANGECANDIDATELIST = 0x0013; // 現在選択している候補を変更した ( dwIndex:変更リストのインデックス dwValue:使わない) (dwIndex:変更リストのインデックス const int NI_CLOSECANDIDATE = 0x0011; //候補リストをクローズした (dwValue:使わない) const int NI_COMPOSITIONSTR = 0x0015; // 変換文字列を操作する (具体的な操作はdwIndexで指定する) const int NI_IMEMENUSELECTED = 0x0018; // 指定のメニューのハンドル (dwIndex:メニューID dwValue:アプリケーション定義の値) const int NI_OPENCANDIDATE = 0x0010; // 候補リストをオープン const int NI_SELECTCANDIDATESTR = 0x0012; // 候補の一つを選択した (dwIndex:候補リストのインデックス dwValue:選択した単語のインデックス) const int NI_SETCANDIDATE_PAGESIZE = 0x0017; // 候補リストのページサイズを変更した(dwValue:0~31の数値) const int NI_SETCANDIDATE_PAGESTART = 0x0016; // 候補リストを設定した (dwIndex:候補リストを指定する0~31の値) // ImmNotifyIME dwIndexの定数 const int CPS_CANCEL = 0x0004; // 変換文字列をクリアする const int CPS_COMPLETE = 0x0001; // 変換文字列を確定文字にする const int CPS_CONVERT = 0x0002; // 次の候補に変換する const int CPS_REVERT = 0x0003; // 変換文字列を取り消し、確定前確定前に戻す // ImmAssociateContextEx dwFlags const int IACE_CHILDREN = 0x0001; const int IACE_DEFAULT = 0x0010; const int IACE_IGNORENOCONTEXT = 0x0020; int ItextLength = 0; IntPtr Hwnd; private string Us100ConverterStr2(byte[] str, int start, int byteNum) { if (byteNum + start > str.Length) { byteNum = str.Length - start; } byte[] str2 = new byte[byteNum]; for (int cnt = 0; cnt < byteNum; cnt++) { str2[cnt] = str[cnt + start]; } return Encoding.Default.GetString(str2); } private void WindowMain_SizeChanged(object sender, SizeChangedEventArgs e) { InputMethod.Current.ImeState = InputMethodState.On; TextBoxInput.Focus(); } private void WindowMain_Loaded(object sender, RoutedEventArgs e) { Debug.WriteLine("WindowMain Loaded "); var helper = new WindowInteropHelper(Application.Current.MainWindow); Hwnd = helper.Handle; HwndSource source = HwndSource.FromHwnd(Hwnd); source.AddHook(new HwndSourceHook(WndProc)); // IME Default CandidateWindow を隠す Start (非表示にするとImmGetCandidateList のサイズが設定される) var lp = ~ISC_SHOWUICANDIDATEWINDOW; var lParam = new IntPtr(lp); Win32.DefWindowProc(helper.Handle, WM_IME_SETCONTEXT, 1, lParam); // 3 para は zero 以外 // IME Default CandidateWindow を隠す End } public IntPtr WndProc(IntPtr hwnd, int imsg, IntPtr wParam, IntPtr lParam, ref bool bhandled) { switch (imsg) { case WM_IME_NOTIFY: // 0x0282 Debug.WriteLine("WndProc NOTIFY : " + wParam.ToString("0") + " : " + lParam.ToString("0")); switch ((int)wParam) { case IMN_CHANGECANDIDATE: // 0x0003 ItextLength = TextBoxInput.Text.Length; bhandled = true; var himc = Win32.ImmGetContext(hwnd); var isize = Win32.ImmGetCandidateList(himc, 0, null, 0); if (isize > 0) { Debug.WriteLine("CandidateChange isize : " + isize.ToString("0")); byte[] bytebuf = new byte[isize]; ListBoxA.Items.Clear(); Win32.ImmGetCandidateList(himc, 0, bytebuf, (int)isize); int icount = System.BitConverter.ToInt32(bytebuf, 8); for (int cnt = 0; cnt < icount; cnt++) { int iOffset = System.BitConverter.ToInt32(bytebuf, cnt * 4 + 24); int len = 0; while (bytebuf[iOffset + len] != '\0') { len++; } ListBoxA.Items.Add(Us100ConverterStr2(bytebuf, iOffset, len)); } Win32.ImmReleaseContext(hwnd, himc); } break; default: Debug.WriteLine("WM_IME_NOTIFY 3 以外 : " + wParam.ToString("0") + lParam.ToString("0")); break; } break; default: break; } if (!bhandled) { Win32.DefWindowProc(hwnd, (uint)imsg, (uint)wParam, lParam); } return IntPtr.Zero; } private void ListBoxA_SelectionChanged(object sender, SelectionChangedEventArgs e) { var iidx = ListBoxA.SelectedIndex; if (iidx >= 0) { var slist = ListBoxA.Items[iidx].ToString(); TextBoxInput.Text = TextBoxInput.Text + slist; var himc = Win32.ImmGetContext(Hwnd); Win32.ImmNotifyIME(himc, (IntPtr)NI_SELECTCANDIDATESTR, (IntPtr)iidx, IntPtr.Zero); Win32.ImmReleaseContext(Hwnd, himc); } } } }