using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace Custom.UserControls { /// /// Most controls, even when on an inactive window, respond /// to clicks by activating and then processing the click. /// /// The ToolStrip and MenuStrip don't activate first, so the click /// event won't even be caught. /// public partial class ClickThroughToolStrip : ToolStrip { private bool clickThroughEnabled; /// /// Enable click through, or not. /// public bool ClickThroughEnabled { get { return clickThroughEnabled; } set { clickThroughEnabled = value; } } public ClickThroughToolStrip() : base() { /// Enable click-through behavior by default clickThroughEnabled = true; } protected override void WndProc(ref Message m) { /// Allow the ToolStrip to process as usual base.WndProc(ref m); /// If click-through is enabled we may have a need to /// activate this window if (clickThroughEnabled) { /// Use Winspector to spy on the ToolStrip. When the /// window isn't selected and you click a ToolStrip button, the /// WM_MOUSEACTIVATE message is fired with an activate code of /// MA_ACTIVATEANDEAT (we'd prefer just MA_ACTIVATE) if (m.Msg == Messages.WM_MOUSEACTIVATE && m.Result == Messages.MA_ACTIVATEANDEAT) m.Result = Messages.MA_ACTIVATE; } } } /// /// The Windows messages this control needs /// internal sealed class Messages { public static int WM_MOUSEACTIVATE = 0x21; public static IntPtr MA_ACTIVATEANDEAT = (IntPtr)2; public static IntPtr MA_ACTIVATE = (IntPtr)1; } }