DuiLib中FlashDemo的例子經(jīng)驗(yàn)雜粹1

??????最近用duilib做個(gè)東西,經(jīng)常卡殼 ,而且以前學(xué)的現(xiàn)在又忘?,F(xiàn)在覺得應(yīng)該好好做筆記,以前老是覺得博客是很鄭重的東西,寫的時(shí)候特別注意,導(dǎo)致很久才能寫上一篇?,F(xiàn)在決定放隨意點(diǎn),把零碎都記下來,以督促自己學(xué)習(xí),既然不能像大神那樣寫多數(shù)量又高質(zhì)量的博客以服務(wù)于大眾,就要做到能寫高數(shù)量的博客,至少能服務(wù)于自己。數(shù)量是最重要的,在這個(gè)“成功細(xì)中取,富貴快中求”的年代。
??????以后簡書的博客就是我的隨筆,沒那么正式。學(xué)過的東西沒做筆記,過后又忘,再來用又要費(fèi)時(shí)間去撿,在這個(gè)什么都追求快速的年代,等于沒學(xué)?。?!以后做項(xiàng)目都得在簡書上做筆記,不然等于沒做?。。?/strong>

????????????????????????????????????FlashDemo經(jīng)驗(yàn)雜粹:

1,在app.cpp中,CFrameWnd類是FlashDem實(shí)例的窗口類,也是唯一的窗口,因?yàn)镈uiLib中其它的窗口(控件)都是模擬出來的,并不是真正意義上的Windows窗口。

2,F(xiàn)lashDemo實(shí)例中,WinMain函數(shù)做的事:

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int nCmdShow)
{
   CPaintManagerUI::SetInstance(hInstance);
   CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath() + _T("skin\\FlashRes"));

    HRESULT Hr = ::CoInitialize(NULL);//使不使用com組件有何不同?我還不清楚,這個(gè)地方回頭要搞懂。
    if( FAILED(Hr) ) return 0;

    CFrameWnd* pFrame = new CFrameWnd();
    if( pFrame == NULL ) return 0;
    pFrame->Create(NULL, NULL, UI_WNDSTYLE_DIALOG, 0);
    pFrame->CenterWindow();
    pFrame->Hide_Bask_Bar();

    pFrame->ShowWindow(true);
    CPaintManagerUI::MessageLoop();
    
    ::CoUninitialize();
    return 0;
}

CPaintManagerUI類:是對于公共的成員變量及成員方法的集成,以減少代碼量,提高代碼重用性,所寫的一個(gè)類
(1)CPaintManagerUI類在WinMain函數(shù)里獲得了本實(shí)例的句柄,獲得了圖片資源路徑。
(2)CPaintManagerUI類的MessageLoop函數(shù)在獲取本線程的消息隊(duì)列里的消息(需轉(zhuǎn)換虛擬鍵時(shí)做轉(zhuǎn)換),并將消息派發(fā)給具體的窗口(實(shí)際是給操作系統(tǒng))。

3,2中(2) 消息派發(fā)給了操作系統(tǒng),操作系統(tǒng)就會根據(jù)消息去回調(diào)該消息對應(yīng)窗口的窗口過程函數(shù)。那么窗口過程函數(shù)在哪里定義呢?

image.png

??????跟蹤代碼可得, pFrame->Create(NULL, NULL, UI_WNDSTYLE_DIALOG, 0);函數(shù)把生產(chǎn)一個(gè)Windows窗口的整個(gè)過程都做了個(gè)遍。從設(shè)計(jì)窗口,注冊窗口,到創(chuàng)建窗口(這個(gè)過程重點(diǎn)推薦 “孫鑫“ 老師講MFC的視頻,講得非常完善)都包括了。

??????在設(shè)計(jì)窗口時(shí),寫入了窗口過程函數(shù),在CFrameWnd的基類CWindowWnd中,是函數(shù)__WndProc。

4,CenterWindow函數(shù)負(fù)責(zé)窗口在屏幕的顯示位置,Hide_Bask_Bar函數(shù)是我自己寫的隱藏任務(wù)欄的函數(shù),沒什么好說的。

5,重點(diǎn)看窗口過程函數(shù)CWindowWnd::__WndProc:

image.png

??????其中有 if( uMsg == WM_NCDESTROY && pThis != NULL ) 這句話的那條執(zhí)行路徑我們可以暫時(shí)不必看,表示窗口銷毀時(shí)要去做啥事。

??????有if( uMsg == WM_NCCREATE )這句話的那條執(zhí)行路徑則表示在窗口響應(yīng)WM_CREATE消息之前應(yīng)該做的事,MDSN上清楚的說明WM_NCCREATE在WM_CREATE之前響應(yīng),暫時(shí)也不必管它。

  if( pThis != NULL ) {
        return pThis->HandleMessage(uMsg, wParam, lParam);
    } 
    else {
        return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
    }

這句話則是理解的關(guān)鍵,表明消息通過HandleMessage處理了。

