標題略長……之前百度了很多,也看過了很多程序,那個時候稍微有點小青澀,所以那些東西根本是看不懂什么意思…現在回過頭來看,其實還是很容易就實現的…當然,話題很初級,不是面向中高級群體的,湊合寫這湊合看,也是為了像當初我這么羞射的人看的……
首先說一下,使用CSplitterWnd類分割窗口。用這個可以動態分割,也可以靜態分割。具體怎么動態分割我忘了,靜態分割的方法大概就是在MainFrame類中重載某個函數…在里面添加分割代碼,首先CreateStatic,然后再為每一個分隔出來的窗口添加View類。當初因為什么原因一定要用這種方式我想不起來了。只是認為還有更好的方式實現多窗口啊,多視圖什么的。比如使用VS的那種風格,叫什么dockable之類的,如果僅僅是想添加一個可以拖動的對話框工具欄,那么直接使用CDialogBar會更簡單啊。使用靜態分割窗口是我那個時候的噩夢。根本搞不清楚如何隱藏。廢話少說,如果要隱藏靜態分隔出來的窗口,有個問題必須要先了解,那就是這些分個窗口的資源ID。嗯。這些資源的ID是有限制的,固定在AFX_IDW_PANE_FIRST和AFX_IDW_PANE_LAST之間。並且大小為16*16.也就是16行16列的意思。好了,言歸正傳,以下內容我只是復制的自己論文的一部分,當然是為了湊字數,實在不知道寫點啥…
1. 獲取要隱藏窗口的指針,調用ShowWindow(SW_HIDE)隱藏窗口;
2. 為該窗口指定一個新的ID資源,這個資源不會與現存的資源沖突;
3. 如果該窗口的后面還有其他窗口資源,那么需要將后面的窗口ID全部重新向前移動一位;
4. 將CSplitterWnd類中的保護成員變量m_nCols(如果是行則為m_nRows)減一,調用RecalcLayout。
代碼才是事實,所以下面是具體事例:
1 void CMySplitterWnd::HideLeftCol() //用於隱藏左側工具欄窗口 2 { 3 CWnd* pPaneHide = GetPane(0, 0); 4 pPaneHide->ShowWindow(SW_HIDE); 5 //將隱藏窗口資源ID分配到當前行的最大列之外 6 pPaneHide->SetDlgCtrlID(AFX_IDW_PANE_FIRST + m_nCols); 7 CWnd* pPane = GetPane(0, 1); 8 pPane->SetDlgCtrlID(IdFromRowCol(0, 0)); //將下一列的資源提前 9 m_nCols--; 10 RecalcLayout(); 11 }
這當然不是什么通用的代碼,所以別想什么復制粘貼的事情了。這段代碼具體來說,看類的名字也許就知道,我是自定義了一個叫做CMySplitterWnd類,這樣,我自己分割窗口當然用CMySplitterWnd類啦。
下面講解一下代碼,因為針對性特別強嘛,所以我說明一下,我用CMySplitterWNd類分割成了左右兩部分,我想隱藏的是左側窗口,所以第3行,pPaneHide就是我想要隱藏的窗口的指針,通過GetPane(0,0)獲取。第4行沒啥好說的,第6行,這里我也是有疑問的,為什么要這么做?我知道第六行代碼的含義是將隱藏窗口的資源ID重新分配,只是我不知道是否可以分配到一個更廣闊的地方呢?我自己也確實懶得實驗…總之這里就是把要隱藏的窗口的ID分配到了當前行的最大列之外一個。這里需要強調一下,這個程序很單一,因為我知道自己將窗口分割成了1行2列,所以才用這么偷懶的方式書寫。按照道理應該是如下書寫:
pPaneHide->SetDlgCtrlID(AFX_IDW_PANE_FIRST +current_row*16+ m_nCols);
一定要記得是當前行啊!由於當前行是0,所以我忽略掉了……接下來的事情就簡單了,誠如所見,就是將剩下的還在的窗口的ID重新分配一下,該提前的提前。第8行代碼的作用不就是如此么。注意第九行啊,一定要寫上。不寫有什么影響我不清楚,但是我認為后果一定很嚴重…這是CSplitterWnd類的內部保護成員,代表分個窗口的列數(看名字就知道。。。我還這么羅嗦。。。)
如果要把隱藏的窗口再顯示回來,自然就是上面步驟逆轉一下就好了,
void CMySplitterWnd::ShowLeftCol() { m_nCols++; //根據ID將隱藏的窗口找出來 CWnd* pPanShow = GetDlgItem(AFX_IDW_PANE_FIRST + m_nCols); pPanShow->ShowWindow(SW_SHOWNA); CWnd* pPane = GetPane(0, 0); pPane->SetDlgCtrlID(IdFromRowCol(0, 1)); pPanShow->SetDlgCtrlID(IdFromRowCol(0, 0)); RecalcLayout(); }
我想到了這里,應該都能懂了,所以就寫到這里吧!如果我有空並且還沒忘記這個地方的話,到時候會補上一個示例程序。
以上。