Сплиттер — это окно. Точнее — это дочернее окно. Оно позиционировано между двумя другими дочерними окнами — мы назовем их левым и правым подокном, соответственно (или верхним и нижним для горизонтального расщепителя). Должно также быть основное окно, явялющееся родителем для трех дочерних.
Без дальнейшей суеты приведем код WinMain, который осуществляет начальные установки.
В начале мы регистрируем классы. Верхний оконный класс связан с его оконной процедурой WndProcMain, которую мы рассмотрим через мгновение. Два дочерних подокна совместно используют тот же самый класс окна, связанный с WndProcPane. Затем регистрируется наш собственный класс сплиттера (мы скоро увидем его код). В заключение, создается и отображается верхнее окно. Дочерние окна создаются динамически во время инициализации родительского окна.
Имеем обычную оконную процедуру за исключением одного сообщения: MSG_MOVESPLITTER. Это — наше собственное, определяемое пользователем сообщение, которое послано сплиттером его родительскому окну. Но сначала давайте взглянем на контроллер главного окна.
class Controller {
public:
Controller(HWND hwnd, CREATESTRUCT* pCreat);
~Controller;
void Size(int cx, int cy);
void MoveSplitter(int x);
private:
enum { splitWidth = 8 }; // width of splitter
// User Interface
HWnd _hwnd;
//Main controller window
HWnd _leftWin;
HWnd _rightWin;
HWnd _splitter;
int _splitRatio; // in per cent
int _cx;
int _cy;
};
Контроллер содержит дескриптор своего окна, двух дочерних подокон, и окна сплиттера. Он также сохраняет текущий коэффициент разбиения, в процентах.
Конструктор контроллера отвечает за создание дочерних окон.
Когда пользователь перемещает полоску расщепителя, родитель получает сообщение MSG_MOVESPLITTER . Параметр wParam содержит новое расстояние полосы расщепителя от левого края родительского окна. В ответ на такое сообщение, родитель должен также изменить размеры дочерних подокон и переместить расщепитель. Он делает это, вызывая метод Size.
void Controller::MoveSplitter(int x) {
_splitRatio = x * 100 / _cx;
if (_splitRatio < 0) _splitRatio = 0;
else if (_splitRatio > 100) _splitRatio = 100;
Size(_cx, _cy);
}
Вообще же, Size вызывается всякий раз, когда пользователь изменяет размеры основного окна, но тот код который вытолько что видели, мы вызываем также тогда, когда сплиттер перемещается.