2014-11-21 40 views
1

我有一個MFC程序寫入,讀取文件,存儲數據,並將其作爲文本繪製在客戶端視圖上。用菜單按鈕分割兩個視圖? (MFC)

我想製作一個菜單按鈕View-> Split,將客戶區域拆分爲兩個,分別滾動顯示相同數據的視圖。

我在網上看到了一些關於CWndSplitter的內容,並通過一些文檔進行了閱讀,但沒有一篇文章證明是有用的,因爲他們談論了使用OnCreate並刪除默認視圖以使其工作。這不是一個選項。我想保留默認視圖,但如果用戶單擊按鈕將其分成兩部分。

我目前創建了一個CWndSplitter成員變量,並在SDI-1View.cpp中定義了一個菜單按鈕事件處理程序。被調用時,它絕對不會導致屏幕閃爍,並且第二次點擊會使程序崩潰。

void CSDI1View::OnViewSplit32778() 
{ 
// TODO: Add your command handler code here 

/* 
int rows = 2; 
int columns = 1; 
if (!m_wndSplitter.CreateStatic(this, rows, columns)) 
    return; 

if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CSDI1View), CSize(100, 100), NULL) || 
    (!m_wndSplitter.CreateView(1, 0, RUNTIME_CLASS(CSDI1View), CSize(100, 100), NULL))) 
{ 
    m_wndSplitter.DestroyWindow(); 
    return; 
} 
*/ 
} 

任何人都可以告訴我什麼將客戶端視圖分成兩半的正常方法是?我只想將它集成到事件處理程序中。 任何幫助將不勝感激。

謝謝。

--------------------------------編輯------------- ---------------------

我現在在我的Split按鈕事件處理程序中有以下代碼,這要歸功於xMRi提供的輪廓,但它仍然是工作不正常...

void CMainFrame::OnViewSplit() 
{ 
// TODO: Add your command handler code here 
//calculate client size 
CRect cr; 
GetClientRect(&cr); 

if (!m_mainSplitter.CreateStatic(this, 2, 1)) 
{ 
    MessageBox(_T("Error setting up splitter frames! (CreateStatic)"), 
     _T("Init Error!"), MB_OK | MB_ICONERROR); 
    return; 
} 

// Set the parent of the splitter window to the current view 
CSDI1View * view = CSDI1View::GetView(); 
m_mainSplitter.SetParent(this); 
view->SetParent(&m_mainSplitter); 

// Create a CCreateContext 
CCreateContext cc; 
CRuntimeClass* prt = RUNTIME_CLASS(CSDI1View); 
cc.m_pNewViewClass = prt; 
cc.m_pCurrentDoc = view->GetDocument(); 
cc.m_pNewDocTemplate = NULL; 
cc.m_pLastView = NULL; 
cc.m_pCurrentFrame = this; 

if (!m_mainSplitter.CreateView(0, 0, 
    cc.m_pNewViewClass, 
    CSize(cr.Width(), cr.Height()/2), &cc)) 
{ 
    MessageBox(_T("Error setting up splitter frames! (CreateView 1)"), 
     _T("Init Error!"), MB_OK | MB_ICONERROR); 
    return; 
} 

if (!m_mainSplitter.CreateView(1, 0, 
    cc.m_pNewViewClass, 
    CSize(cr.Width(), cr.Height()/2), &cc)) 
{ 
    MessageBox(_T("Error setting up splitter frames! (CreateView 2)"), 
     _T("Init Error!"), MB_OK | MB_ICONERROR); 
    return; 
} 

m_bInitSplitter = TRUE; 
} 

在點擊查看 - >劈扣,我得到一個「調試斷言錯誤」彈出式和第一次調用CreateView的返回FALSE,顯示我的消息框:「錯誤設置分離器框!(CreateView 1)「

回答

3

sta tic分離器是針對靜態分割 - 即,一個窗口是總是分割。當您想在拆分的每個窗格中顯示不同的視圖(例如,在一個窗格中顯示一列數字,在另一個窗格中顯示一個圖形)時,通常會使用它。

對於像你的情況,你希望能夠擁有這個窗口,然後再分割它,並有兩個基本相同的視圖,你(至少通常)要使用動態分配器。

至少通常在創建視圖時創建分隔線。這將創建在用戶下拉拆分視圖頂部,右上角有一個把手的窗口:

enter image description here

要拆分的窗口中,用戶拉下手柄:

enter image description here

當分流他們想要的,它們釋放鼠標按鈕,並且視圖分成兩個分別可滾動部分:

enter image description here

既然你沒有指定你是否要垂直或水平分割,我設置一個最高允許一個或兩個:

enter image description here

該代碼,這看起來是這樣的:

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT, CCreateContext* pContext) { 
    return my_splitter.Create(this, 
     2, 2,    // 2 rows, 2 columns 
     CSize(20, 20),  // minimum pane size 
     pContext); 
} 

其中my_splitter的定義是這樣的:

CSplitterWnd my_splitter; 
+0

感謝您的支持。我想創建一個靜態分割,我可以通過切換父母的方式打開和關閉,本質上是xMRi在他的答案中描述的。我遇到了另一個問題,請看我的問題編輯。 – JayB 2014-11-21 15:30:00

1

如果您想要按需使用分隔窗口,則需要更改當前視圖的父級。 因此,步驟是:

  • 創建一個簡單的SDI應用程序
  • 根據需要創建一個拆分窗口
  • 使用的setparent到當前視圖並將其設置爲在拆分窗口父。
  • 在第二個分離器中創建另一個窗口。

而回來的路上。

  • 使用SetParent並將普通視圖重新附加到主框架。
  • 銷燬分離器

有活性的樣品如何切換的視圖一個當前文檔(MSDN)英寸它可以幫助您如何替換和更改ID。

+0

感謝您的分解,這正是我一直在尋找的! – JayB 2014-11-21 14:48:45

+0

只是爲了澄清,當你說「在第二個分離器中創建另一個窗口」時,你的意思是在第二個窗口(這是分離器)還是應該創建兩個分離器? – JayB 2014-11-21 14:49:34

+1

我已更新我的問題 – JayB 2014-11-21 15:19:48