您的位置:首页 > WinForm >

自定义一个控件继承基类usercontrol,但是不能输入中文 (完美解

2012-05-03 11:18 来源:未知编辑:admin点击:

就为第个问题我花了很多的时间.搜索了许多的网站.都没有找到解决办法.
被逼无耐只好自已看源代码。还参考了MONO的源码。发现它们之间差别非常大。而且在VS里看看源码很困难

,没有类查找功能。只能一个类文件一个类文件的打开看,想看看这个方法里边用的其它类只能一步步的跟

。还是因为我没找到好的方法呢?最终我放弃了这个方法。我用了反编译软件Reflector.exe。这个软件查

找很方便。只要点击就能找到你想看到的东西.我先找到了UserControl类,我随便看了一个,发现覆写了

WndProc
protected override void WndProc(ref Message m)
{
if (m.Msg == 7)
{
this.WmSetFocus(ref m);
}
else
{
base.WndProc(ref m);
}
}
这里好像没什么重要的,我先点了this.WmSetFocus。然后点base.WndProc(ref m)。一下就跳到了基类

ContainerControl的
protected override void WndProc(ref Message m)
{
if (m.Msg == 7)
{
this.WmSetFocus(ref m);
}
else
{
base.WndProc(ref m);
}
}
我再次点this.WmSetFocus,到达这个函数
private void WmSetFocus(ref Message m)
{

if (!base.HostedInWin32DialogManager)
{
if (this.ActiveControl != null)
{
base.WmImeSetFocus();
if (!this.ActiveControl.Visible)
{
this.OnGotFocus(EventArgs.Empty);
}
this.FocusActiveControlInternal();
}......

}
这时看到了base.WmImeSetFocus(),我欣喜若狂.秘密一定在这里面.点击后到达了

Control.WmImeSetFocus().

internal void WmImeSetFocus()
{
if (ImeModeConversion.InputLanguageTable != ImeModeConversion.UnsupportedTable)
{
this.UpdateImeContextMode();
}
}
接着再往下,
internal void UpdateImeContextMode()
{
ImeMode[] inputLanguageTable = ImeModeConversion.InputLanguageTable;
if ((!base.DesignMode && (inputLanguageTable != ImeModeConversion.UnsupportedTable)) &&

this.Focused)
{
ImeMode disable = ImeMode.Disable;
ImeMode cachedImeMode = this.CachedImeMode;
if (this.ImeSupported && this.CanEnableIme)
{
disable = (cachedImeMode == ImeMode.NoControl) ? PropagatingImeMode :

cachedImeMode;
}
if ((this.CurrentImeContextMode != disable) && (disable != ImeMode.Inherit))
{
this.DisableImeModeChangedCount++;
ImeMode propagatingImeMode = PropagatingImeMode;
try
{
ImeContext.SetImeStatus(disable, this.Handle);
}
finally
{
this.DisableImeModeChangedCount--;
if ((disable == ImeMode.Disable) && (inputLanguageTable ==

ImeModeConversion.ChineseTable))
{
PropagatingImeMode = propagatingImeMode;
}
}
if (cachedImeMode == ImeMode.NoControl)
{
if (this.CanEnableIme)
{
PropagatingImeMode = this.CurrentImeContextMode;
}
}
else
{
if (this.CanEnableIme)
{
this.CachedImeMode = this.CurrentImeContextMode;
}
this.VerifyImeModeChanged(disable, this.CachedImeMode);
}
}
}
}

所有的秘密都再这里边了.得这些代码让我看傻眼。 我要怎么弄呢?MS的代码我不能改呀。要我重写一个类

似的类吗?天啊?里边用了那么多类,msdn里根本就找不到说明,对于我来说这太难了。这时就想放弃吧!
在这里折腾了好一会,反代码反复看了看。发现就两个属性决定了程序逻辑。this.CanEnableIme 和

this.ImeSupported。点开ImeSupported好像没什么。
private bool ImeSupported
{
get
{
return (this.DefaultImeMode != ImeMode.Disable);
}
}
再点CanEnableIme。惊喜!............
protected virtual bool CanEnableIme
{
get
{
return this.ImeSupported;
}
}
既然是virtual,那个覆写试试。 在我自定义的类里加上了下面的代码

protected override bool CanEnableIme
{
get
{
return true;
}
}
就这么简单。有效吗?我不知道。运行了现说吧!F5!程序起来了,赶紧打开输入法试试,看看能不能输中

文。啊!世界太美了!我终于成功了。