Идея cracked handlers такова. Обработчики оконных событий в WTL выглядят так:
class SomeWindowImplПотом приходится копаться в MSDN и выковыривать из wParam и lParam нужную информацию. Идея cracked handlers проста - сделать все по-человечески:
{
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);
};
class SomeWindowImplВсе бы было нормально, если не видеть как реализованы все эти MSG_WM_xxx:
{
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);
};
#define MSG_WM_LBUTTONDOWN(func) \Посмотришь на них - и начинаешь задумываться: что произойдет быстрее - появятся мониторы с 33 тыс.точек по горизонтали (или вертикали), или люди перестанут пользоваться программой, которую ты пишешь. Я, конечно, про GET_x_LPARAM - они работают до поры до времени, позже все же придется воспользоваться GetClientRect() и GetMessagePos(). Или не придется?... ;) Попробуй угадай.
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; \
}
А иногда там встречаются менее заметные вещи, типа использования unsigned вместо signed. Сразу и не догадаешься. Вобщем, в результате:
// #include <atlcrack.h>
3 комментария:
А почему бы вместо
// #include <atlcrack.h>
не предложить более правильное решение? Многие пользователи WTL спасибо скажут...
Немного придерусь к терминологии. Такой подход когда-то назывался window message crackers (см. windowsx.h). Действительно удобное, но несёт потенциальную опасность, как и всё связанное с использованием макросов. Однако никто не мешает вам переписать макросы, используя static_cast
Термин взял из комментария в atlcrack.h:
// Message map macro for cracked handlers
Отправить комментарий