Чтение онлайн

на главную - закладки

Жанры

Применение Windows API

Легалов А. И.

Шрифт:

 HWnd _rightWin;

 HWnd _splitter;

 int _splitRatio; // in per cent

 int _cx;

 int _cy;

};

Контроллер содержит дескриптор своего окна, двух дочерних подокон, и окна сплиттера. Он также сохраняет текущий коэффициент разбиения, в процентах.

Конструктор контроллера отвечает за создание дочерних окон.

Controller::Controller(HWND hwnd, CREATESTRUCT * pCreat) : _hwnd (hwnd), _leftWin (0), _rightWin (0), _splitter (0), _splitRatio (50) {

 // Create child windows

 {

ChildWinMaker leftWinMaker(IDC_PANE, _hwnd, ID_LEFT_WINDOW);

leftWinMaker.Create;

_leftWin.Init(leftWinMaker);

leftWinMaker.Show;

 }

 {

ChildWinMaker rightWinMaker(IDC_PANE, _hwnd, ID_RIGHT_WINDOW);

rightWinMaker.Create;

_rightWin.Init(rightWinMaker);

rightWinMaker.Show;

 }

 Splitter::MakeWindow(_splitter, _hwnd, ID_SPLITTER);

}

Когда

пользователь перемещает полоску расщепителя, родитель получает сообщение 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 вызывается всякий раз, когда пользователь изменяет размеры основного окна, но тот код который вытолько что видели, мы вызываем также тогда, когда сплиттер перемещается.

void Controller::Size(int cx, int cy) {

 _cx = cx;

 _cy = cy;

 int xSplit = (_cx * _splitRatio) / 100;

 if (xSplit < 0) xSplit = 0;

 if (xSplit + splitWidth >= _cx) xSplit = _cx - splitWidth;

 _splitter.MoveDelayPaint(xSplit, 0, splitWidth, cy);

 _leftWin.Move(0, 0, xSplit, cy);

 _rightWin.Move(xSplit+splitWidth, 0, cx-xSplit-splitWidth, cy);

 _splitter.ForceRepaint ;

}

Обратите внимание на

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

Выше была представлена реализация клиентского кода. Теперь, я надеюсь, Вам будет интересно увидеть реализацию сплиттера.

Прежде всего нам приятно объединить зависимые функции в пространство имен. Вам видны вызовы Splitter::RegisterClass и Splitter::MakeWindow. Splitter в этих именах — это namespace.

namespace Splitter {

 void RegisterClass(HINSTANCE hInst);

 void MakeWindow(HWnd& hwndSplitter /* out */, HWnd hwndParent, int childId);

};

Ниже приводится реализация этих функций.

LRESULT CALLBACK WndProcSplitter(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

void Splitter::RegisterClass(HINSTANCE hInst) {

 WinClassMaker splitterClass(WndProcSplitter, "RsSplitterClass", hInst);

 splitterClass.SetSysCursor(IDC_SIZEWE);

 splitterClass.SetBgSysColor(COLOR_3DFACE);

 splitterClass.Register;

}

void Splitter::MakeWindow(HWnd& hwndSplitter, HWnd hwndParent, int childId) {

 ChildWinMaker splitterMaker("RsSplitterClass", hwndParent, childId);

 splitterMaker.Create; hwndSplitter.Init(splitterMaker);

 splitterMaker.Show;

}

Курсор мыши IDC_SIZEWE мы связываем с классом расщепителя — это стандартная, «направленная с запада на восток», двунаправленная стрелка. Мы также устанавливаем фоновую кисть к COLOR_3DFACE.

Оконная процедура расщепителя имеет дело с созданием/разрушением расщепителя, прорисовкой и перемещением мыши.

LRESULT CALLBACK WndProcSplitter(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {

 SplitController* pCtrl = GetWinLong<SplitController*>(hwnd);

 switch (message) {

 case WM_CREATE:

try {

pCtrl = new SplitController(hwnd, reinterpret_cast<CREATESTRUCT *>(lParam));

SetWinLong<SplitController*>(hwnd, pCtrl);

} catch (char const * msg) {

MessageBox(hwnd, msg, "Initialization", MB_ICONEXCLAMATION | MB_OK);

Поделиться:
Популярные книги

Печать Пожирателя

Соломенный Илья
1. Пожиратель
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Печать Пожирателя

Привет из Загса. Милый, ты не потерял кольцо?

Лисавчук Елена
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Привет из Загса. Милый, ты не потерял кольцо?

Мастер 2

Чащин Валерий
2. Мастер
Фантастика:
фэнтези
городское фэнтези
попаданцы
технофэнтези
4.50
рейтинг книги
Мастер 2

Нечто чудесное

Макнот Джудит
2. Романтическая серия
Любовные романы:
исторические любовные романы
9.43
рейтинг книги
Нечто чудесное

Клан

Русич Антон
2. Долгий путь домой
Фантастика:
боевая фантастика
космическая фантастика
5.60
рейтинг книги
Клан

Имя нам Легион. Том 3

Дорничев Дмитрий
3. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 3

Запасная дочь

Зика Натаэль
Фантастика:
фэнтези
6.40
рейтинг книги
Запасная дочь

Убивать чтобы жить 7

Бор Жорж
7. УЧЖ
Фантастика:
героическая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 7

У врага за пазухой

Коваленко Марья Сергеевна
5. Оголенные чувства
Любовные романы:
остросюжетные любовные романы
эро литература
5.00
рейтинг книги
У врага за пазухой

Кодекс Охотника. Книга XXI

Винокуров Юрий
21. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XXI

Генерал Скала и ученица

Суббота Светлана
2. Генерал Скала и Лидия
Любовные романы:
любовно-фантастические романы
6.30
рейтинг книги
Генерал Скала и ученица

Оцифрованный. Том 1

Дорничев Дмитрий
1. Линкор Михаил
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Оцифрованный. Том 1

Его маленькая большая женщина

Резник Юлия
Любовные романы:
современные любовные романы
эро литература
8.78
рейтинг книги
Его маленькая большая женщина

Хуррит

Рави Ивар
Фантастика:
героическая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Хуррит