Home page Home page Home page Home page
Pixel Header R1 C1 Pixel
Pixel Header R2 C1 Pixel
Pixel Header R3 C1 Pixel
By Captain C | Wednesday, 15 September 2010 09:30 | 0 Comments
Here at Sprezz Towers we're hard at work on the Big Project: a large Arev to OI conversion using our shiny new promoted event framework (well it ain't that new but it gets more polished each time we use it). Part of this week's programming fun has been implementing Arev Softkeys functionality as a menu that dynamically configures itself based on the active MDI child - we have a promoted event that simply alters a static "placeholder" menu on the fly using a combination of properties such as VISIBLE, ENABLED, TEXT and so on.

Visually all this was working really well, but as I waded into event handling I came across an unexpected problem: No events for the softkey menu items would fire! Hmm...

First of all I decided to check if the MDI frame was actually being told by Windows about the menu click: The trusty Microsoft Spy++ tool soon revealed that the frame was indeed receiving the menu item's WM_COMMAND message, but still nothing was getting to OpenEngine. This was really strange as normally ALL menu items call the RUN_EVENT function to see if there's a MENU event handler to execute - this time there was no action whatsoever.

Next I started turning off the Set_Property calls one by one to see if I could determine if any particular property was responsible for the strange behaviour and I came across an interesting result: As soon as I set the ENABLED property to FALSE$ the menu item lost the ability to execute a MENU event, even if I re-enabled it by setting ENABLED back to TRUE$.

This had me stumped at first until I tested some more and removed the code setting the VISIBLE property: If I didn't use the VISIBLE property then ENABLED worked as advertised. Progress of a sort I guess...

More testing revealed this: If I removed a menu item by setting it's VISIBLE and ENABLED properties to FALSE$, in that order, and then I subsequently set the VISIBLE and ENABLED properties back to TRUE$, again in that order, then the menu item's event handling stopped working. So, the next question was ... Why?

The evidence suggested that the ENABLED property did something different based on whether or not a menu item was hidden. A little more work with Spy++ showed that a hidden disabled menu item still raised a WM_COMMAND message when fired (via an accelerator key combination), but RUN_EVENT wasn't called. However, if the menu item was visible and disabled no WM_COMMAND message was raised. Ergo the menu ENABLED property must trigger a switch inside OpenInsight that turned off hidden menu item event handling.

Thinking about this some more led me to the following conclusions:

  • When a menu item is visible OpenInsight can use the Windows API EnableMenuItem function to disable it - the menu item is "grayed out" and clicking on it produces no WM_COMMAND message.

  • When a menu item is hidden it is actually deleted from its parent menu - Windows knows nothing about it and therefore EnableMenuItem can't be used. However, OpenInsight still keeps the item details in memory so that hidden items can be executed via accelerator keys, so there must be a mechanism to disable this as needed.

Indeed there is, and it's even there on a checkbox I totally ignore when designing menus in the Form Designer:

You can actually turn off menu item event processing by design and it's this flag that the ENABLED property is setting when you use it with a hidden item. The actual OpenInsight bug is that the flag is never set or removed if you use the ENABLED property on a visible item!

In other words, if you disable a hidden item you must re-enable it before you make it visible again if you want it to fire events.

So, armed with this new wisdom it was a simple matter to ensure that the ENABLED and VISIBLE properties were set in a better order, and now event handling works like a charm - another case closed!

Labels: , ,


Post a Comment

Subscribe to Post Comments [Atom]

<< Home

Pixel Footer R1 C1 Pixel