C#のIMEについて,いろいろなサイトを参考に以下のようなコードを使って平仮名を漢字に変換しようとしたのですが,ImmGetCandidateLis()が常に0を返してしまい変換候補のリストが取得できません.
調べてみたところこのような現象はほかでも起こっていることはわかっています.
なにか,いい回避する方法はないでしょうか.
※ImmGetCandidateLis()がうまく働いていないので変換そのものについてはまだ未実装です.また,それ以前に何か問題の含んでいるコードである可能性があります.
C#
1using System; 2using System.Runtime.InteropServices; 3using Microsoft.International.Converters; 4using System.Text; 5using System.Collections.Generic; 6 7 public static class MyIME 8 { 9 static IntPtr hwnd; 10 static IntPtr context; 11 static string target; 12 static Queue<string> outRef; 13 14 #region Api //APIのインポート 15 [StructLayout(LayoutKind.Sequential)] 16 public class CANDIDATELIST 17 { 18 public int dwSize; 19 public int dwStyle; 20 public int dwCount; 21 public int dwSelection; 22 public int dwPageStart; 23 public int dwPageSize; 24 public int dwOffset; 25 } 26 27 [StructLayout(LayoutKind.Sequential)] 28 public struct RECONVERTSTRING 29 { 30 public uint dwSize; 31 public uint dwVersion; 32 public uint dwStrLen; 33 public uint dwStrOffset; 34 public uint dwCompStrLen; 35 public uint dwCompStrOffset; 36 public uint dwTargetStrLen; 37 public uint dwTargetStrOffset; 38 } 39 40 [DllImport("User32.dll")] 41 public static extern IntPtr GetKeyboardLayout(int idThread); 42 43 [DllImport("imm32.dll")] 44 private static extern IntPtr ImmCreateContext(); 45 46 [DllImport("imm32.dll", SetLastError = true)] 47 public static extern bool ImmAssociateContextEx(IntPtr hWnd,IntPtr hIMC,int dwFlags); 48 49 [DllImport("imm32.dll", SetLastError = true)] 50 public static extern int ImmGetCandidateList( 51 IntPtr hIMC, int deIndex, ref CANDIDATELIST lpCandidateList, 52 int dwBufLen); 53 54 [DllImport("imm32.dll", SetLastError = true)] 55 public static extern int ImmGetCandidateList( 56 IntPtr hIMC, int deIndex, byte[] lpCandidateList, 57 int dwBufLen); 58 59 [DllImport("imm32.dll", SetLastError = true)] 60 public static extern int ImmGetCandidateList( 61 IntPtr hIMC, int deIndex,IntPtr lpCandidateList, 62 int dwBufLen); 63 64 [DllImport("Imm32.dll", SetLastError=true)] 65 public static extern int ImmGetConversionList( 66 IntPtr hKL,IntPtr hIMC,string lpSrc, 67 IntPtr lpDst,int dwBufLen,int uFlag); 68 69 70 [DllImport("Imm32.dll")] 71 private static extern int ImmSetCompositionString( 72 IntPtr hImc,int index, IntPtr lpComp,int dwCompLen, 73 System.Text.StringBuilder lpRead, int dwReadLen); 74 75 [DllImport("Imm32.dll")] 76 private static extern int ImmSetCompositionString( 77 IntPtr hImc,int index, IntPtr lpComp,int dwCompLen, 78 int lpRead, int dwReadLen); 79 80 [DllImport("imm32.dll")] 81 public static extern bool ImmSetConversionStatus(IntPtr hIMC, ref int dwConversion, ref int dwSentence); 82 83 [DllImport("imm32.dll")] 84 public static extern bool ImmGetConversionStatus(IntPtr hIMC, ref int dwConversion, ref int dwSentence); 85 86 [DllImport("Imm32.dll")] 87 private static extern IntPtr ImmGetContext(IntPtr hWnd); 88 89 [DllImport("imm32.dll")] 90 public static extern int ImmNotifyIME(IntPtr hIMC, int dwAction, int dwIndex, int dwValue); 91 92 [DllImport("Imm32.dll")] 93 public static extern bool ImmSetOpenStatus(IntPtr hIMC, bool fOpen); 94 95 [DllImport("Imm32.dll")] 96 public static extern bool ImmReleaseContext(IntPtr hWnd, IntPtr hIMC); 97 98 [DllImport("imm32.dll", SetLastError = true)] 99 public static extern int ImmGetGuideLine( 100 int hIMC, int dwIndex, string lpBuf, 101 int dwBufLen); 102 103 [DllImport("imm32.dll", SetLastError = true)] 104 public static extern int ImeGetCandidateListCount(int hIMC, ref int lpdwListCount); 105 106 107 #endregion 108 109//初期化メゾットhidは対象となるFormクラスのハンドル 110 public static void IMEStart(IntPtr hid) 111 { 112 hwnd = hid; 113 target = ""; 114 context = ImmCreateContext(); 115 ImmAssociateContextEx(hid, context, 0x1); 116 } 117 118//終了メゾット 119 public static void IMEEnd() 120 {} 121 122//対象となる文字列のプロパティ 123 public static string Target 124 { 125 get 126 { 127 return target; 128 } 129 set 130 { 131 if(target != value) 132 { 133 target = value; 134 } 135 } 136 } 137 138//変換中の文字列 139 public static string PreConvert() 140 { 141 return KanaConverter.RomajiToHiragana(target); 142 } 143 144 145 146 public static void SetConvert(IntPtr nhwnd) 147 { 148 149 StringBuilder sb = new StringBuilder(target); 150 151 int dwConversion = 0, dwSentence = 0; 152 153 if (!ImmSetOpenStatus(context, true)) 154 return; 155 156 if (!ImmGetConversionStatus(context, ref dwConversion, ref dwSentence)) 157 return; 158 159 dwConversion &= ~0x100; 160 161 if (!ImmSetConversionStatus(context, ref dwConversion, ref dwSentence)) 162 return; 163 164 if (ImmSetCompositionString( 165 context, 0x9, IntPtr.Zero, 166 Marshal.SizeOf<IntPtr>(), sb, Encoding.Default.GetByteCount(target)) == 0) 167 return; 168 169 if (ImmNotifyIME(context, 0x15, 2, 0) == 0) 170 return; 171 172 int size = ImmGetCandidateList(context,0,IntPtr.Zero,0); 173 IntPtr bp = Marshal.AllocHGlobal(size); 174 if(ImmGetCandidateList(context,0,bp,size) != 0) 175 { 176 CANDIDATELIST list = new CANDIDATELIST(); 177 Marshal.PtrToStructure(bp, list); 178 outRef = new Queue<string>(); 179 } 180 181// ImmReleaseContext(hwnd, context); 182 183 } 184 185 public static string Convert() 186 { 187 string ans = ""; 188 if(outRef != null && outRef.Count != 0) 189 { 190 ans = outRef.Dequeue(); 191 outRef.Enqueue(ans); 192 } 193 return ans; 194 } 195 196 public static void ResetConvert() 197 {} 198 }
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/03/11 06:00