До чего же мне нравится идея "cracked handlers" в WTL, но вот реализация...
Идея cracked handlers такова. Обработчики оконных событий в WTL выглядят так:
class SomeWindowImpl
{
BEGIN_MSG_MAP(SomeWindowImpl)
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
MESSAGE_HANDLER(WM_SIZE, OnSize)
END_MSG_MAP()
LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
};
Потом приходится копаться в MSDN и выковыривать из wParam и lParam нужную информацию. Идея cracked handlers проста - сделать все по-человечески:
class SomeWindowImpl
{
BEGIN_MSG_MAP(SomeWindowImpl)
MSG_WM_LBUTTONDOWN(OnLButtonDown)
MSG_WM_SIZE(OnSize)
END_MSG_MAP()
LRESULT OnLButtonDown(UINT nFlags, CPoint Point);
LRESULT OnSize(UINT nType, CSize Size);
};
Все бы было нормально, если не видеть как реализованы все эти MSG_WM_xxx:
#define MSG_WM_LBUTTONDOWN(func) \
if (uMsg == WM_LBUTTONDOWN) \
{ \
SetMsgHandled(TRUE); \
func((UINT)wParam, CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
lResult = 0; \
if(IsMsgHandled()) \
return TRUE; \
}
#define MSG_WM_SIZE(func) \
if (uMsg == WM_SIZE) \
{ \
SetMsgHandled(TRUE); \
func((UINT)wParam, CSize(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \
lResult = 0; \
if(IsMsgHandled()) \
return TRUE; \
}
Посмотришь на них - и начинаешь задумываться: что произойдет быстрее - появятся мониторы с 33 тыс.точек по горизонтали (или вертикали), или люди перестанут пользоваться программой, которую ты пишешь. Я, конечно, про GET_x_LPARAM - они работают до поры до времени, позже все же придется воспользоваться GetClientRect() и GetMessagePos(). Или не придется?... ;) Попробуй угадай.
А иногда там встречаются менее заметные вещи, типа использования unsigned вместо signed. Сразу и не догадаешься. Вобщем, в результате:
// #include <atlcrack.h>