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

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

Жанры

Применение 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);

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

Реванш

СветочкаN
Фантастика:
фэнтези
5.00
рейтинг книги
Реванш

Воевода

Ланцов Михаил Алексеевич
5. Помещик
Фантастика:
альтернативная история
5.00
рейтинг книги
Воевода

Князь

Мазин Александр Владимирович
3. Варяг
Фантастика:
альтернативная история
9.15
рейтинг книги
Князь

Вечный. Книга II

Рокотов Алексей
2. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга II

Снега

Чепурин Юлий Петрович
Поэзия:
драматургия
5.00
рейтинг книги
Снега

На границе империй. Том 10. Часть 10

INDIGO
Вселенная EVE Online
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 10

Боярышня Дуняша 2

Меллер Юлия Викторовна
2. Боярышня
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Боярышня Дуняша 2

Ваше Сиятельство 6

Моури Эрли
6. Ваше Сиятельство
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Ваше Сиятельство 6

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

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

Хроники Тириса. Книга 1

Маханенко Василий Михайлович
1. Хроники Тириса
Фантастика:
боевая фантастика
космическая фантастика
фантастика: прочее
6.00
рейтинг книги
Хроники Тириса. Книга 1

Родословная. Том 4

Ткачев Андрей Юрьевич
4. Линия крови
Фантастика:
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Родословная. Том 4

Глубокий космос

Вайс Александр
9. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
Глубокий космос

Группа крови на рукаве

Вязовский Алексей
1. ГК
Фантастика:
боевая фантастика
попаданцы
альтернативная история
6.40
рейтинг книги
Группа крови на рукаве

Геном хищника. Книга четвертая

Гарцевич Евгений Александрович
4. Я - Легенда!
Фантастика:
боевая фантастика
рпг
попаданцы
5.00
рейтинг книги
Геном хищника. Книга четвертая