天天看點

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