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.
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; } }