1.VC6使用記得Project Settings -> C/C++ -> Preprocessor definitions添加_USRDLL,UILIB_EXPORTS。
2.mfc中建立duilib視窗退出時整個程式退出了,是因為duilib視窗退出時使用了PostQuitMessage(0),使得整個程式退出,換成Close(); 但是不知道什麼原因有的duilib視窗先退出了,mfc視窗出非法訪問錯誤也退出了,有的duilib視窗就不會。
3.建duilib視窗要PostQuitMessage(0); ::CoInitialize(NULL);
①:架構程式基本流程
-> WinMain(入口函數)
-> CPaintManagerUI::SetResourceInstance (執行個體控制代碼與渲染類關聯)
-> ::CoInitialize
(初始化COM庫, 為載入COM庫提供支援)
-> new C360SafeFrameWnd (建立視窗類別)
-> pFrame->Create (註冊視窗類別與建立視窗)
->RegisterSuperclass (註冊一個超類 即已有一個視窗類別的基上再註冊一個視窗類別)
->RegisterWindowClass(註冊視窗類別)
-> ::CreateWindowEx (建立視窗,此時觸發 WM_CREATE訊息)
-> HandleMessage ( WM_CREATE訊息處理OnCreate)
-> pFrame->CenterWindow (視窗置中顯示)
-> CPaintManagerUI::MessageLoop (處理訊息迴圈)
-> ::CoUninitialize(); (退出程式並釋放COM庫)
②:上面的流程圖是一個基本的WIN32程式架構,相對於 DUILIB庫,此時我們應關心的是視窗上的元素是如何建立起來的。這時我們應關心WM_CREATE的訊息處理函數OnCreate的實現
-> C360SafeFrameWnd:: OnCreate
-> m_pm.Init(m_hWnd) (主視窗類與視窗控制代碼關聯)
-> CControlUI* pRoot = builder.Create(載入XML並動態建立介面無素,與布局介面元素,核心函數單獨分析 注意:CDialogBuilder並不是一個對話方塊類)
-> m_pm.AttachDialog (附加控制項資料到HASH表中)
-> InitControls
(初始化控制項)
->FindControl
->__FindControlFromNameHash
->pManager->m_mNameHash.Insert(把控制項插入到Hash中)
-> m_pm.AddNotifier增加通知處理
③:接下來我們應關心的是XML的載入過程,及XML中的數是如何與視窗類別進行關聯的
-> CDialogBuilder::Create (載入XML檔案)
-> m_xml.LoadFromFile
-> CMarkup::LoadFromFile (也可從資源檔中載入::LoadResource)
-> CMarkup::LoadFromMem(把外部XML資料加入到記憶體)
-> m_xml.GetRoot
(獲得XML 根結點, 開始解析XML資料)
-> "window" (解析根結點window下的三個公用元素屬性)
-> "image" pManager->AddImage(載入裝置無關位元影像並關聯到映像HASH中m_mImageHash.Insert)
-> "font" pManager->AddFont(增加字型)
-> CPaintManagerUI::AddFont(增加字型 並關聯字型數組m_aCustomFonts.Add)
-> "default" (增加預設屬性 如:垂直捲軸和水平捲軸)
-> _Parse
(解析具體的控制項元素 動態產生控制項元素)
-> node.GetName (跳過已經解析過的三個元素"image" "font" "default")
-> _tcscmp (根據元素的名稱 動態產生控制項"Edit" "List" "Text" "Combo" "Label" "Button" "Option" "Slider" "Control" "ActiveX" "Progress" "Container" "TabLayout" "ListHeader"
"TileLayout" "DialogLayout" "VerticalLayout" "ListHeaderItem" "ListTextElement" "HorizontalLayout" "ListLabelElement" "ListExpandElement" "ListContainerElement")
-> pContainer->Add(pControl) (增加控制項)
-> m_items.Add(關聯於控制項數組中)
-> pControl->SetAttribute設定控制項屬性
④上面的工作完成了XML資料的載入,並動態產生了控制項,把控制項載入到了控制項列表,建立了與控制項相關的HASH表。接下來我們應關心的是控制項如何顯示在介面上的。
通過上面的源碼,我們應關心幾個核心類的關聯:
->首先產生主視窗類:C360SafeFrameWnd,
->在主視窗類中放置成變數 CPaintManagerUIm_pm; 與 控制項繪製和訊息處理關聯起來
->CPaintManagerUI::MessageHandler WM_PAINT
->雙緩衝繪圖
-> m_pRoot->DoPaint繪背景圖
-> CControlUI::DoPaint
-> CRenderEngine 真正的繪圖類
-> pPostPaintControl->DoPostPaint在背景圖上繪製控制項
->::BitBlt 把離屏視圖畫到主屏上
⑤當介面元素正常顯示後,接下來我們應關心的是如何處理控制項的事件
-> C360SafeFrameWnd:: HandleMessage (應用需要處理的訊息及處理函數)
-> m_pm.MessageHandler(DUILIB庫幫我們處理的訊息及相關的處理函數)
-> CWindowWnd::HandleMessage(應用程式層和 DUILIB都不處理的訊息交由系統預設處理)