Разделить вид на две части с помощью кнопки меню? (МФЦ)

У меня написана программа 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)»

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;
3

Другие решения

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

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

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

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

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

1

По вопросам рекламы [email protected]