前言
帶界面軟件可以分兩部分:界面顯示和消息處理。前面介紹了界面解析繪制和消息處理,而繪制管理器類(CPaintManagerUI)兩部分都管理:處理了大部分的繪制工作、控件消息分發處理。
示例
class CDuilibWnd : public CWindowWnd, public INotifyUI
{
public:
// 重寫CWindowWnd::HandleMessage處理消息
virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
{
if (uMsg == WM_CREATE)
{
// 初始化繪制管理器,m_hWnd句柄在一個消息WM_NCCREATE中賦值
m_PaintManager.Init(m_hWnd);
// 使用XML布局文件生成界面
CDialogBuilder builder;
CControlUI* pRoot = builder.Create(_T("duilib.xml"), 0, NULL, &m_PaintManager);
ASSERT(pRoot && "Failed to parse XML");
// 添加CControlUI對象,用於管理界面
m_PaintManager.AttachDialog(pRoot);
// 添加INotifyUI對象,用於處理消息
m_PaintManager.AddNotifier(this);
}
// CPaintManagerUI處理消息
if (m_PaintManager.MessageHandler(uMsg, wParam, lParam, lRes)) return lRes;
// CWindowWnd兜底處理消息
return __super::HandleMessage(uMsg, wParam, lParam);
}
protected:
CPaintManagerUI m_PaintManager; // 繪制管理器:負責繪制界面和管理消息
}
接管窗口
Init:初始化所維護的窗口句柄,參數hWnd即為繪制管理的窗口句柄,並維護該窗口上下文,此外將該本管理器UI對象加入內部預處理器,以處理過濾全局的消息,該函數在窗口創建時被調用;
GetPaintDC:獲取窗口上下文繪制DC;
GetPaintWindow:獲取繪制窗口句柄;
GetTooltipWindow:獲取提示信息窗口句柄;
管理界面
AttachDialog:將控件附加到本類繪制管理UI對象,內部調用InitControls初始化控件樹
GetRoot:獲取控件樹根對象;
FindControl:查找指定位置的控件對象;
FindControl:重載版本,獲取指定名稱的控件對象;
FindSubControlByPoint:獲取某控件下某位置的子控件對象;
FindSubControlByName:獲取某控件下指定名稱的控件對象;
FindSubControlByClass:獲取某控件下指定類名的控件對象
監聽消息
AddNotifier:添加消息通告者監聽對象至消息通告集中;
RemoveNotifier:移除指定的消息通告者監聽對象;
AddPreMessageFilter:添加預處理消息過濾器對象至m_aPreMessageFilters過濾器集中;
RemovePreMessageFilter:從m_aPreMessageFilters中移除指定的預處理消息過濾器對象;
AddMessageFilter:添加消息過濾器對象至m_aMessageFilters集中;
RemoveMessageFilter:移除m_aMessageFilters集中的指定消息過濾器對象;
處理消息
MessageLoop:消息循環泵,內部維護一個消息循環,先執行CPaintManagerUI類的TranslateMessage消息翻譯(預先翻譯以及預處理消息),再交給TranslateMessage翻譯,此后DispatchMessage分發消息;
MessageHandler:消息處理函數,內部負責處理各消息以及分發通告消息;
PreMessageHandler:預處理消息處理函數,內部預處理消息以及消息轉化;
小結
繪制管理器類(CPaintManagerUI)的功能主要是管理:界面顯示和消息處理。AttachDialog用來管理界面,AddNotifier用來處理消息。
Duilib技術交流群:799142530
源碼地址:https://github.com/KongKong20/DuilibTutor