www.pudn.com > input.rar > IME.cs


using System; 
using System.Text; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 
using System.Drawing; 
using System.Text.RegularExpressions; 
 
namespace InputMethodReader 
{ 
    public class IME : Form 
    { 
        ///  
        /// 争渡(QQ258190355) 
        /// 20080529 
        ///  
        // 型定義 
 
 
        #region API Calls 
        // Imm系メソッド 
        [DllImport("imm32.dll")] 
        public static extern IntPtr ImmGetContext(IntPtr hWnd); 
        [DllImport("imm32.dll")] 
        public static extern bool ImmSetCompositionWindow(IntPtr hIMC, ref COMPOSITIONFORM lpCompForm); 
        [DllImport("imm32.dll")] 
        public static extern int ImmSetCompositionFont(IntPtr hIMC, ref LOGFONT lplf); 
        [DllImport("imm32.dll")] 
        public static extern int ImmReleaseContext(IntPtr hWnd, IntPtr hIMC); 
        //获取选择上去的字符 
        [DllImport("imm32.dll")] 
        public static extern int ImmGetCompositionString(IntPtr hIMC, uint dwIndex, StringBuilder lpBuf, uint dwBufLen); 
        //获取候选所有字 
        [DllImport("imm32.dll", EntryPoint = "ImmGetCandidateList")] 
        public static extern int ImmGetCandidateList(IntPtr himc, int deIndex, IntPtr lpCandidateList, int dwBufLen); 
 
        #endregion 
 
