4

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.

Naveen
  • 74,600
  • 47
  • 176
  • 233

3 Answers3

0

Take a look at the mediator pattern. It is designed to keep track of stuff like this.

from the gof:

Use the Mediator pattern when

A set of objects communicate in well-defined but complex ways. The resulting interdependencies are unstructured and difficult to understand.

Reusing an object is difficult because it refers to and communicates with many other objects.

A behavior that's distributed between several classes should be customizable without a lot of subclassing.

Ray Tayek
  • 9,841
  • 8
  • 50
  • 90
0

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 Koelle
  • 20,726
  • 23
  • 93
  • 130
  • Downside, however, would be the risk of having a huge business logic method :( – cwap Mar 02 '09 at 16:17
  • 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 Koelle Mar 02 '09 at 22:09
  • Yep. Either way, better to have this code in one place, than scattered throughout the app (for this particular scenario) – David Koelle Mar 06 '09 at 15:57
  • I have done it this way with a project of mine and didn't like it. It was very confusing to call this one function after every GUI action and certain gui actions didn't have to call it. Overall it was very confusing to follow the logic even for me. I think the state method would end up adding many classes but maybe is still the better way to do it. – zar Oct 02 '13 at 19:49
0

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.

Community
  • 1
  • 1
ChrisN
  • 16,635
  • 9
  • 57
  • 81
  • ON_UPDATE_COMMAND_UI is handled only for menus and toolbar which are relatively easy. The main issue is how to enable/disable controls on dialog which ON_UPDATE_COMMAND_UI doesn't handle. – zar Oct 02 '13 at 19:51