DUiLib 源碼分析——第一篇UIManager

DUiLib 源碼分析 ——以UiLib 1.01版爲分析目標
----------------------------------------------------------------------------------
分析約定:
private o------- 私有的成員變量或方法
protect x------- 受保護的成員變量或方法
public  +------- 公開的成員變量或方法
----------------------------------------------------------------------------------

本篇分析一下源文件
UIManager.h/UIManager.cpp

CPaintManagerUI
成員變量
 
窗體句柄
 o---m_hWndPaint                要CPaintManagerUI進行Direct繪圖操作的窗體句柄
 o---m_hwndTooltip              提示窗口句柄
 o---m_hInstance                當前管理的Instance實例
 o---m_hResourceInstance        當前管理的資源DLL Instance實例
 o---m_pStrResourcePath         當前使用的資源路徑
 o---m_pStrResourceZip          當前使用的資源壓縮包文件全稱

    
 
 
 ------------------------------------------------------CPaintManagerUI使用的資源
 繪圖設備
 o---m_hDcPaint                 直接繪製到窗體的DC(爲窗體的整個區域包括費客戶區)
 o---m_hDcOffscreen             內存緩衝區繪圖DC
 o---m_hDcBackground            背景繪製(支持AlphaBackground時使用)
 位圖
 o---m_hbmpOffscreen            m_hDcPaint的後臺作圖畫布
 o---m_hbmpBackground           背景圖片bmp
 
 ------------------------------------------------------CPaintManagerUI用到的信息
 o---m_ToolTip                  提示消息
        typedef struct tagTOOLINFOA {
            UINT cbSize;                //該結構體的大小 sizeof(TOOLINFO)
            UINT uFlags;                //附加標識類信息
            HWND hwnd;                  //消息接受的窗體
            UINT_PTR uId;               //控件ID
            RECT rect;                  //消息產生的區域位置
            HINSTANCE hinst;            //消息接收的實例
            LPSTR lpszText;             //提示消息
            LPARAM lParam;              //IE3.0以上的版本有該屬性
            void *lpReserved;           //NT5.0以上的版本有該屬性 附加信息
        } TOOLINFO
 標識類信息       
 o---m_bShowUpdateRect          是否顯示更新區域
 o---m_bFirstLayout             是否是首個佈局 
 o---m_bUpdateNeeded            是否需要更新界面
 o---m_bFocusNeeded             是否需要焦點
 o---m_bOffscreenPaint          是否需要開雙緩存繪圖
 o---m_bAlphaBackground         窗體背景是否需要支持Alpha通道(如png圖片的半透明效果)
 o---m_bMouseTracking           是否需要支持鼠標追蹤
 o---m_bMouseCapture            是否需要支持鼠標捕獲
 
 控件信息
 o---m_pRoot                    xml根節點解析成的對象,通常爲各種Window
 o---m_pFocus                   處於獲得焦點狀態的控件
 o---m_pEventHover              處於鼠標懸停狀態的控件
 o---m_pEventClick              被鼠標點擊的控件
 o---m_pEventKey                接收鍵盤輸入的控件
 
 位置記錄信息
 o---m_pLastMousePos            鼠標最新的位置
 o---m_szMinWindow              設置窗體可以調整到的最小大小
 o---m_szMaxWindow              窗體可以調整到的最大大小
 o---m_szInitWindowSize         窗體初始化是的大小
 o---m_rcSizeBox                窗體外邊框區域的大小
 o---m_szRoundCorner            窗體四角的圓角弧度
 o---m_rcCaption                窗體標題欄區域大小
 o---m_uTimerID                 當前定時器ID
 
 集合類信息
 o---m_aNotifiers               能夠接收通知的對象集合
 o---m_aTimers                  定時器集合
 o---m_aPreMessage              預處理消息集合
 o---m_aPreMessageFilters       預處理消息過濾器集合
 o---m_aMessageFilters          消息過濾器集合
 o---m_aPostPaintControls       發送繪製請求的控件集合
 o---m_aDelayedCleanup          延遲清理的對象集合
 o---m_aAsyncNotify             異步通知消息集合
 o---m_mNameHash                名稱HashMap
 o---m_mOptionGroup             選項組Map
 
 xml對應資源
 o---m_pParentResourcePM        上級(父類)資源的PaintManagerUI繪圖管理器
 o---m_dwDefaultDisabledColor   默認失效狀態顏色
 o---m_dwDefaultFontColor       默認字體顏色
 o---m_dwDefaultLinkFontColor   默認超鏈接字體顏色
 o---m_dwDefaultLinkHoverFontColor默認超鏈接鼠標懸停狀態的字體顏色
 o---m_dwDefaultSelectedBkColor 默認選中狀態背景色
 o---m_DefaultFontInfo          默認字體信息
        TFontInfo{
            hFont               該字體的句柄
            sFontName           字體名稱
            iSize               字號
            bBold               是否粗體
            bUnderline          是否有下劃線
            bItalic             是否爲斜體
            TEXTMETRIC tm       該字體的TEXTMETRIC信息
        }
 o---m_aCustonFonts             自定義字體資源集合
 o---m_mImageHash               圖片資源HashMap
 o---m_DefaultAttrHash          DefaultAttr資源HashMap

