У меня написана программа 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-> split я получаю всплывающее окно «Ошибка подтверждения отладки», и первый вызов CreateView возвращает FALSE, отображая мое сообщение: «Ошибка при настройке разделителей! (CreateView 1)»
Статический сплиттер для статический разделить — то есть окно это всегда Трещина. Вы обычно используете его, когда вы хотите иметь разные представления на каждой панели разделения (например, отображать столбец чисел на одной панели и график на другой панели).
Для ситуации, подобной вашей, вы хотите иметь окно, а затем разделить его и получить два практически идентичных представления, и вы (по крайней мере обычно) захотите использовать динамический разделитель.
По крайней мере, обычно вы создаете сплиттер при создании представления. Это создаст окно с ручкой в правом верхнем углу, которую пользователь тянет вниз, чтобы разделить вид:
Чтобы разделить окно, пользователь нажимает на ручку:
Когда разделение происходит там, где они хотят, они отпускают кнопку мыши, и представление разделяется на две отдельно прокручиваемые секции:
Так как вы не указали, хотите ли вы вертикальное или горизонтальное разделение, я настроил это, чтобы разрешить одно или оба:
Код для этого выглядит примерно так:
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;
Если вы хотите использовать окно сплиттера по требованию, вам нужно изменить родительский элемент текущего представления.
Итак, шаги:
И обратный путь.
Есть активные примеры, как переключить вид в текущем документе (MSDN). Это поможет вам, как идентификаторы должны быть заменены и изменены.