激活表单并同时单击处理按钮



我在c#中使用Windows窗体。

我有一个主要的形式与一对工具栏,其中包含toolStripButtons。在使用另一个包含数据的表单后,主表单失去焦点,并且单击toolStripButton不会触发OnClick事件:第一次单击激活主表单,只有第二次单击才真正按下按钮。我需要用户点击一个按钮,只有一次触发点击事件,任何想法如何做到这一点?谢谢。

指出:

  • 我正在使用MDI,点击父窗体按钮没有问题。但是现在最重要的是让表单在多个显示器之间自由浮动。
  • 工作表单将主表单作为Owner属性,这样它们就会位于主表单的顶部。
  • 当我点击非活动表单的按钮时,没有鼠标悬停,鼠标进入,鼠标向下和鼠标向上触发。它只是主表单触发的激活事件。
  • 在主表单上有一个treeView(在tabControl中,在splitContainer中,在panel中)即使主窗体处于非活动状态,也会在第一次单击鼠标时选中它的项。我想并不是所有的控制都是一样的!

您需要做的是创建一个继承ToolStrip并处理WndProc的类。这是一种方法。

private class MyToolStrip : ToolStrip
{
    private const uint WM_LBUTTONDOWN = 0x201;
    private const uint WM_LBUTTONUP   = 0x202;
    private static bool down = false;
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_LBUTTONUP && !down)
        {
            m.Msg = (int)WM_LBUTTONDOWN;
            base.WndProc(ref m);
            m.Msg = (int)WM_LBUTTONUP;
        }
        if (m.Msg == WM_LBUTTONDOWN) down = true;
        if (m.Msg == WM_LBUTTONUP)   down = false;
        base.WndProc(ref m);
    }
}

我也见过这样的解决方案:

protected override void WndProc(ref Message m)
{
    // WM_MOUSEACTIVATE = 0x21
    if (m.Msg == WM_MOUSEACTIVATE && this.CanFocus && !this.Focused)
        this.Focus();
    base.WndProc(ref m);
}

我在最后一个工作的地方遇到了这个问题,我认为我想出的解决方案更像后者,但我没有访问我使用的确切代码。

如果你有没有边界的形式,所以这个逻辑是为你工作内置:)

form.FormBorderStyle = FormBorderStyle.None