views:

186

answers:

2

I have application running on Windows written using MFC. The enable/disable state of the menu items depends upon a lot of conditions. For example, I have to enable the menu item if condition A is satisfied OR if condition B is satisfied, but should be disabled if both A AND B are TRUE at the same time. How do we model this in code ? I think I should use some sort of state machine, but my state machine seems to contain too many states. What is the general way of handling such problems? Please note that the above was just an example, there will be many more conditions like this. Also, the option of keeping the menu enabled always and displaying an error message when user presses it doesn't exist as I have to disable the menu.

Just to clarify, I am not looking for how to disable the menu items in MFC, what I am looking for what is the best way to decide whether a menu item is to be enabled/disabled when there are many interdependent states are involved.

+1  A: 

Try writing a method, updateUIStatus(), that gets called after every UI action. That method would set the enabled or disabled state of the menu item (and any other UI component) based on your conditions.

The nice thing about having a single method to do all UI state updates is that you centralize all of this logic in one place, instead of having multiple calls to, say, if (condition A && condition B) menu.setEnabled(true);

David
Downside, however, would be the risk of having a huge business logic method :(
cwap
I know, I thought of that, too. But since it's on the UI side, it's not really business logic. If there are business logic decisions in there, then calls should be made to other classes (i.e., call "isOptionValid()" in some business logic class)
David
Point taken - Not really business logic, more like "ui logic"..
cwap
Yep. Either way, better to have this code in one place, than scattered throughout the app (for this particular scenario)
David
+1  A: 

MFC has a built-in mechanism for enabling and disabling menu items, in the form of command routing and the ON_UPDATE_COMMAND_UI macro. For more details, see How to: Update User-Interface Objects and the CCmdUI class documentation in MSDN.

You don't necessarily need a state machine. For each menu command, decide where the command should be handled, e.g., in your document, view, or main frame class, then implement an OnUpdate handler and add an ON_UPDATE_COMMAND_UI message map entry for the appropriate class.

As an example, have look at the answer I gave to this question.

ChrisN