大致代码如下:[DllImport("imm32.dll")]
        public static extern IntPtr ImmGetContext(IntPtr hWnd);
        [DllImport("imm32.dll")]
        public static extern int ImmReleaseContext(IntPtr hWnd, IntPtr hIMC);
        [DllImport("imm32.dll")]
        public static extern bool ImmSetCompositionWindow(IntPtr hIMC, ref COMPOSITIONFORM lpCompForm);

        [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 Point ptCurrentPos;
            public RECT rcArea;
        }
private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            IntPtr hImc = ImmGetContext(this.textBox1.Handle);            COMPOSITIONFORM cf = new COMPOSITIONFORM();
            cf.dwStyle = 0x0000;
            cf.ptCurrentPos.X = 10;
            cf.ptCurrentPos.Y = 10;
            cf.rcArea.Bottom = 10;
            cf.rcArea.Top = 10;
            cf.rcArea.Left = 10;
            cf.rcArea.Right = 10;
            bool setcom = ImmSetCompositionWindow(hImc, ref cf);            ImmReleaseContext(hImc, this.textBox1.Handle);
        }
现在问题是,我如何控制IME的composition window位置?我希望能让composition window出现在光标的左上方。现在还碰到一个问题是,如果textbox过大,那个composition就跳不出来,很奇怪,希望高人给我点办法

解决方案 »

  1.   

    [DllImport("imm32.dll")]
            public static extern IntPtr ImmGetContext(IntPtr hWnd);
            [DllImport("imm32.dll")]
            public static extern int ImmReleaseContext(IntPtr hWnd, IntPtr hIMC);
            [DllImport("imm32.dll")]
            public static extern bool ImmSetCompositionWindow(IntPtr hIMC, ref  COMPOSITIONFORM lpCompForm);        [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 Point ptCurrentPos;
                public RECT rcArea;
            }        private void textBox1_KeyDown(object sender, KeyEventArgs e)
            {
                IntPtr hImc = ImmGetContext(this.textBox1.Handle);            COMPOSITIONFORM cf = new COMPOSITIONFORM();
                cf.dwStyle = 2;            Point p = GetCursorPos(this.textBox1.Handle.ToInt32());
                Point p1 = this.textBox1.PointToScreen(p);
                cf.ptCurrentPos.X = p.X-300;
                cf.ptCurrentPos.Y =p.Y-100;
                //cf.rcArea.Bottom = 100;
                //cf.rcArea.Top =0;
                //cf.rcArea.Left = p1.X - 900;
                //cf.rcArea.Right = p1.X-500;
                bool setcom = ImmSetCompositionWindow(hImc, ref  cf);            ImmReleaseContext(hImc, this.textBox1.Handle);
                       }         const int EM_GETSEL = 0xB0;   
             const int EM_LINEFROMCHAR = 0xC9;   
             const int EM_LINEINDEX = 0xBB;   
             [DllImport("user32.dll", EntryPoint = "SendMessage")]   
             public static extern int SendMessage(   
                 int hwnd,   
                 int wMsg,   
                 int wParam,   
                 ref int lParam   
             );   
             private Point GetCursorPos(int TextHwnd)   
             {   
                 int i = 0, j = 0, k = 0;   
                 int lParam = 0, wParam = 0;   
                 i = SendMessage(TextHwnd, EM_GETSEL, wParam, ref lParam);   
                 j = i / 65536;   
                 int lineNo = SendMessage(TextHwnd, EM_LINEFROMCHAR, j, ref lParam) + 1;   
                 k = SendMessage(TextHwnd, EM_LINEINDEX, -1, ref lParam);   
                 int colNo = j - k + 1;   
                 Point ret = new Point(lineNo, colNo);   
                 return ret;   
             }   输入法的坐标位置还需要调整
      

  2.   

    请问2楼兄弟,dwStyle = 2是什么意思?
      

  3.   

    http://msdn.microsoft.com/en-us/library/dd317764(v=VS.85).aspxCFS_DEFAULT Move the composition window to the default position. The IME window can display the composition window outside the client area, such as in a floating window. 
    CFS_FORCE_POSITION Display the upper left corner of the composition window at exactly the position specified by ptCurrentPos. The coordinates are relative to the upper left corner of the window containing the composition window and are not subject to adjustment by the IME. 
    CFS_POINT Display the upper left corner of the composition window at the position specified by ptCurrentPos. The coordinates are relative to the upper left corner of the window containing the composition window and are subject to adjustment by the IME. 
    CFS_RECT Display the composition window at the position specified by rcArea. The coordinates are relative to the upper left of the window containing the composition window. http://dev.firnow.com/course/4_webprogram/asp.net/netjs/2008215/99962_35.htmlPublic Const CFS_DEFAULT = &H0
    Public Const CFS_RECT = &H1
    Public Const CFS_POINT = &H2
    Public Const CFS_SCREEN = &H4
    Public Const CFS_FORCE_POSITION = &H20
    Public Const CFS_CANDIDATEPOS = &H40
    Public Const CFS_EXCLUDE = &H80