TN029. Окна разделителей

В этой заметке описывается класс MFC CSplitterWnd, который обеспечивает разделение окон и управление изменением размера других окон панели.

Стили разделения

A CSplitterWnd поддерживает два разных стиля разбиения окон.

В разделе "статические разбиения" окно разделения создает панели при создании. Порядок и количество панелей никогда не изменяются. Полосы разделения используются для изменения размера разных панелей. Этот стиль можно использовать для отображения другого класса представления на каждой панели. Графический редактор Visual C++ и диспетчер файлов Windows являются примерами программ, использующих этот стиль разделения. Этот стиль окна разделения не использует поля разделения.

В "динамических разбиениях" дополнительные панели создаются и уничтожаются по мере разделения пользователем и отмены разделения новых представлений. Этот разделитель начинается с одного представления и предоставляет поля разделения для пользователя, чтобы инициировать разделение. Окно разбиения динамически создает новый объект представления, если представление разделено в одном направлении. Этот новый объект представления представляет новую панель. Если представление разделено в двух направлениях с помощью интерфейса клавиатуры, окно разделения создает три новых объекта представления для трех новых областей. Хотя разделение активно, Windows отображает поле разбиения в виде полосы разделения между панелями. Windows уничтожает дополнительные объекты представления, когда пользователь удаляет разделение, но исходное представление остается до тех пор, пока окно разделения не будет уничтожено. Microsoft Excel и Microsoft Word — это примеры приложений, использующих динамический стиль разделения.

При создании любого типа окна разбиения необходимо указать максимальное количество строк и столбцов, которыми будет управлять разделитель. Статический разделитель создаст панели для заполнения всех строк и столбцов. Динамический разделитель создаст только первую панель при CSplitterWnd создании.

Максимальное количество панелей, которые можно указать для статических разбиений, — 16 строк на 16 столбцов. Рекомендуемые конфигурации:

  • 1 строка x 2 столбца: обычно с разнородными панелями

  • 2 строки x 1 столбца: обычно с разнородными панелями

  • 2 строки x 2 столбца: обычно с аналогичными панелями

Максимальное количество панелей, которые можно указать для динамических разделитов, — 2 строки по 2 столбцам. Рекомендуемые конфигурации:

  • 1 строка x 2 столбца: для данных столбцов

  • 2 строки x 1 столбца: для текстовых или других данных

  • 2 строки x 2 столбца: для сетки или табличных данных

Примеры разделения

Многие примеры программ MFC используют окна разделения напрямую или косвенно. В примере VIEWEX MFC показано несколько способов использования статических разбиений, в том числе способ размещения разбиения в разделитель.

Вы также можете использовать ClassWizard для создания нового класса окна дочернего окна фрейма (MDI) нескольких интерфейсов документов, содержащего окно разделения. Дополнительные сведения о окнах разбиения см. в разделе "Несколько типов документов", "Представления" и "Кадры".

Терминология, используемая реализацией

Ниже приведен список терминов, характерных для разделителей окон:

CSplitterWnd: окно, включающее элементы управления разделением области и полосы прокрутки, которые совместно используются между всеми панелями в строке или столбце. Строки и столбцы с отсчитываются от нуля (первая область — строка = 0 и столбец = 0).

Область: окно, управляемое приложением CSplitterWnd . Область обычно является объектом, производным от класса CView, но может быть любым объектом CWnd , который имеет соответствующий идентификатор дочернего окна.

Чтобы использовать производный CWndобъект, передайте RUNTIME_CLASS объекта в CreateView функцию, как было бы, если бы вы использовали производный CViewкласс. Класс должен использовать DECLARE_DYNCREATE и IMPLEMENT_DYNCREATE, так как платформа использует динамическое создание во время выполнения. Хотя в этом классе существует много кода CSplitterWndCView , CObject::IsKindOf всегда используется перед выполнением этих действий.

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

Splitter Box: элемент управления в динамическом CSplitterWnd объекте, который можно использовать для создания новых строк или столбцов панелей. Он расположен в верхней части вертикальных полос прокрутки или слева от горизонтальных полос прокрутки.

Пересечение разбиения: пересечение вертикальной полосы разбиения и горизонтальной полосы разбиения. Вы можете перетащить его, чтобы изменить размер строки и столбца панелей одновременно.

Общие полосы прокрутки

