C#下实现空白窗体中文输入

在空白窗体上打开输入法,在C#里的空白窗口是无论如何也是打不开输入法.设置了this.ImeMode= ImeMode.NoControl也是无法打开输入法的录字窗口.去Microsoft 开发论坛上问了一些问题.感谢周雪峰版主与Riquel_Dong 版主给的指点.用了API函数: ImmAssociateContext(IntPtr hWnd, IntPtr hIMC);终于把输入法给调了出来,它的功能是把输入与指定的窗口进行关联.

  在空白窗体上打开输入法,在C#里的空白窗口是无论如何也是打不开输入法.设置了this.ImeMode= ImeMode.NoControl也是无法打开输入法的录字窗口.去Microsoft 开发论坛上问了一些问题.感谢周雪峰版主与Riquel_Dong 版主给的指点.用了API函数: ImmAssociateContext(IntPtr hWnd, IntPtr hIMC);终于把输入法给调了出来,它的功能是把输入与指定的窗口进行关联.

  代码如下:


      f (m.Msg == WM_IME_SETCONTEXT && m.WParam.ToInt32() == 1)
  {
  ImmAssociateContext(this.Handle, m_hImc);
  }

 

  现在可以调用输入法了.可是又出现了新的问题.怎么样取得输入法录字窗体上的字呢.

  当打开输入法输入文字时,会发送WM_IME_CHAR的消息.我们在这个消息下处理下就可以得到汉字了

  可以用IMM的函数: ImmGetCompositionString(IntPtr hIMC, int dwIndex, StringBuilder  lPBuf, int dwBufLen);取得录字窗体上输入的汉字或者NUICODE类的字.当然,这里就不研究别的了.只说汉字问题.

  取字的代码如下:


     case WM_IME_CHAR:
  int size = ImmGetCompositionString(m_hImc, GCS_COMPSTR, null, 0);
  size += sizeof(Char);
  ImmGetCompositionString(m_hImc, GCS_RESULTSTR, str, size);
  sb.Append(str.ToString());
  MessageBox.Show(str.ToString());
  intoText();//打印文字
  isShowChina = true;
  break;

 

  OK,.好象是大功告成了.测试了一下才发现打印出来的都是重复的文字.比如输入”为人民服务”,打印出的却是”为为人人民民服服务务”我的天呐,问题出在哪里呢.

  去查了一下MSDN.对WM_IME_CHAR有这样的说明:

  the WM_IME_CHAR message includes a double-byte character and the application passes this message to DefWindowProc

  是不是问题就出在这里了.是发送消息两次的问题.

  看了一个网上的讨论,得出一个解决方案:加上判断


    if (m.WParam.ToInt32() == PM_REMOVE)
  {
  }

 

  测试.终于没有了问题了

  代码帖子上


 using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Drawing;
  using System.Data;
  using System.Text;
  using System.Windows.Forms;
  using System.Runtime.InteropServices;
  namespace WindowSAPplication2
  {
  public partial class UserControl1 : UserControl
  {
  IntPtr m_hImc;
  bool isShowChina = false;
  public const int WM_IME_SETCONTEXT = 0x0281;
  private const int WM_IME_CHAR = 0x0286;
  private const int WM_CHAR = 0x0102;
  private const int WM_IME_COMPOSITION = 0x010F;
  private const int GCS_COMPSTR = 0x0008;
  [DllImport("Imm32.dll")]
  public static extern IntPtr ImmGetContext(IntPtr hWnd);
  [DllImport("Imm32.dll")]
  public static extern IntPtr ImmAssociateContext(IntPtr hWnd, IntPtr hIMC);
  [DllImport("imm32.dll")]
  static extern int ImmGetCompositionString(IntPtr hIMC, int dwIndex, StringBuilder  lPBuf, int dwBufLen);
  private int GCS_RESULTSTR = 0x0800;
  private const int HC_ACTION = 0;
  private const int PM_REMOVE  = 0x0001;
  StringBuilder sb = new StringBuilder();
  Font font = new Font("宋体", 14, FontStyle.Regular);
  public UserControl1()
  {
  InitializeComponent();
  }
  private void UserControl1_Load(object sender, EventArgs e)
  {
  m_hImc = ImmGetContext(this.Handle);
  }
  protected override void WndProc(ref Message m)
  {
  base.WndProc(ref m);
  if (m.Msg == WM_IME_SETCONTEXT && m.WParam.ToInt32() == 1)
  {
  ImmAssociateContext(this.Handle, m_hImc);
  }
  switch (m.Msg)
  {
  case WM_CHAR:
  KeyEventArgs e = new KeyEventArgs(((Keys)((int)((long)m.WParam))) | ModifierKeys);
  char a = (char)e.KeyData; //英文
  sb.Append(a);
  intoText();
  isShowChina = false;
  break;
  case WM_IME_CHAR:
  if (m.WParam.ToInt32() == PM_REMOVE) //如果不做这个判断.会打印出重复的中文
  {
  StringBuilder str = new StringBuilder();
  int size = ImmGetCompositionString(m_hImc, GCS_COMPSTR, null, 0);
  size += sizeof(Char);
  ImmGetCompositionString(m_hImc, GCS_RESULTSTR, str, size);
  sb.Append(str.ToString());
  MessageBox.Show(str.ToString());
  intoText();
  isShowChina = true;
  }
  break;
  }
  }
  /// 
  /// 打印文字
  /// 
  private void intoText()//
  {
  Graphics g  = this.CreateGraphics();
  g.DrawString(sb.ToString(), font, Brushes.Black, 10, 10);
  }
  }
  }

你可能感兴趣的:(C#)