补充:采用OnActivited事件激活输入法,那么这个窗体的TopMost属性应该为false才能使输入法设置有效。这个原因可能是由于设置TopMost为True时,将此句代码写入构造函数里,而此时修复输入法的代码还没有被执行。也是说,将TopMost=True的代码写在窗体的OnLoad事件中,没有问题了。于是,我把输入法修复的代码修改如下:
#region 解决输入法BUG
[DllImport("imm32.dll")]
public static extern IntPtr ImmGetContext(IntPtr hwnd);
[DllImport("imm32.dll")]
public static extern bool ImmSetOpenStatus(IntPtr himc, bool b);
delegate void fixImeDele();
protected override void OnLoad(EventArgs e)
{
fixImeDele fixime = delegate
{
IntPtr HIme = ImmGetContext(this.Handle);
ImmSetOpenStatus(HIme, true);
};
this.BeginInvoke(fixime);
this.TopMost = true;
base.OnLoad(e);
}
#endregion
  注意这里使用了一个小技巧,用包含BeginInvoke语句的OnLoad方法代替了原先的OnActivited方法,TopMost=True也写在这个OnLoad重载里,这样,窗口置顶和输入法开启的代码全部有效。BTW,在Onload中加入BeginInvoke的方式还可以解决Control.Focus()方法在Load中失效的问题,原理和这个一样,写在委托里调用是了,范例参见:《WinForm IME输入法BUG测试》。