私有方法
            將所有的控件添加到m_mNameHash哈希表中
 o---static CControlUI* CALLBACK __FindControlFromNameHash(CControlUI* pThis, LPVOID pData);
            計算控件數量
 o---static CControlUI* CALLBACK __FindControlFromCount(CControlUI* pThis, LPVOID pData);
            根據點是否在區域中,查詢控件
 o---static CControlUI* CALLBACK __FindControlFromPoint(CControlUI* pThis, LPVOID pData);
            通過Tab信息查詢控件
 o---static CControlUI* CALLBACK __FindControlFromTab(CControlUI* pThis, LPVOID pData);
            從快照中查詢控件
 o---static CControlUI* CALLBACK __FindControlFromShortcut(CControlUI* pThis, LPVOID pData);
            查找需要更新的控件
 o---static CControlUI* CALLBACK __FindControlFromUpdate(CControlUI* pThis, LPVOID pData);
            通過名稱比較查詢控件
 o---static CControlUI* CALLBACK __FindControlFromName(CControlUI* pThis, LPVOID pData);

公開方法
            繪圖管理器的初始化(m_hWndPaint,m_hDcPaint賦值,在預處理消息中加入管理器)
 +---void Init(HWND hWnd);
            當前需要更新界面
 +---void NeedUpdate();
            指定區域失效
 +---void Invalidate(RECT& rcItem);
            獲取繪圖設備DC
 +---HDC GetPaintDC() const;
            獲取繪圖的窗口句柄
 +---HWND GetPaintWindow() const;
            獲取提示窗體句柄
 +---HWND GetTooltipWindow() const;
            獲取當前鼠標的位置
 +---POINT GetMousePos() const;
            獲取客戶區大小
 +---SIZE GetClientSize() const;
            獲取窗體初始化時的大小
 +---SIZE GetInitSize();
            設置窗體初始化大小
 +---void SetInitSize(int cx, int cy);
            獲取窗體的邊框區域大小
 +---RECT& GetSizeBox();
            設置窗體的邊框區域大小
 +---void SetSizeBox(RECT& rcSizeBox);
            獲取標題區域位置
 +---RECT& GetCaptionRect();
            設置標題區域位置
 +---void SetCaptionRect(RECT& rcCaption);
            獲取窗體四角的圓角弧度
 +---SIZE GetRoundCorner() const;
            設置窗體四角的圓角弧度
 +---void SetRoundCorner(int cx, int cy);
            獲取窗體可以調整到的最小大小
 +---SIZE GetMinInfo() const;
            設置窗體可以調整到的最小大小
 +---void SetMinInfo(int cx, int cy);
            獲取窗體可以調整到的最大大小
 +---SIZE GetMaxInfo() const;
            設置窗體可以調整到的最大大小
 +---void SetMaxInfo(int cx, int cy);
            窗體的不透明度(0完全透明-255完全不透明)
 +---void SetTransparent(int nOpacity);
            設置繪圖是否支持透明處理
 +---void SetBackgroundTransparent(bool bTrans);
            是否顯示更新區域
 +---bool IsShowUpdateRect() const;
            設置是否顯示更新
 +---void SetShowUpdateRect(bool show);
            獲取當前管理的實例句柄
 +---static HINSTANCE GetInstance();
            獲得當前運行的實例的路徑
 +---static CStdString GetInstancePath();
            獲得當前的工作路徑
 +---static CStdString GetCurrentPath();
            獲取資源DLL的實例句柄
 +---static HINSTANCE GetResourceDll();
            獲取資源的路徑(以"\"結尾)
 +---static const CStdString& GetResourcePath();
            獲得Zip資源的路徑
 +---static const CStdString& GetResourceZip();
            設置實例句柄
 +---static void SetInstance(HINSTANCE hInst);
            設置當前的工作路徑
 +---static void SetCurrentPath(LPCTSTR pStrPath);
            設置當前的DLL資源的實例句柄
 +---static void SetResourceDll(HINSTANCE hInst);
            設置資源所在文件夾路徑
 +---static void SetResourcePath(LPCTSTR pStrPath);
            設置Zip資源的路徑(包括Zip文件名)
 +---static void SetResourceZip(LPCTSTR pStrZip);
            設置使用上級資源的繪圖管理器
 +---bool UseParentResource(CPaintManagerUI* pm);
            獲得上級資源繪圖管理器
 +---CPaintManagerUI* GetParentResource() const;
            獲取禁用狀態的默認顏色
 +---DWORD GetDefaultDisabledColor() const;
            設置禁用狀態的默認顏色
 +---void SetDefaultDisabledColor(DWORD dwColor);
            獲取字體默認顏色
 +---DWORD GetDefaultFontColor() const;
            設置字體默認顏色
 +---void SetDefaultFontColor(DWORD dwColor);
            設置鏈接文字的默認字體顏色           
 +---DWORD GetDefaultLinkFontColor() const;
            獲取鏈接文字的默認顏色
 +---void SetDefaultLinkFontColor(DWORD dwColor);
            獲取鼠標懸停與超鏈上的默認字體顏色
 +---DWORD GetDefaultLinkHoverFontColor() const;
            獲取鼠標懸停與超鏈上的默認字體顏色
 +---void SetDefaultLinkHoverFontColor(DWORD dwColor);
            獲取選中狀體的默認背景顏色
 +---DWORD GetDefaultSelectedBkColor() const;
            設置選中狀態的默認背景顏色
 +---void SetDefaultSelectedBkColor(DWORD dwColor);
            獲取默認使用的字體信息
 +---TFontInfo* GetDefaultFontInfo();
            設置默認使用的字體信息
 +---void SetDefaultFont(LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic);
            獲取用戶自定義字體的數量(一般對應xml中Font的數量)
 +---DWORD GetCustomFontCount() const;
            向字體數組列表追加字體資源
 +---HFONT AddFont(LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic);
            向字體數組列表中插入字體資源
 +---HFONT AddFontAt(int index, LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic);
            獲取數組中指定下標的字體對象句柄
 +---HFONT GetFont(int index);
            從字體數組中獲取指定配置的字體對象句柄
 +---HFONT GetFont(LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic);
            字體數組集合中是否存在字體對象
 +---bool FindFont(HFONT hFont);
            字體數組集合中是否存在指定配置的字體對象
 +---bool FindFont(LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic);
            獲得字體對象的
 +---int GetFontIndex(HFONT hFont);
            根據指定的配置信息查詢字體索引
 +---int GetFontIndex(LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic);
            從字體數組列表中移除字體對象
 +---bool RemoveFont(HFONT hFont);
            從字體數組列表中移除指定位置的字體信息
 +---bool RemoveFontAt(int index);
            清空字體數組列表
 +---void RemoveAllFonts();
            通過字體數組索引查找字體信息
 +---TFontInfo* GetFontInfo(int index);
            通過字體對象句柄獲取字體信息
 +---TFontInfo* GetFontInfo(HFONT hFont);
            根據圖像路徑查找圖像信息
 +---const TImageInfo* GetImage(LPCTSTR bitmap);
            根據名稱,類型,遮罩色 查詢 圖像信息
 +---const TImageInfo* GetImageEx(LPCTSTR bitmap, LPCTSTR type = NULL, DWORD mask = 0);
            添加圖像
 +---const TImageInfo* AddImage(LPCTSTR bitmap, LPCTSTR type = NULL, DWORD mask = 0);
            添加圖像
 +---const TImageInfo* AddImage(LPCTSTR bitmap, HBITMAP hBitmap, int iWidth, int iHeight, bool bAlpha);
            根據圖像名稱移除圖像
 +---bool RemoveImage(LPCTSTR bitmap);
            移除全部圖像
 +---void RemoveAllImages();
            添加控件的默認配置信息(如button)
 +---void AddDefaultAttributeList(LPCTSTR pStrControlName, LPCTSTR pStrControlAttrList);
            根據控件名稱查詢該類控件的默認配置
 +---LPCTSTR GetDefaultAttributeList(LPCTSTR pStrControlName) const;
            移除指定控件類型名稱的默認配置
 +---bool RemoveDefaultAttributeList(LPCTSTR pStrControlName);
            獲取默認配置信息列表
 +---const CStdStringPtrMap& GetDefaultAttribultes() const;
            清空默認配置信息列表
 +---void RemoveAllDefaultAttributeList();
            將對話框控件附加到當前的管理器中
 +---bool AttachDialog(CControlUI* pControl);
            控件初始化
 +---bool InitControls(CControlUI* pControl, CControlUI* pParent = NULL);
            控件回收
 +---void ReapObjects(CControlUI* pControl);

            添加控件到指定的選項組
 +---bool AddOptionGroup(LPCTSTR pStrGroupName, CControlUI* pControl);
            查詢指定選項組名稱中的全部選項
 +---CStdPtrArray* GetOptionGroup(LPCTSTR pStrGroupName);
            從指定控件中移除指定選項組名稱的選項組
 +---void RemoveOptionGroup(LPCTSTR pStrGroupName, CControlUI* pControl);
            清空全部選項組列表
 +---void RemoveAllOptionGroups();

            獲取焦點狀態的控件
 +---CControlUI* GetFocus() const;
            設置控件爲獲得焦點狀態
 +---void SetFocus(CControlUI* pControl);
            設置控件爲需要繪製焦點
 +---void SetFocusNeeded(CControlUI* pControl);

            設置下一個獲得Tab鍵會獲得焦點的控件,Tab是否繼續往下走
 +---bool SetNextTabControl(bool bForward = true);
            
            爲指定控件以及其子控件設置定時器
 +---bool SetTimer(CControlUI* pControl, UINT nTimerID, UINT uElapse);
            移除指定控件上的指定編號的定時器
 +---bool KillTimer(CControlUI* pControl, UINT nTimerID);
            清空所有的定時器
 +---void RemoveAllTimers();
            
            設置窗體接受鼠標事件
 +---void SetCapture();
            釋放窗體捕獲鼠標事件
 +---void ReleaseCapture();
            判斷窗體是否接受鼠標事件
 +---bool IsCaptured();

            添加控件到通知集合中
 +---bool AddNotifier(INotifyUI* pControl);
            將控件從通知集合中移除
 +---bool RemoveNotifier(INotifyUI* pControl);   
            發送同步/異步通知
 +---void SendNotify(TNotifyUI& Msg, bool bAsync = false);
            構建同步或異步通知併發送
 +---void SendNotify(CControlUI* pControl, LPCTSTR pstrMessage, WPARAM wParam = 0, LPARAM lParam = 0, bool bAsync = false);


            向預處理消息過濾器鏈中添加消息過濾器
 +---bool AddPreMessageFilter(IMessageFilterUI* pFilter);
            從預處理消息過濾器鏈閤中移除指定的消息過濾器
 +---bool RemovePreMessageFilter(IMessageFilterUI* pFilter);

            向消息過濾器鏈中添加消息過濾器
 +---bool AddMessageFilter(IMessageFilterUI* pFilter);
            從消息過濾器鏈中移除消息過濾器
 +---bool RemoveMessageFilter(IMessageFilterUI* pFilter);
            獲取發送需要繪製的控件的數量
 +---int GetPostPaintCount() const;
            向繪製請求集合中添加要繪製的控件
 +---bool AddPostPaint(CControlUI* pControl);
            從繪製請求集合中移除指定的控件
 +---bool RemovePostPaint(CControlUI* pControl);
            將繪製請求控件插入到繪製請求集合的指定位置
 +---bool SetPostPaintIndex(CControlUI* pControl, int iIndex);
            向延遲清理集合中添加需要延遲清理的對象
 +---void AddDelayedCleanup(CControlUI* pControl);
            獲取根節點控件
 +---CControlUI* GetRoot() const;
            從根節點開始查找指定點所在的控件
 +---CControlUI* FindControl(POINT pt) const;
            從指定節點開始查找指定點所在的控件
 +---CControlUI* FindControl(CControlUI* pParent, POINT pt) const;
            從根節點開始,查找指定名稱的控件
 +---CControlUI* FindControl(LPCTSTR pstrName);
            從指定節點開始查找指定名稱的控件
 +---CControlUI* FindControl(CControlUI* pParent, LPCTSTR pstrName);

            消息循環,非遊戲框架消息泵,無法利用無消息的空閒時間            
 +---static void MessageLoop();
            消息翻譯,在Win32原有的消息轉換基礎上,將需要自己處理的消息轉發給消息預處理器
 +---static bool TranslateMessage(const LPMSG pMsg);
            消息預處理器
            1.消息預處理過濾(消息預處理過濾器集合對消息進行過濾處理)
            2.檢查是否按下Tab鍵,設置下一個獲得焦點的控件
            3.處理Alt+Shortcut Key按下後的控件獲得焦點和激活的設置
            4.檢查是否有系統鍵消息,有則發送獲得焦點的控件的事件
 +---bool PreMessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lRes);
 
 