        #region structs 
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
        public struct LOGFONT 
        { 
            public int lfHeight; 
            public int lfWidth; 
            public int lfEscapement; 
            public int lfOrientation; 
            public int lfWeight; 
            public byte lfItalic; 
            public byte lfUnderline; 
            public byte lfStrikeOut; 
            public byte lfCharSet; 
            public byte lfOutPrecision; 
            public byte lfClipPrecision; 
            public byte lfQuality; 
            public byte lfPitchAndFamily; 
            // stringでいけると書いてあったがうまく動かないのでこれで 
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = LF_FACESIZE * 2)] 
            public byte[] lfFaceName; 
        } 
        [StructLayout(LayoutKind.Sequential)] 
        public struct RECT 
        { 
            public int Left; 
            public int Top; 
            public int Right; 
            public int Bottom; 
        } 
        [StructLayout(LayoutKind.Sequential)] 
        public struct POINTAPI 
        { 
            public int x; 
            public int y; 
        } 
        [StructLayout(LayoutKind.Sequential)] 
        public struct COMPOSITIONFORM 
        { 
            public uint dwStyle; 
            public POINTAPI ptCurrentPos; 
            public RECT rcArea; 
        } 
 
        [StructLayout(LayoutKind.Sequential)] 
        public class CANDIDATELIST 
        { 
            public int dwSize;// 用字节表示的内存大小:=sizeof(CANDIDATELIST)+选择字符数据 
            public int dwStyle;// 列表串的取值方式 
            public int dwCount;// 当前列表个数 
            public int dwSelection; // 当前选择的列表序号 
            public int dwPageStart;// 在列表窗口中所显示的列表的起始序号(上下翻页时用) 
            public int dwPageSize;// 一页显示的列表个数 
            public int dwOffset;// 列表数据存放区地址:[阿];[大]。。。。 
        } 
 
        #endregion 
 
        #region variables 
        #endregion 
 
        #region constants 
        // IME系定義 
        public const int CFS_DEFAULT = 0x0000; 
        public const int CFS_RECT = 0x0001; 
        public const int CFS_POINT = 0x0002; 
        public const int CFS_FORCE_POSITION = 0x0020; 
        public const int CFS_CANDIDATEPOS = 0x0040; 
        public const int CFS_EXCLUDE = 0x0080; 
 
        public const int NI_COMPOSITIONSTR = 0x0015; 
        public const int CPS_CANCEL = 0x0004; 
        public const int NI_OPENCANDIDATE = 0x0010; 
        public const int IMN_OPENCANDIDATE = 0x0005; 
        public const int WM_IME_NOTIFY = 0x0282; 
 
        // IME系メッセージ 
        public const int WM_IME_STARTCOMPOSITION = 0x010D; 
        public const int WM_IME_ENDCOMPOSITION = 0x010E; 
        public const int WM_IME_COMPOSITION = 0x010F; 
        public const int WM_IME_KEYDOWN = 0x0209; 
 
        public const int LF_FACESIZE = 32; 
        #endregion 
 
        #region methods 
        // IMEで入力された文字列を取得 
        public string getImeString(IntPtr hwnd) 
        { 
            IntPtr hIMC = ImmGetContext(hwnd);//this.Handle); 
            StringBuilder buf; 
            try 
            { 
                // 訳のわからん処理だがこうしないとゴミる模様 
                int strLen = ImmGetCompositionString(hIMC, 0x800, null, 0); 
                buf = new StringBuilder(strLen); 
                int getSize = ImmGetCompositionString(hIMC, 0x800, buf, (uint)strLen); 
                byte[] by = System.Text.Encoding.Default.GetBytes(buf.ToString()); 
                return System.Text.Encoding.Default.GetString(by, 0, strLen); 
            } 
            finally 
            { 
                ImmReleaseContext(hwnd, hIMC); 
            } 
        } 
 
        // ImmSetCompositionWindowとImmSetCompositionFontのラッパー 
        public void setImeContext(bool setFont) 
        { 
            IntPtr hIMC = ImmGetContext(this.Handle);//this.Handle); 
            if (hIMC == IntPtr.Zero) 
                return; 
            try 
            { 
                // ウィンドウセット 
                COMPOSITIONFORM form = new COMPOSITIONFORM(); 
                form.dwStyle = CFS_POINT; 
                form.ptCurrentPos.x = 0;// MEMO:X位置設定 
                form.ptCurrentPos.y = 0;// MEMO:Y位置設定 
                ImmSetCompositionWindow(hIMC, ref form); 
 
                if (setFont) 
                { 
                    // なんかラッパかまして変換しないとうまくいかない 
                    object logFontWrap = new LOGFONT(); 
                    this.Font.ToLogFont(logFontWrap); 
                    LOGFONT logFont = (IME.LOGFONT)logFontWrap; 
                    byte[] by = Encoding.Default.GetBytes(this.Font.Name);  // MEMO:英語環境とかの挙動怪しいかも? 
                    for (int i = 0; i < logFont.lfFaceName.Length; i++) 
                    { 
                        logFont.lfFaceName[i] = (i >= by.Length) ? (byte)0 : by[i]; 
                    } 
                    ImmSetCompositionFont(hIMC, ref logFont); 
                } 
            } 
            finally 
            { 
                ImmReleaseContext(this.Handle, hIMC); 
            } 
        } 
 
        public string[] GetAllCandidateList(IntPtr hwnd) 
        { 
            string[] strList = null; 
            string str = ""; 
            try 
            { 
                IntPtr hIMC = ImmGetContext(hwnd); 
 
                //MessageBox.Show(hIMC.ToString()); 
                if (hIMC != IntPtr.Zero) 
                { 
                    CANDIDATELIST c = new CANDIDATELIST(); 
                    IntPtr ip = IntPtr.Zero; 
                    int dwSize = ImmGetCandidateList(hIMC, 0, ip, 0); 
                    if (dwSize > 28) 
                    { 
                        //MessageBox.Show(hIMC.ToString()); 
                        CANDIDATELIST list = new CANDIDATELIST(); 
                        IntPtr BufList = Marshal.AllocHGlobal(dwSize); 
                        ImmGetCandidateList(hIMC, 0, BufList, dwSize); 
                        Marshal.PtrToStructure(BufList, list); 
 
                        byte[] buf = new byte[dwSize]; 
                        Marshal.Copy(BufList, buf, 0, dwSize); 
                        Marshal.FreeHGlobal(BufList); 
                        int os = list.dwOffset; 
                        str = System.Text.Encoding.Default.GetString(buf, os, buf.Length - os - 2); 
                        char[] par = "\0".ToCharArray(); 
                        strList = str.Split(par); 
 
                        ImmReleaseContext(hwnd, hIMC); 
                        if (str != "") 
                            return strList; 
                    } 
                } 
            } 
            catch (Exception ex) 
            { 
                return new string[1] { "" }; 
            } 
            return new string[1] { "" }; 
 
        } 
        #endregion 
    } 
}