2014-11-21 4 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; 
} 

После нажатия кнопки view-> раздвоение, я получаю «Debug Assertion Error» всплывающее окно, и первый вызов CreateView возвращает FALSE, отображение моего MessageBox: «Ошибка установки до разветвителя кадров ! (CreateView 1) "

ответ

3

A sta tic сплиттер для статический split - i.e, окно всегда split. Обычно вы используете его, когда хотите иметь другое представление в каждой области разделения (например, отображать столбец чисел на одной панели и график в другой панели).

Для ситуации, подобной вашей, что вы хотите иметь окно, затем разделите ее и получите два по существу идентичных вида, вы (по крайней мере, обычно) хотите использовать динамический разделитель.

Как минимум, вы создаете сплиттер при создании представления.Это позволит создать окно, которое имеет ручку в верхнем, правом угле, что пользователь тянет вниз, чтобы разделить мнение:

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

1

Если вы хотите использовать окно сплиттера по требованию, вам нужно изменить родительский элемент текущего представления. Так шаги:

  • создать простое приложение SDI
  • По требованию создать окно сплиттера
  • Использование SetParent для текущего вида и установить его в качестве родителя в окне сплиттера.
  • Создайте еще одно окно во втором сплиттере.

И обратный путь.

  • Используйте SetParent и приложите нормальный вид назад к основной раме.
  • уничтожить разветвитель

Есть активные образцы, как переключать вид в текущем документе (MSDN). Это помогает вам как заменять и изменять идентификаторы.

+0

Спасибо за пробой, это именно то, что я искал! – JayB

+0

просто для того, чтобы уточнить, когда вы говорите: «Создайте еще одно окно во втором сплиттере», вы имеете в виду во втором окне (которое является разделителем) или мне нужно создать два разветвителя? – JayB

+1

Я обновил свой вопрос – JayB