----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
消息處理器(核心處理器)
1.消息過濾
2.檢查Custom消息並處理
3.檢查是否有WM_CLOSE消息並處理
4.處理WM_ERASEBKGND(不允許進行背景擦除,防止閃爍)
5.繪製處理(核心)
    5.1做延遲繪圖判斷,當前是否有 窗體大小調整的操作,或者是否需要初始化窗體
    5.2設置焦點控件
    5.3如果開啓雙緩存繪圖,採用雙緩存方式繪圖,否則採用標準繪圖方式繪圖
    5.4               
6.處理客戶區的繪製WM_PRINTCLIENT
7.接到WM_GETMINMAXINFO消息後向系統提交該窗體可調整大小的最小和最大限制
8.窗體大小改變時,向焦點控件發送改變大小消息並設置窗體需要更新
9.處理定時器消息,向定時器集合中廣播定時消息
10.處理鼠標懸停
    10.1向鼠標懸停的控件發送鼠標懸停消息
    10.2如果當前控件有提示消息,創建消息提示窗體
11.處理鼠標離開事件,關閉消息提示框,發送鼠標離開消息,取消鼠標的追蹤
12.鼠標移動時,開始追蹤鼠標
    12.1處理鼠標移動時,鼠標在控件上進入,移動,懸停和離開的消息
