我有一个带有包含按钮的工具条的Windows窗体应用程序。令人沮丧的是,我必须在任何按钮上单击两次才能在表单没有聚焦时触发它。第一次单击似乎激活表单,然后第二次单击单击按钮(或者,我可以单击表单上的任意位置,然后单击按钮一次)。如何解决这个问题,即使表单未激活,我也可以直接点击按钮?
编辑:我认为这应该是可行的,因为它适用于SQL Server Profiler和Visual Studio等程序(不是这些程序使用WinForms,但它表明它不是操作系统问题)。答案 0 :(得分:1)
尝试这样的事情:
[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
。
答案 1 :(得分:0)
这是另一种方法。您可以使用Form的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是来自表单位置的toolstripcontainer的偏移量)。可能有一种方法可以实际考虑X和Y偏移应该是什么,但这对我有用。 HTH