.net 我如何找到哪个控件是集中的?

.net 我如何找到哪个控件是集中的?,.net,winforms,mdi,.net,Winforms,Mdi,我有一个用vb.net编写的.net MDI应用程序。我正在尝试编写一个表单,它允许用户选择一个特殊字符,如°、µ、²、³、Γ等,并在启动表单之前通过热键或MDI父菜单将该字符插入到任何控件中 实现这一点的简单方法是,在调用字符选择表单时,找出哪个控件集中在哪个MDI子表单上,但我找不到有关如何执行此操作的任何信息 有什么想法吗?添加和监视windows消息,如或。您可以使用将INTPTR转换为.NET控件。添加和监视windows消息,如或。您可以使用将INTPTR转换为.NET控件。您可以将

我有一个用vb.net编写的.net MDI应用程序。我正在尝试编写一个表单,它允许用户选择一个特殊字符,如°、µ、²、³、Γ等,并在启动表单之前通过热键或MDI父菜单将该字符插入到任何控件中

实现这一点的简单方法是,在调用字符选择表单时,找出哪个控件集中在哪个MDI子表单上,但我找不到有关如何执行此操作的任何信息


有什么想法吗?

添加和监视windows消息,如或。您可以使用将INTPTR转换为.NET控件。

添加和监视windows消息,如或。您可以使用将INTPTR转换为.NET控件。

您可以将类似这样的类添加到项目中:

public class FocusWatcher
{
    private static System.Windows.Forms.Control _focusedControl;
    public static System.Windows.Forms.Control FocusedControl
    {
        get
        {
            return _focusedControl;
        }
    }

    public static void GotFocus(object sender, EventArgs e)
    {
        _focusedControl = (System.Windows.Forms.Control)sender;
    }
}
然后,对于任何形式的任何控件,如果您希望成为“最近关注的控件”的候选对象,您可以执行以下操作:

textBox1.GotFocus += FocusWatcher.GotFocus;
然后访问
FocusWatcher.FocusedControl
以获取最近聚焦的控件。监视消息会起作用,但您必须忽略您不想要的消息(如Mdi表单中的WM_ACTIVATE)


您可以迭代每个表单上的所有控件,并为GotFocus事件添加此处理程序,但肯定有一些控件不需要这样做(例如按钮)。您可以迭代,只添加文本框的处理程序。

您可以向项目中添加如下类:

public class FocusWatcher
{
    private static System.Windows.Forms.Control _focusedControl;
    public static System.Windows.Forms.Control FocusedControl
    {
        get
        {
            return _focusedControl;
        }
    }

    public static void GotFocus(object sender, EventArgs e)
    {
        _focusedControl = (System.Windows.Forms.Control)sender;
    }
}
然后,对于任何形式的任何控件,如果您希望成为“最近关注的控件”的候选对象,您可以执行以下操作:

textBox1.GotFocus += FocusWatcher.GotFocus;
然后访问
FocusWatcher.FocusedControl
以获取最近聚焦的控件。监视消息会起作用,但您必须忽略您不想要的消息(如Mdi表单中的WM_ACTIVATE)


您可以迭代每个表单上的所有控件,并为GotFocus事件添加此处理程序,但肯定有一些控件不需要这样做(例如按钮)。您可以迭代,只添加文本框的处理程序。

看起来WM_SETFOCUS消息没有通过。。。。我的错。我很肯定他们会通过这个方法。作为一种解决方法,我必须在每次收到消息时进行p/调用,并存储具有焦点的控件的句柄

第一个代码段是过滤器类,第二个代码段是测试代码



    public class LastFocusedControlFilter : IMessageFilter
    {
        [DllImport("user32")]
        private static extern IntPtr GetFocus();

        private IntPtr? _lastCtrl;
        private readonly Control _ctrlToIgnore;

        public LastFocusedControlFilter(Control controlToIgnore)
        {
            _ctrlToIgnore = controlToIgnore;
        }

        public bool PreFilterMessage(ref Message m)
        {
            if (!_ctrlToIgnore.IsHandleCreated || _ctrlToIgnore.Disposing || _ctrlToIgnore.IsDisposed)
            {
                return false;
            }
            IntPtr handle = GetFocus();
            if (handle != _ctrlToIgnore.Handle)
            {
                _lastCtrl = handle;
            }
            return false;
        }

        public Control GetLastFocusedControl()
        {
            return _lastCtrl.HasValue ? Control.FromHandle(_lastCtrl.Value) : null;
        }
    }
