同时激活表单和处理按钮?

发布于 2024-11-27 18:03:46 字数 540 浏览 6 评论 0原文

我在 C# 中使用 Windows 窗体。

我有一个主窗体,其中有几个包含 toolStripButtons 的工具栏。使用包含数据的另一个窗体后,主窗体失去焦点,并且单击 toolStripButton 不会触发 OnClick 事件:第一次单击激活主窗体,只有第二次单击实际按下按钮。我需要用户仅单击按钮一次即可触发 Click 事件,关于如何做到这一点有什么想法吗?谢谢。

注意:

  • 我使用的是 MDI,单击父级表单按钮没有任何问题。但现在最重要的是让表单在多个显示器上自由浮动。
  • 工作人员窗体将主窗体作为所有者属性,这样它们就保留在主窗体之上。
  • 当我单击非活动表单的按钮时,MouseHover、MouseEnter、MouseDown 和 MouseUp 都不会触发。它只是触发主窗体的激活事件。
  • 主窗体上有一个 treeView(在 tabControl 内、splitContainer 内、面板内)。即使主窗体处于非活动状态,第一次单击鼠标即可选择其项目。我想并不是所有的控件都是平等的!

I'm using Windows Forms in C#.

I have a main form with a couple of toolbars that contain toolStripButtons. After working with another form that contains data, the main form loses focus and clicking on a toolStripButton does not trigger OnClick event: the first click activates the main form, and only the second click actually pushes the button. I need the user to click a button only once to trigger a Click event, any ideas on how to do that? Thanks.

Notes:

  • I was using MDI and there were no problems clicking on the parent's form buttons. But now the paramount is to have forms freely floating across multiple displays.
  • The worker forms have the main form as the Owner property, this way they stay on top of the main form.
  • When I click on the button of an inactive form, none of MouseHover, MouseEnter, MouseDown nor MouseUp fires. It's just main form's Activate event that fires.
  • There is a treeView (inside a tabControl, inside a splitContainer, inside a panel), on the main form. Its items are selected upon a first mouse click, even if the main form is inactive. I guess not all controls are equal!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

枫以 2024-12-04 18:03:46

您需要做的是创建一个继承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);
}

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

What you need to do is create a class that inherits ToolStrip and handles the WndProc. This is one way to do it. There are others.

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);
    }
}

I've also seen this solution:

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);
}

I ran into this at the last place I worked, I think the solution I came up with worked more like the latter, but I don't have access to the exact code I used.

泪意 2024-12-04 18:03:46

如果你有无边框的表单,那么这个逻辑对你来说是内置的:)

form.FormBorderStyle = FormBorderStyle.None

if u have Form without borders, so this logic was working for you built in :)

form.FormBorderStyle = FormBorderStyle.None
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文