3

I recently fixed worked around a very annoying issue in my code base.

I have a ParentMenuItemBase abstract class from which I derive classes that essentially wrap a CommandBarPopup control, and create the child CommandBarButton objects and wire up their Click event to execute an ICommand.

Say I had a RefactorRenameCommand hooked up to 5 completely independent CommandBarButton objects, under 5 completely unrelated CommandBarPopup controls.

When I clicked the CommandBarButton, the child_Click handler would then run 5 times - and the Ctrl parameter would have the same hash code for all 5 "clicks".

Then if I clicked the same button again, the handler would again run 5 times, and again the Ctrl parameter would have the same hash code for all 5 "clicks", ...but the hash code would be different from what it was the first time around - and if I clicked again, I'd get a new hash code for that parameter.

I obtained the desired behavior by storing the last hash code for that Ctrl parameter in a private static field, and only executing the handler if the hash code for Ctrl was different - in other words, I made it work by building on top of an observed behavior that I didn't completely understand, and it feels dirty and it bothers me beyond words. Here's the hack in question, including the actual in-code comments:

// note: HAAAAACK!!!
private static int _lastHashCode;

private void child_Click(CommandBarButton Ctrl, ref bool CancelDefault)
{
    var item = _items.Select(kvp => kvp.Key).SingleOrDefault(menu => menu.Key == Ctrl.Tag) as ICommandMenuItem;
    if (item == null || Ctrl.GetHashCode() == _lastHashCode)
    {
        return;
    }

    // without this hack, handler runs once for each menu item that's hooked up to the command.
    // hash code is different on every frakkin' click. go figure. I've had it, this is the fix.
    _lastHashCode = Ctrl.GetHashCode();

    Debug.WriteLine("({0}) Executing click handler for menu item '{1}', hash code {2}", GetHashCode(), Ctrl.Caption, Ctrl.GetHashCode());
    item.Command.Execute(null);
}

That Debug.WriteLine call would output something like this:

(46595510) Executing click handler for menu item '&Rename', hash code 16706408
(16139946) Executing click handler for menu item '&Rename', hash code 16706408
(11041789) Executing click handler for menu item '&Rename', hash code 16706408
(32267243) Executing click handler for menu item '&Rename', hash code 16706408
(21969731) Executing click handler for menu item '&Rename', hash code 16706408

And the next click would produce an identical output, except with a different hash code for the Ctrl parameter.

So, exactly what is this Ctrl parameter? If it's the CommandBarButton COM control that was clicked, then why does its hash code not match that of the CommandBarButton object I created? And why does its hash code change every time the handler runs?

Mathieu Guindon
  • 69,817
  • 8
  • 107
  • 235
  • Well, [the doc](https://msdn.microsoft.com/en-us/library/office/aa170943(v=office.11).aspx) isn't much help. It pretty much says what you'd expect... – RubberDuck Oct 15 '15 at 11:43

0 Answers0