如何使一个ToolStrip按钮在没有先点击窗体的情况下立即可点击?

8
我有一个Windows Forms应用程序,其中包含工具栏和按钮。令人沮丧的是,当表单没有焦点时,我必须点击两次任何按钮才能使其触发。第一次点击似乎会激活表单,然后第二次点击才能点击按钮(或者,我可以在表单上的任何位置单击,然后再单击按钮)。如何修复此问题,以便即使表单未被激活,我也可以直接单击按钮?
编辑:我觉得这应该是可行的,因为它在像SQL Server Profiler和Visual Studio这样的程序中有效(尽管它们没有使用WinForms,但这表明这不是操作系统问题)。

似乎是个好主意。耐心等待答案。 - user2509901
1
我认为这些是最好的答案:https://stackoverflow.com/a/4967537/767664 和 https://dev59.com/1nRB5IYBdhLWcg3w6LR2#1892990。 - Pedro77
2个回答

2
尝试像这样做:
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo);

private const int MOUSEEVENTF_LEFTDOWN = 0x02;
private const int MOUSEEVENTF_LEFTUP = 0x04;
private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
private const int MOUSEEVENTF_RIGHTUP = 0x10;

private const int WM_PARENTNOTIFY = 0x210;
private const int WM_LBUTTONDOWN = 0x201;

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_PARENTNOTIFY)
    {
        if (m.WParam.ToInt32() == WM_LBUTTONDOWN && ActiveForm != this)
        {
            Point p = PointToClient(Cursor.Position);
            if (GetChildAtPoint(p) is ToolStrip)
                mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, (uint)p.X, (uint)p.Y, 0, 0);
        }
    }
    base.WndProc(ref m);
}

编辑:现在适用于ToolStrip


我更新了我的示例,现在它适用于ToolStrip并跳过其他控件的多余点击。 - Dmitry
1
我发现类似Rick Brewster的解决方案很有效,只需确保设置myToolStrip.ClickThrough = true - SharpC

0
这里有一种替代方法。您可以使用表单的Activated事件,然后检查鼠标是否悬停在工具栏按钮上,如果是,则调用PerformClick()
private void Form1_Activated(object sender, EventArgs e)
{
    for (int i = 0; i < toolStrip1.Items.Count; i++)
    {
        ToolStripItem c = toolStrip1.Items[i];
        if (new RectangleF(new Point(i * (c.Size.Width - 1) + this.Location.X + 18, this.Location.Y + 32), c.Size).Contains(MousePosition))
            c.PerformClick();
    }
}

(18和32是工具栏容器相对于窗体位置的偏移量)。可能有一种方法可以实际计算X和Y偏移量应该是多少,但这对我有效。希望能帮到你。


这对右键点击无效,因为它有相同的问题。 - user169771

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接