补充:采用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测试》。