1

I have a dockable window in a custom ArcMap extension. The dockable window has a regular windows forms ToolStrip control in it with ToolStripButtons on the ToolStrip. When the parent dockable window is not Active and I try to click a button on the toolstrip within the dockable window, I have to click it twice - once to set the focus and then again to fire the click event. I only want to click the button once even if the dockable window is not currently active.

3

I found a work around to this by using Rick Brewster's suggestions.

First, I modified Rick's class by adding a constructor public ToolStripEx() : base() { }

Then in my dockable window's designer class "MyClass.Designer.cs" I changed the toolstrip's declared type from System.Windows.Forms.ToolStrip to ToolStripEx.

Next, in the InitializeComponent() method of the same designer class, I changed the initialization type for the toolstrip the same way from this.MyToolStrip = new System.Windows.Forms.ToolStrip() to this.MyToolStrip = new ToolStripEx().

Finally, I set this.MyToolStrip.ClickThrough = true; in the default property assignment section in the same designer class.

Now the buttons on the toolstrip fire the onClick event everytime - even when the dockable window is not active!

UPDATE:

Rick's original ToolStripEx class is below incase the link above ever breaks:

/// <summary>
/// This class adds on to the functionality provided in System.Windows.Forms.ToolStrip.
/// </summary>
public class ToolStripEx
: ToolStrip
{
private bool clickThrough = false;

/// <summary>
/// Gets or sets whether the ToolStripEx honors item clicks when its containing form does
/// not have input focus.
/// </summary>
/// <remarks>
/// Default value is false, which is the same behavior provided by the base ToolStrip class.
/// </remarks>
public bool ClickThrough
{
    get
    {
        return this.clickThrough;
    }

    set
    {
        this.clickThrough = value;
    }
}

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);

    if (this.clickThrough &&
        m.Msg == NativeConstants.WM_MOUSEACTIVATE &&
        m.Result == (IntPtr)NativeConstants.MA_ACTIVATEANDEAT)
    {
        m.Result = (IntPtr)NativeConstants.MA_ACTIVATE;
    }
}
}

internal sealed class NativeConstants
{
private NativeConstants()
{
}

internal const uint WM_MOUSEACTIVATE = 0x21;
internal const uint MA_ACTIVATE = 1;
internal const uint MA_ACTIVATEANDEAT = 2;
internal const uint MA_NOACTIVATE = 3;
internal const uint MA_NOACTIVATEANDEAT = 4;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.