Here is a brief summary of the code I use for this in the Zeus editor :
Step 1: Define a pair of message structures to hold Windows message data:
typedef struct
{
MSG msg;
LRESULT lResult;
} xMessage;
struct xWM_COMMAND
{
HWND hwnd;
UINT Msg;
WORD ItemID;
WORD NotifyCode;
HWND Ctl;
LRESULT lResult;
};
//-- unpack a message buffer
Step 2: Define the base window class using several special methods:
class xWindow
{
protected:
static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg,
WPARAM wParam,
LPARAM lParam);
void dispatch(HWND hwnd, UINT uMessageID, WPARAM wParam,
LPARAM lParam, LRESULT &Result);
virtual void dispatchToCmdMap(xMessage *pMessage);
virtual void dispatchToMsgMap(xMessage *pMessage);
};
Step 3: Define several macros for sending Windows messages:
protected: \
virtual void dispatchToMsgMap(xMessage *msg)\
{ \
if (msg->msg.message == WM_NULL) \
{ \
return; \
}
else if (msg->msg.message == wm_msg) \
{ \
this->meth(msg); \
return; \
}
else if (msg->msg.message == WM_COMMAND) \
{ \
this->dispatchToCmdMap(msg); \
return; \
} \
else if (msg->msg.message == WM_NOTIFY) \
{ \
this->dispatchToNotifyMap(msg); \
return; \
} \
\
base::dispatchToMsgMap(msg); \
};
virtual void dispatchToCmdMap(xMessage *msg)\
{ \
MSG_UNPACK(Cmd, WM_COMMAND, msg); \
\
if (Cmd->ItemID == 0) \
{ \
\
}
else if (Cmd->ItemID == cmd_id) \
{ \
this->meth(Cmd->ItemID); \
}
else \
{ \
base::dispatchToCmdMap(msg); \
} \
};
Step 4: Define the dispatcher method:
void xWindow::dispatch(HWND, UINT uMessageID, WPARAM wParam,
LPARAM lParam, LRESULT &Result)
{
xMessage message;
message.msg.message = uMessageID;
message.msg.wParam = wParam;
message.msg.lParam = lParam;
message.lResult = 0;
this->dispatchToMsgMap(&message);
}
5: ( : , ):
LRESULT CALLBACK xWindow::wndProc(HWND hwnd, UINT msg,
WPARAM wParam,
LPARAM lParam)
{
LRESULT lResult = 0;
if (msg == WM_NCCREATE)
{
CREATESTRUCT *pCreateData = (CREATESTRUCT*)lParam;
xWindow *pWindow = (xWindow)pCreateData->lpCreateParams;
if (pWindow)
{
SetWindowLong(hwnd, pWindow);
pWindow->dispatch(hwnd, msg, wParam, lParam, lResult);
}
else
{
lResult = DefWindowProc(hwnd, msg, wParam, lParam);
}
}
else if (hwnd)
{
xWindow *pWindow = (xWindow *)GetWindowLong(hwnd);
if (pWindow)
{
pWindow->dispatch(hwnd, msg, wParam, lParam, lResult);
}
else
{
lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
}
}
return lResult;
}
, , , :
class MyWindow : public xWindow
{
protected:
virtual void onAdd(int);
virtual void onDelete(int);
virtual void onClose(xMessage *pMessage);
virtual void onSize(xMessage *pMessage);
public:
MyWindow();
virtual ~MyWindow();
BEGIN_MSG_MAP
CMD_HANDLER(onAdd , IDPB_ADD )
CMD_HANDLER(onDelete, IDPB_DELETE)
MSG_HANDLER(onClose , WM_CLOSE)
MSG_HANDLER(onSize , WM_SIZE )
END_MSG_MAP(xWindow)
};
: .
, , , , wndProc xWindow - , Win32 Window, RegisterClassEx Win32.
, wndProc, , , , Windows .
, , Windows , dispatchToMsgMap.
MyWindow :
BEGIN_MSG_MAP
//-- command message handlers
CMD_HANDLER(onAdd , IDPB_ADD )
CMD_HANDLER(onDelete, IDPB_DELETE)
//-- other message handling
MSG_HANDLER(onClose , WM_CLOSE)
MSG_HANDLER(onSize , WM_SIZE )
END_MSG_MAP(xWindow)
, . , , dispatchToMsgMap. dispatchToMsgMap, .
, Windows , Zeus Windows.