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

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

Жанры

Применение 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
рейтинг книги
Деревенщина в Пекине

Черный Маг Императора 4

Герда Александр
4. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 4

Курсант: назад в СССР 2

Дамиров Рафаэль
2. Курсант
Фантастика:
попаданцы
альтернативная история
6.33
рейтинг книги
Курсант: назад в СССР 2

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

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

Герой

Бубела Олег Николаевич
4. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.26
рейтинг книги
Герой

Точка Бифуркации V

Смит Дейлор
5. ТБ
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Точка Бифуркации V

Последний Паладин. Том 3

Саваровский Роман
3. Путь Паладина
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 3

Меченный смертью. Том 1

Юрич Валерий
1. Меченный смертью
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Меченный смертью. Том 1

Газлайтер. Том 22

Володин Григорий Григорьевич
22. История Телепата
Фантастика:
боевая фантастика
попаданцы
фэнтези
5.00
рейтинг книги
Газлайтер. Том 22

Газлайтер. Том 12

Володин Григорий Григорьевич
12. История Телепата
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Газлайтер. Том 12

Тринадцатый VII

NikL
7. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый VII

Зодчий. Книга I

Погуляй Юрий Александрович
1. Зодчий Империи
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Зодчий. Книга I

Сирийский рубеж 2

Дорин Михаил
6. Рубеж
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сирийский рубеж 2

Большая Гонка

Кораблев Родион
16. Другая сторона
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Большая Гонка