静态类程序
{
/// 
///应用程序的主要入口点。
/// 
[状态线程]
静态void Main()
{
使用(表单=新表单())
{
动作resetBackColor=null;
对于(int i=0;i<10;i++)
{
TextBox TextBox=新建TextBox();
resetBackColor+=delegate{textBox.BackColor=Color.White;};
Text=((char)('a'+i)).ToString();
textBox.Location=新点(0,textBox.Height*i);
表单.控件.添加(文本框);
}
按钮showTextButton=新按钮();
LastFocusedControlFilter msgFilter=新建LastFocusedControlFilter(showTextButton);
showTextButton.Dock=DockStyle.Bottom;
showTextButton.Text=“显示上次选定控件的文本”;
showTextButton.单击+=委托(对象发送者,事件参数e)
{
重置背景颜色();
Control lastControl=msgFilter.GetLastFocusedControl();
if(lastControl==null)
{
Show(“以前没有控件有焦点。”);
}
其他的
{
lastControl.BackColor=Color.Red;
Show(string.Format(“类型为{0}的控件的焦点为文本“{1}.”,lastControl.GetType(),lastControl.text));
}
};
表单.控件.添加(showTextButton);
Application.AddMessageFilter(msgFilter);
申请表格;
}
}
}

看起来WM_SETFOCUS消息没有通过。。。。我的错。我很肯定他们会通过这个方法。作为一种解决方法,我必须在每次收到消息时进行p/调用,并存储具有焦点的控件的句柄

第一个代码段是过滤器类,第二个代码段是测试代码



    public class LastFocusedControlFilter : IMessageFilter
    {
        [DllImport("user32")]
        private static extern IntPtr GetFocus();

        private IntPtr? _lastCtrl;
        private readonly Control _ctrlToIgnore;

        public LastFocusedControlFilter(Control controlToIgnore)
        {
            _ctrlToIgnore = controlToIgnore;
        }

        public bool PreFilterMessage(ref Message m)
        {
            if (!_ctrlToIgnore.IsHandleCreated || _ctrlToIgnore.Disposing || _ctrlToIgnore.IsDisposed)
            {
                return false;
            }
            IntPtr handle = GetFocus();
            if (handle != _ctrlToIgnore.Handle)
            {
                _lastCtrl = handle;
            }
            return false;
        }

        public Control GetLastFocusedControl()
        {
            return _lastCtrl.HasValue ? Control.FromHandle(_lastCtrl.Value) : null;
        }
    }
静态类程序
{
/// 
///应用程序的主要入口点。
/// 
[状态线程]
静态void Main()
{
使用(表单=新表单())
{
动作resetBackColor=null;
对于(int i=0;i<10;i++)
{
TextBox TextBox=新建TextBox();
resetBackColor+=delegate{textBox.BackColor=Color.White;};
Text=((char)('a'+i)).ToString();
textBox.Location=新点(0,textBox.Height*i);
表单.控件.添加(文本框);
}
按钮showTextButton=新按钮();
LastFocusedControlFilter msgFilter=新建LastFocusedControlFilter(showTextButton);
showTextButton.Dock=DockStyle.Bottom;
showTextButton.Text=“显示上次选定控件的文本”;
showTextButton.单击+=委托(对象发送者,事件参数e)
{
重置背景颜色();
Control lastControl=msgFilter.GetLastFocusedControl();
if(lastControl==null)
{
Show(“以前没有控件有焦点。”);
}
其他的
{
lastControl.BackColor=Color.Red;
Show(string.Format(“类型为{0}的控件的焦点为文本“{1}.”,lastControl.GetType(),lastControl.text));
}
};