2009-9-8
========================================================
《深入解析MFC》筆記 9.MFC的增強型用戶界面類
========================================================
----------------------------
CSplitterWnd: MFC分割窗口 《深入解析MFC》P249
使用 CSplitterWnd
創建動態分割窗口
① 在子框架的派生類中加上一個 CSplitterWnd 數據成員。
② 在CMyChildFrame::OnCreateClient() 處理程序,添加對 CSplitterWnd::Create() 的調用。
Create() 的第一個參數指向父框架的指針,第二個和第三個分別指定了最大行數和最大列數。
第四個參數指定了所允許的最小窗格大小,第五個參數指向 CCreateContext 的指針。
③ 將框架窗口的 RUNTIME_CLASS 消息傳遞給 CDocTemplate 構造函數:
CMultiDocTemplate* pDocTemplate =
new CMultiDocTemplate( IDR_MYAPPTYPE, RUNTIME_CLASS(CMyDocClass ), RUNTIME_CLASS( CMyChildFrameClass ),
RUNTIME_CLASS(CMyViewClass));
AddDocTemplate(pDocTemplate);
創建靜態分割窗口,用 CreateStatic() 代替 Create()。調用CSplitterWnd::CreateView() 來創建新的窗格。
*************************
CSplitterWnd 內部實現
封裝的數據類型
· ESplitType —— 定義要畫出的分割器的類型,屬于枚舉類型。類型有 分割框、分割條、分割焦點以及分割邊界。
· CRowColInfo —— 記錄行或列的最小尺寸、理想尺寸和當前尺寸。
創建/布局數據成員
· m_pDynamicViewClass —— 指向由 CSplitterWnd 動態創建的視圖(窗格)的CRuntimeClass 信息的指針。Create() 或CreateView()中定義
· m_nMaxRows / m_nMaxCols —— 調用 Create() 和 CreateStatic() 時制定的最大行數和列數。
· m_nRows / m_nCols —— 當前在 CSplitterWnd 里顯示的行數和列數。
· m_bHasHScroll / m_bHasVScroll —— 表明行滾動條或列滾動條 是否已經創建的標記。
· m_pColInfo —— 是CRowInfo的數組,每個元素對應 CSplitterWnd 的一列。靜態分割中,這個值固定。
· m_pRowInfo —— 是 CRowColInfo 的數組,每個元素對應CSplitterWnd 的一行。
修飾的數據成員
在構造函數中初始化,
· m_cxSplitte / m_cySplitter —— 分割框和分割器的寬度和高度。
· m_cxBorderShare / m_cyBorderShare —— 如果分割窗口正在畫分割窗口的邊界,值為1.
· m_cxSplitterGap / m_cySplitterGap —— 分割框/分割條和滾動條/邊界之間的距離。值為6.
· m_cxBorder / m_cyBorder —— 分割邊界的邊界寬度。值為0.
跟蹤數據成員
用于點擊測試和跟蹤
· m_bTracking —— 如果為真,則用戶正在拖動一個分割條。
· m_bTracking2 —— 如果為真,用戶正在拖動兩個分割條。
· m_ptTrackOffset —— 點擊測試中的“選取”尺寸。允許用戶有所偏差。
· m_rectLimit —— 跟蹤時窗格的大小,用來確定被跟蹤的分割條的高度。
· m_rectTracker —— 跟蹤時用來畫分割條的矩形。
· m_rectTracker2 —— 跟蹤時用來畫第二個分割條的矩形
· m_htTrack —— 被 CSplitterWnd 的點擊跟蹤機制設置成一個枚舉值,用來描述分割窗口的哪個部分被點擊了。
通用成員函數
· CreateCommon() —— 當Create() 和 CreateStatic() 初始化完 CSplitterWnd 的動態成員或靜態成員時會調用這個函數。
· CreateScrollBarCtrl() —— 創建帶有指定風格和標示符的滾動條。
· DoScroll() —— 對滾動條消息作出反應。 DoScroll() 能夠同步適當的窗格。
· DoScrollBy() —— 以制定的數量滾動相應的窗格。
· DoKeyboardSplit() —— 在程序里調用該函數會使得窗口被分割。
· CanActivateNext() —— 用來確定下一個窗格是否能被激活。即是否能得到焦點,被CView類調用
· ActivateNext() —— 激活下一個窗格。通常在一個窗格被刪除時調用
布局成員函數
· RecalcLayout() —— 維護所有分割窗口的位置,當一個窗格被創建/刪除時,被調用。
· TrackRowSize() —— 更新指定行的 m_pRowInfo 數組信息。同時確定是否有足夠的空間來存儲該行。
· TrackColumnSize() ——
· GetSizingParent() —— 搜索大小可變的父窗口
繪畫成員函數
· DrawAllSplitBars() —— “驅動”分割窗口的繪畫進程,為每個需要繪畫的組件調用 OnDrawSplitter.
· OnDrawSplitter() —— 為分割窗口的每個組件進行繪畫,為虛函數。
· OnPaint() —— 對WM_PAINT消息作出響應
點擊測試成員函數
· HitTest() —— 選取某個點,返回這個點的點擊測試值。
· GetInsideRect() —— 類同GetClientRect(),考慮了共享的滾動條。
· GetHitRect() —— 為某一指定的分割窗口組件檢索點擊矩形。
· SetSplitCursor() —— 使用點擊測試來確定要顯示哪一種光標。
跟蹤成員函數
· OnNcCreate() —— CSplitterWnd 處理WM_NCCREATE 消息,所以它可以移走 WS_EX_CLIENTEDGE 的擴展風格位。
· OnPaint() —— 畫分割窗口的各個組件。
· OnDisplayChange() —— 當用戶改變顯示器的分辨率時背調用,調用RecalcLayout() 來更新分割窗口。
· OnSize() —— 當用戶改變窗口大小時 調用 RecalcLayout()。
· OnMouseMove() —— 在分割窗口組件上執行點擊測試。
**************************
CSplitteWnd 的初始化
CSPlitterWnd::CreateCommon()
① 調整好風格標記。
② 調用 AfxDeferRegisterClass(),CWnd::CreateEx()。
③ 為 m_pColInfo 和 m_pRowInfo 數組分配空間,并進行初始化,將 m_nMaxCols/Rows 作為數組的大小。
CreateCommon() 在循環里一次訪問CRowColInfo數組,做如下操作
1. nMinSize 和 nIdealSize 都被設置成參數 sizeMin的值。
2. nCurSize 被初始化為 -1,說明當窗格的尺寸被初始化(RecalcLayout)時,該值應該被設置。
④ 初始化完CrowColInfo 的行列數組后,調用 SetScrollStyle() 將 m_bHasH/VScroll 進行初始化,然后返回TRUE
CSplitterWnd::CreateView()
① 將sizeInit參數存儲在 CRowColInfo相應的數組下標里,設置一個局部標記 bSendInitialUpdate 值為FALSE。
② 創建一個局部的CCreateContext(),盡量將每個元素初始化為比較完整的值。調用 GetActivePane() 來確定 m_pLastViewCView指針
一旦CreateView() 有了m_pLastView,就可以通過調用 GetDocument() 來確定 CCreateContext 其他域的值,
然后調用 CDocument::GetDocTemplate()。在找到所有這些元素后,pContext指向她們,將bSendInitialUpadte設為 TRUE。
③ 調用 CreateObject() 為 CRuntimeClass 信息創建一個窗格對象。設置要傳遞到 Create() 的參數 風格和定位矩形。
posted on 2010-03-15 23:26
Euan 閱讀(1653)
評論(0) 編輯 收藏 引用 所屬分類:
windows