一、窗口如何分割 切分窗口既適用於SDI應用程序,也適宜於MDI應用程序。它通常駐是以類 CSplitterWnd來表示,對 Windows 來說,CSplitterWnd 是一個真正的窗口,它完全占用框架窗口的客戶區域而視圖占用切分窗口的窗格區域。 動態切分與靜態切分 動態切分允許用戶須任何時候對窗口進行切分,用戶既可以通過選取菜單也可以通過拖動滾動條中的切分框來進行切分。動態切分窗口使用的是一個視圖類。 靜態切分,當窗口第一次被創建時,窗格就已經被切他好了,它們不能再被改變。用戶可以移動窗格邊框,但此時不能再對窗口進行合並或再劃分。靜態切分窗口允許使用多個視圖類,並且可以創建時對這些視圖類進行配置。在靜態切分窗口中,每個窗格都有自己的滾動條。 動態切分比較簡單,不實用,下面看靜態切分。
BOOL CMainFrame::OnCreateClIEnt(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
CRect rect;
GetClIEntRect(&rect);
m_wndSplitter1.CreateStatic(this,1,2);
m_wndSplitter1.CreateView(0,0,RUNTIME_CLASS(CClassTreeVIEw),CSize(150,150),pContext);
m_wndSplitter2.CreateStatic(&m_wndSplitter1,
2,1,WS_CHILD|WS_VISIBLE,
m_wndSplitter1.IdFromRowCol(0,1));
m_wndSplitter2.CreateView(1,0,RUNTIME_CLASS(CDagDetialVIEw),CSize(0,0),pContext);
m_wndSplitter2.CreateView(0,0,RUNTIME_CLASS(CDagVIEw),CSize(0,0),pContext);
m_wndSplitter2.SetRowInfo(0,rect.Height()/2,0);
return true;
//重載時不能調用基類的OnCreateClIEnt()
}
以上是本程序DEMO使用的方法。關於切分詳細信息,請查閱MSDN.
二、多視圖之間的通信 本程序demo使用了三個視圖類,Winzard生成了一個,其余的是我加的。關於多視圖之間的通信主要是茯得你要訪問的視圖類的pointer,如何茯得?有兩種方法1,通過視圖類(如果有多個視圖共享一個文檔類的話)2.通過主框架茯得。由於我的程式就一個文檔類,其他視圖類是獨立的,所以就采用第二種方法了。
以下代碼是茯得CDagDetialVIEw類指針的示例,其余類同。CMainFrame* pFrame=static_cast
(AfxGetMainWnd());//茯得主框架
CDagDetialView* pDagDetialVIEw =
static_cast(pFrame->m_wndSplitter2.GetPane(1,0));
以上有一點,我覺得最好采用以上形式,雖說通過C的強制轉換語法也行,但最好還是使用C++的語法比較好。
茯得視圖指針後你就可以do anything that you want to do
順便說一下,通信細節有一些牽連到效率的地方,一定要妥善處理。上面的demo程式,沒有考慮過多。因為我覺得這比較適合大家看明白意思,如果程式模塊分散開來,程式看起來是簡潔了不少,但不太方便看清程序流程。請見諒。
三、列表視圖的操作及事件處理
說句實話,列表的屬性參數很多,標准的、擴展的風格參數一大堆,看看那些英文文檔,在其中苦苦搜尋,找一條自己需要的特性,其中的滋味別提了。還好我很有耐心:)熟練了就好了,都記住了一大半,還怕什麼。列表控件顯示數據,要用LVS_REPORT風格,比較好看,就像DataGrid一樣。設置窗口風格需要用SetWindowLong這個API函數。這個函數是通用的。參數也一大堆。處理列表的單擊事件即是處理消息NM_CLICK,處理選擇改變時的事件即是處理LVN_ITEMCHANGED,不同的消息可能參數不同,需區別對待。
void CDagVIEw::OnItemchanged(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListVIEw = (NM