如果你想使用SOUI最好有點WTL基礎,一點點就行了。
SOUI不依賴於WTL,但是SOUI的編碼風格基本和WTL一樣的:SOUI抄襲了WTL的消息處理形式,SOUI的事件處理也是模仿了WTL的消息映射宏。
抄襲WTL的消息處理形式表現在兩個層次:
1、在SWindow及其派生類中處理消息使用WTL基本一致的消息映射宏:
SOUI_MSG_MAP_BEGIN()
MSG_WM_PAINT_EX(OnPaint)
MSG_WM_DESTROY(OnDestroy)
MSG_WM_LBUTTONDOWN(OnLButtonDown)
MSG_WM_MOUSEMOVE(OnMouseMove)
MSG_WM_MOUSELEAVE(OnMouseLeave)
MSG_WM_KEYDOWN(OnKeyDown)
SOUI_MSG_MAP_END()
上面是一個SOUI控件中處理消息映射的映射表,除了SOUI_MSG_MAP_BEGIN/END()和WTL有點區別外,中間的宏基本是一樣的。不同在於SOUI中WM_PAINT消息的參數不是HDC,而且IRenderTarget,所以使用SOUI擴展的映射宏:MSG_WM_PAINT_EX來處理。
2、在CSimpleWnd的派生類(包括SHostWnd, SHostDialog)中直接使用WTL的消息映射宏處理真窗口消息:
//HOST消息及響應函數映射表 BEGIN_MSG_MAP_EX(CMainDlg) MSG_WM_CREATE(OnCreate) MSG_WM_INITDIALOG(OnInitDialog) MSG_WM_DESTROY(OnDestory) MSG_WM_CLOSE(OnClose) MSG_WM_SIZE(OnSize) MSG_WM_COMMAND(OnCommand) MSG_WM_SHOWWINDOW(OnShowWindow) CHAIN_MSG_MAP(SHostWnd) REFLECT_NOTIFICATIONS_EX() END_MSG_MAP()
由於SWindow的消息來自SHostWnd的消息分發,如果在SHostWnd或者SHostDialog的派生類中處理了一個消息,如果沒有將該消息交給SHostWnd繼續處理,可能導致SOUI不能正常工作。
沒有WTL使用經歷的朋友可能想知道如何將一個消息交給SHostWnd繼續處理。當用戶在自己的消息映射表中增加一個消息處理函數,而且是插入在映射表的CHAIN_MSG_MAP(SHostWnd)前(也應該在此之前,否則很可能就收不到消息),默認情況下會自動標志該消息已經被處理了,如此一來就不會繼續交給SHostWnd處理,解決辦法很簡單,在你的消息處理函數中增加一行:
SetMsgHandled(FALSE);
有了這一行,你就不用擔心你的消息處理影響到SHostWnd的處理了。
很多朋友在使用SOUI時處理自己的Timer,結果導致SOUI中的動畫不動了,就是因為這個原因:SOUI內部需要處理自己的定時器消息,但它被最外層的消息映射表截斷了。
基本上會上面這樣一點WTL相關的知識就可以玩轉SOUI了。