在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