Menu

Using_single_message_response_function

Sometimes, a series of command messages may be related in such a way that it makes more sense to handle them all with a single message-response function than to create a function for each. For example, a Line menu may enable a user to select one of several line thicknesses. It's logical to handle all Line menu commands in a single function whose job it is to set the line width. To perform this trick, you need to use EV_COMMAND_AND_ID macros in your window class's response table.

The Solution

First, create a response table that contains an EV_COMMAND_AND_ID macro for each message you want handled by the single message-response function, using the same function as the macro's second argument:

DEFINE_RESPONSE_TABLE1(TLineWindow, TFrameWindow)
  EV_COMMAND_AND_ID(CM_LINEWIDTH1, CmLineWidth),
  EV_COMMAND_AND_ID(CM_LINEWIDTH2, CmLineWidth),
  EV_COMMAND_AND_ID(CM_LINEWIDTH3, CmLineWidth),
END RESPONSE TABLE;

The EV_COMMAND_AND_ID macro takes exactly the same arguments as the EV_COMMAND macro: the message ID and the name of the function that will handle that message. The difference is that when the program calls the message-response function it sends along the ID of the message that triggered the call. In the message-response function, use this parameter to implement the handler appropriately:

void TLineWindow::CmLineWidth(WPARAM id)
{
  typedef std::map<WPARAM, int> LineWidthMap;
  const LineWidthMap::value_type v[] = 
    {{CM_LINEWIDTH1, 1}, {CM_LINEWIDTH2, 5}, {CM_LINEWIDTH3, 10}};
  static const LineWidthMap m(v, v + COUNTOF(v));
  SetLineWidth(m[idWidth]); // 0 if not in map
}

On the other hand, beware that if your handler ends up looking like the following you should really consider using separate handlers. Don't do manual dispatch.

void TMyWindow::CmCommand(WPARAM messageld)
{
  switch (messageld) {
    case CM_COMMAND1: /* Handle message 1 */
      break;
    case CM_COMMAND2: /* Handle message 2 */
      break;
    case CM_COMMAND3: /* Handle message 3 */
      break;
  }
}

Related

Wiki: Knowledge_Base