2014-02-28 105 views
7

我有一个包含按钮的工具栏的窗体应用程序。令人沮丧的是,当表单没有被聚焦时,我必须点击任意按钮两次才能触发它。第一次点击似乎激活了表单,然后再次点击按钮(或者,我可以单击表单上的任意位置,然后单击该按钮一次)。我如何解决这个问题,即使表单没有被激活,我也可以直接点击按钮?编辑:我觉得这应该是可行的,因为它在像SQL Server Profiler和Visual Studio(不是说这些使用WinForms,但它会提示它不是操作系统问题)的程序中工作。如何在不点击表单的情况下立即点击ToolStrip按钮?

+0

似乎是个好主意。耐心等待答案 – 2014-02-28 19:16:54

+0

我认为这些是最好的答案:https://stackoverflow.com/a/4967537/767664和https://stackoverflow.com/a/1892990/767664 – Pedro77

回答

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

编辑: Works为ToolStrip现在。

+0

我已更新我的示例。现在它适用于'ToolStrip'并跳过其他控件的过度点击。 – Dmitry

0

这是另一种方法来做到这一点。您可以使用Form's 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是来自表单位置的tooltripcontainer偏移量)。实际上可能有一种方法可以计算X和Y偏移应该是什么,但这对我有用。 HTH

+0

这不适用于右键单击,它具有相同的问题。 – user169771

相关问题