6,可以看到在CWindowWnd類中,HandleMessage是一個(gè)虛函數(shù),那么這個(gè)地方調(diào)用的就是CFrameWnd的HandleMessage了,來看CFrameWnd的HandleMessage函數(shù):

image.png

可見這里具體處理了各個(gè)消息。

7,現(xiàn)在我有一個(gè)疑問,既然CFrameWnd::HandleMessage處理了消息,那么 CFrameWnd::Notify函數(shù)又是做什么用的呢?看代碼:

image.png

可以看到由if( msg.sType == _T("click") )這句話的進(jìn)入的那個(gè)條件,似乎是響應(yīng)關(guān)閉按鈕。但是關(guān)閉不是可以由LRESULT CFrameWnd::OnLbuttonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)或者OnLbuttonUp來控制嗎(MFC里的學(xué)的是)?為什么還要進(jìn)入Notify函數(shù)?他們之前是啥關(guān)系?

在這三個(gè)消息前設(shè)置三個(gè)斷點(diǎn),然后點(diǎn)擊對話框的關(guān)閉按鈕,發(fā)現(xiàn)執(zhí)行的順序依次是:OnLbuttonDown -> OnLbuttonUp->Notify,在Notify處命中斷點(diǎn)的堆棧是:

image.png

可以看到函數(shù)棧底還是由CFrameWnd::HandleMessage(unsigned int uMsg, unsigned int wParam, long lParam) 函數(shù)開始的,當(dāng)產(chǎn)生WM_LBUTTONDOWN消息時(shí),先將光標(biāo)點(diǎn)擊的位置記錄在對象CPaintManagerUI m_pm的成員變量POINT m_ptLastMousePos中,再根據(jù)點(diǎn)pt來FindControl,得出具體是哪個(gè)控件起的作用。按F11進(jìn)入函數(shù)里面,再看FindControl的調(diào)用堆棧:
image.png

調(diào)用m_pRoot->FindControl進(jìn)入的是CContainerUI::FindControl,而根據(jù)8(原諒我敘述水平有先,在8中才介紹m_pRoot,在這里請先看一下8)中m_pRoot是 CControlUI類型的,而CContainerUI是CControlUI的派生類,可知m_pRoot在實(shí)際生成的時(shí)候,實(shí)際上是指向的是一個(gè)CContainerUI類型對象的。即讀取xml文件的函數(shù)CDialogBuilder::Create里,實(shí)際產(chǎn)生的是一個(gè)容器類型CContainerUI的對象。


8,CFrameWnd::OnCreate(unsigned int uMsg, unsigned int wParam, long lParam, int & bHandled) 函數(shù)會讀取ui.xml文件,解析并生成 CControlUI* pRoot,可以推測到pRoot應(yīng)該是一個(gè)樹狀結(jié)構(gòu)的,因?yàn)閤ml文件里各控件的描述是樹狀的。在調(diào)用 m_pm.AttachDialog函數(shù)的時(shí)候,我們可以看到,最終對xml文件的解析結(jié)果返回的對象,是賦給了CPaintManagerUI m_pm里的成員m_pRoot。

9,再來看CContainerUI::FindControl的代碼:
image.png

看見pResult那個(gè)變量了嗎?可以清晰看到是具體的找到某個(gè)控件然后返回的,而眾所周知,DuiLib中控件都是根據(jù)xml文件的描述虛擬出來的,所以這里可以找出的控件應(yīng)該和xml里是一 一對應(yīng)的。

10,現(xiàn)在回到7中Notify函數(shù)是做什么用的問題上,CPaintManagerUI的成員變量m_pEventClick被賦值為當(dāng)前光標(biāo)選中的控件,m_pEventClick變量和點(diǎn)信息,光標(biāo)的參數(shù)等封裝到一個(gè)TEventUI結(jié)構(gòu)體中,最后都直接調(diào)用m_pEventClick的event信息傳達(dá)下去:


image.png

在堆棧的最后,還是通過CPaintManagerUI送達(dá)給了CFrameWnd的Notify函數(shù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Windows 常用消息大全 表A-1 Windows消息分布 消息范圍說 明 0 ~ WM_USER – 1系統(tǒng)...
    北風(fēng)知我意閱讀 2,243評論 0 0
  • 1.面向?qū)ο蟮某绦蛟O(shè)計(jì)思想是什么? 答:把數(shù)據(jù)結(jié)構(gòu)和對數(shù)據(jù)結(jié)構(gòu)進(jìn)行操作的方法封裝形成一個(gè)個(gè)的對象。 2.什么是類?...
    少帥yangjie閱讀 5,124評論 0 14
  • Windows 常用消息及含義 消息范圍 說明0 ~ WM_USER – 1 系統(tǒng)消息WM...
    MagicalGuy閱讀 919評論 0 0
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,650評論 1 32
  • Windows 95中文輸入法編輯器(IME) 微軟 翻譯:TBsoft Software Studio ...
    returntrue閱讀 2,881評論 0 3

友情鏈接更多精彩內(nèi)容