Класс CSplitterWnd также поддерживает общие полосы прокрутки. Эти элементы управления полосой прокрутки являются дочерними CSplitterWnd элементами и совместно используются различными панелями в разделитете.

Например, в окне столбца 1 строки x 2 можно указать WS_VSCROLL при создании CSplitterWnd. Windows создает специальный элемент управления полосой прокрутки, совместно используемый между двумя панелями.

[      ][      ][^]
[pane00][pane01][|]
[      ][      ][v]

Когда пользователь перемещает полосу прокрутки, WM_VSCROLL сообщения будут отправляться в оба представления. Если любое представление задает позицию полосы прокрутки, будет задана общая полоса прокрутки.

Обратите внимание, что общие полосы прокрутки наиболее полезны для аналогичных объектов представления. Если вы смешиваете представления разных типов в разбиении, может потребоваться написать специальный код для координации их позиций прокрутки. Любой CViewпроизводный CWnd класс, использующий API полосы прокрутки, будет делегироваться на общую полосу прокрутки, если она существует. Реализация CScrollView является одним из примеров CView класса, который поддерживает общие полосы прокрутки. Классы, не производные от классов, использующих полосы прокрутки, не зависящие от CViewэлементов управления, или классы, использующие стандартные реализации Windows (например, CEditView), не будут работать с общей функцией CSplitterWndполосы прокрутки.

Минимальные размеры

Для каждой строки имеется минимальная высота строки, а для каждого столбца — минимальная ширина столбца. Это минимальное значение гарантирует, что панель не слишком мала, чтобы отображаться подробно.

Для окна статического разбиения начальная минимальная высота строки и ширина столбца равна 0. Для динамического окна разделения начальная минимальная высота строки и ширина столбца задаются параметром CSplitterWnd::Create sizeMin функции.

Эти минимальные размеры можно изменить с помощью функций CSplitterWnd::SetRowInfo и CSplitterWnd::SetColumnInfo .

Фактические и идеальные размеры

Макет панелей в окне разбиения зависит от размера кадра, содержащего их. Когда пользователь изменяет размер содержащего кадра, CSplitterWnd он изменяет положение и изменяет размер панелей таким образом, чтобы они соответствовали им как можно больше.

Пользователь может вручную задать размеры строк и ширины столбцов, или программа может задать идеальный размер с помощью CSplitterWnd класса. Фактический размер может быть меньше или больше идеала. Windows настраивает фактический размер, если недостаточно места для отображения идеального размера или если в правой или нижней части окна разбиения слишком много пустого места.

Пользовательские элементы управления

Можно переопределить множество функций, чтобы обеспечить настраиваемое поведение и настраиваемый интерфейс. Вы можете переопределить этот первый набор, чтобы предоставить альтернативные изображения для различных графических компонентов окна разделения.

  • virtual void OnDrawSpltter(CDC* pDC, ESplitType nType, const CRect& rect);

  • virtual void OnInvertTracker(const CRect& rect);

Эта функция вызывается для создания общего элемента управления полосой прокрутки. Вы можете переопределить его, чтобы создать дополнительные элементы управления рядом с полосой прокрутки.

  • virtual BOOL CreateScrollBarCtrl(DWORD dwStyle, UINT nID);

Эти функции реализуют логику окна динамического разделения. Их можно переопределить, чтобы обеспечить более расширенную логику разделения.

  • virtual void DeleteView(int row, int col);

  • virtual BOOL SplitRow(int cyBefore);

  • virtual BOOL SplitColumn(int cxBefore);

  • virtual void DeleteRow(int rowDelete);

  • virtual void DeleteColumn(int colDelete);

Функции CView

Класс CView использует следующие команды высокого уровня для делегирования CSplitterWnd реализации. Так как эти команды являются виртуальными, стандартная CView реализация не требует, чтобы вся CSplitterWnd реализация была связана. Для приложений, которые используются CView , но не CSplitterWndиспользуются, CSplitterWnd реализация не будет связана с приложением.

  • virtual BOOL CanActivateNext(BOOL bPrev = FALSE);

    Проверяет, возможно ли ID_NEXT_PANE или ID_PREV_PANE.

  • virtual void ActivateNext(BOOL bPrev = FALSE);

    Выполняет команду "Следующая область" или "Предыдущая область".

  • virtual BOOL DoKeyboardSplit();

    Выполняет команду разделения клавиатуры, обычно "Разделение окна".

См. также

Технические примечания по номеру
Технические примечания по категории