Пересмотрено на основе комментария:
Хорошо, вам нужно статическое окно сплиттера.Самый простой способ (я знаю) создать это - начать с проекта SDI MFC и сообщить ему, что вам нужно окно разделителя (в AppWizard в разделе «Функции интерфейса пользователя» установите флажок «Разделить окно»).Это создаст динамический разделитель - то есть, он начинается только с одной панели, и вы можете создать секунду, перетаскивая панель разделителя - но когда вы это сделаете, вы просто получите два одинаковых представления (хотя вы можете прокрутить их отдельнодруг от друга).
Затем нам нужно проделать небольшую работу, чтобы превратить ее из динамического разделителя в статический разделитель.Вероятно, лучше начать с просмотра кода для динамического сплиттера.Если вы посмотрите в CMainFrame
этого приложения, вы обнаружите, что оно имеет:
CSplitterWnd m_wndSplitter;
Если вы посмотрите в OnCreateClient
основного кадра, вы найдете что-то вроде этого:
return m_wndSplitter.Create(this,
2, 2, // TODO: adjust the number of rows, columns
CSize(10, 10), // TODO: adjust the minimum pane size
pContext);
Это то, что нам нужно изменить - Create
- это то, что создает динамический сплиттер.Мы должны избавиться от этого и создать вместо этого статический сплиттер.Первый шаг для этого - создать другой класс представлений - сейчас у нас есть только один класс представлений, но мы хотим два, по одному для каждой панели.
Самый простой (из известных мне) способ созданиянаш второй класс представления должен запустить вторую копию VS и создать другое (отдельное) приложение.Мы расскажем ему, чтобы основать класс представления для этого приложения на CListView
.Затем мы возьмем файлы для этого представления и добавим их в наш оригинальный проект.Чтобы упростить процесс подключения, мы хотим убедиться, что этот второй проект использует то же имя для своего класса документа, что и первый.
На этом этапе у нас есть код для нашего второго представления., но он не связан с чем-либо еще, поэтому созданное им представление не будет видимо.Чтобы сделать его видимым, нам нужно включить его заголовок в CMainframe.cpp (или любое другое имя, которое он имеет в вашем целевом проекте).Затем мы возвращаемся к OnCreateClient
и заменяем приведенный выше код на что-то вроде этого:
CRect rect;
GetClientRect(&rect);
BOOL ret = m_wndSplitter.CreateStatic(this, 2, 1); // 2 rows, 1 column of views
// row 0, column 0 will be the "OriginalView". The initial split will be
// in half -- i.e., each pane will be half the height of the frame's client
//
m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(OriginalView), CSize(1, rect.Height()/2), pContext);
m_wndSplitter.CreateView(1, 0, RUNTIME_CLASS(ListBasedView), CSize(1, rect.Height()/2), pContext);
На данный момент я создал горизонтальное разделение с «OriginalView» в верхнемпанель и «ListBaseView» в нижней панели, но (я думаю) должно быть совершенно очевидно, какие изменения нужно внести, чтобы изменить порядок представлений.
Оттуда, конечно, вам придется написатькод в каждого представления, чтобы делать то, что предполагается, что это представление должно делать - но так как каждое все еще является отдельным, нормальным представлением, каждое является достаточно независимым, поэтому разработка примерно такая же, как нормальная.Единственное существенное отличие состоит в том, что вы должны следовать правилам признания документа недействительным, и (особенно если обновление одного из представлений является дорогостоящим) вы можете рассмотреть возможность использования подсказок, чтобы указать, какая часть данных имеетбыл признан недействительным, поэтому вы можете написать каждое представление для обновления только того, что нужно, вместо того, чтобы просто перерисовывать все его данные каждый раз.