13.處理鼠標左鍵按下的消息設定活動的焦點的控件
14.鼠標雙擊事件處理,向需要接收鼠標雙擊事件的控件發送雙擊事件
15.鼠標左鍵擡起時,向上次接收到點擊消息的控件發送鼠標左鍵擡起的消息
16.鼠標右鍵按下時,向需要接收鼠標右鍵按下的控件發送右鍵按下消息
17.鼠標右鍵快捷菜單消息,將該消息通知給上次點擊過的按鈕
18.滾輪消息時,象鼠標所在的控件發送滾輪消息
19.WM_CHAR 消息時,向獲得焦點的控件發送該消息
20.鍵盤按下時,向焦點控件發送該鍵盤消息,並設定焦點控件爲鍵盤消息控件
21.鍵盤按鍵擡起時,向事鍵盤消息控件發送該事件
22.設定鼠標光標消息時,獲得光標所在控件接收該消息
23.通知消息到來時,加OCM_BASE後發送通知消息
24.命令消息到來,加OCM_BASE後發送消息
25.WM_CTLCOLOREDIT,STATIC消息到來後,加OCM_BASE後發送消息
 +---bool MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lRes);
 
                                    ——colin3dmax 分析於2011-6-15 22:00

在此我再次感謝colin3dmax的無私分享還有爲duilib開源做出貢獻的人哈

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章