第一章 第四小節Duilib的WindowImplBase基類(二)--CWindowWnd

  在duilib中,繪製對象的目標載體是窗口,那就必然有窗口部分的內容需要處理,在WindowImplBase中,封裝在父類CWindowWnd中,如下所示:

class UILIB_API CWindowWnd
    {
    public:
        CWindowWnd();

        HWND GetHWND() const;
        operator HWND() const;//類型轉換函數
        
		//註冊窗口類
        bool RegisterWindowClass();
        bool RegisterSuperclass();

		//創建窗口
        HWND Create(HWND hwndParent, LPCTSTR pstrName, DWORD dwStyle, DWORD dwExStyle, const RECT rc, HMENU hMenu = NULL);
        HWND Create(HWND hwndParent, LPCTSTR pstrName, DWORD dwStyle, DWORD dwExStyle, int x = CW_USEDEFAULT, int y = CW_USEDEFAULT, int cx = CW_USEDEFAULT, int cy = CW_USEDEFAULT, HMENU hMenu = NULL);
        HWND CreateDuiWindow(HWND hwndParent, LPCTSTR pstrWindowName,DWORD dwStyle =0, DWORD dwExStyle =0);
		//保存窗口與對象的映射、修改窗口過程函數和解綁
        HWND Subclass(HWND hWnd);
        void Unsubclass();
		
		//顯示窗口
        void ShowWindow(bool bShow = true, bool bTakeFocus = true);
        UINT ShowModal();
        void Close(UINT nRet = IDOK);
        void CenterWindow();    // 居中,支持擴展屏幕
        void SetIcon(UINT nRes);// 修改窗口圖標
		
		//系統函數的封裝
        LRESULT SendMessage(UINT uMsg, WPARAM wParam = 0, LPARAM lParam = 0L);
        LRESULT PostMessage(UINT uMsg, WPARAM wParam = 0, LPARAM lParam = 0L);
        void ResizeClient(int cx = -1, int cy = -1);//修改客戶端區域大小

    protected:
        virtual LPCTSTR GetWindowClassName() const = 0;
        virtual LPCTSTR GetSuperClassName() const;
        virtual UINT GetClassStyle() const;

        virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
        virtual void OnFinalMessage(HWND hWnd);

        static LRESULT CALLBACK __WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
        static LRESULT CALLBACK __ControlProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

    protected:
        HWND m_hWnd;
        WNDPROC m_OldWndProc;
        bool m_bSubclassed;
    };

  部分內容寫在註釋裏,耐心的讀者,請在以上源代碼中閱讀,可以學習下,在Subclass函數中,如何修改窗口函數、建立窗口和窗口對象指針聯繫的方法。但這個函數,在duilib中,並沒有調用。窗口函數的指定,還是在RegisterWindowClass或者RegisterSuperclass中完成的。
  在窗口的創建過程中,提供了兩種方法註冊窗口程序,一種是獨立窗口,另外一種是子控件的方法,對應着兩個註冊函數 bool RegisterWindowClass(),bool RegisterSuperclass();
  其次查看窗口中最重要的窗口消息函數,如下所示:

LRESULT CALLBACK CWindowWnd::__WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    CWindowWnd* pThis = NULL;
    if( uMsg == WM_NCCREATE ) {//創建窗口消息
        LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);//獲取創建窗口時的創建參數
        pThis = static_cast<CWindowWnd*>(lpcs->lpCreateParams);
        pThis->m_hWnd = hWnd;
        ::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LPARAM>(pThis));
    } 
    else {
        pThis = reinterpret_cast<CWindowWnd*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA));//獲取保存的窗口對象
        if( uMsg == WM_NCDESTROY && pThis != NULL ) {
            LRESULT lRes = ::CallWindowProc(pThis->m_OldWndProc, hWnd, uMsg, wParam, lParam);
            ::SetWindowLongPtr(pThis->m_hWnd, GWLP_USERDATA, 0L);
            if( pThis->m_bSubclassed ) pThis->Unsubclass();
            pThis->m_hWnd = NULL;
            pThis->OnFinalMessage(hWnd);
            return lRes;
        }
    }
    if( pThis != NULL ) {
        return pThis->HandleMessage(uMsg, wParam, lParam);//窗口自定義的消息處理
    } 
    else {
        return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
}

  從上述函數中可以得出,HandleMessage是窗口的消息處理函數。同時它是一個虛函數,子類可以通過虛函數的特徵來修改這個窗口消息函數。


  歡迎光臨知了軟件開發網絡平臺,本公司定製開發各類軟件,主要方向爲桌面專業軟件開發和插件定製開發,桌面軟件主要包括文字圖形識別類軟件,信息管理類軟件,3D打印類軟件,視頻類軟件以及其它涉及專業的各類圖形圖像處理軟件。插件包含AE插件,AI插件,PS插件,PDF插件,3DMAX插件以及Word,Excel等Office插件開發。詳情請諮詢,微信QQ:312117271,手機:18928899728,郵箱: [email protected].
公司網址:http://www.zhiliaos.com

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