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