А И Легалов - Применение Windows API
Название: | Применение Windows API | |
Автор: | А И Легалов | |
Жанр: | Современные российские издания, Литература ХXI века (эпоха Глобализации экономики), Windows, Программирование: прочее, Windows API | |
Изадано в серии: | неизвестно | |
Издательство: | неизвестно | |
Год издания: | 2002 | |
ISBN: | неизвестно | |
Отзывы: | Комментировать | |
Рейтинг: | ||
Поделись книгой с друзьями! Помощь сайту: донат на оплату сервера |
Краткое содержание книги "Применение Windows API"
Аннотация к этой книге отсутствует.
Читаем онлайн "Применение Windows API". [Страница - 28]
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);
return -1;
} catch (...) {
MessageBox(hwnd, "Unknown Error", "Initialization", MB_ICONEXCLAMATION | MB_OK);
return -1;
}
return 0;
case WM_SIZE:
pCtrl->Size(LOWORD(lParam), HIWORD(lParam));
return 0;
case WM_PAINT:
pCtrl->Paint();
return 0;
case WM_LBUTTONDOWN:
pCtrl->LButtonDown(MAKEPOINTS(lParam));
return 0;
case WM_LBUTTONUP:
pCtrl->LButtonUp(MAKEPOINTS(lParam));
return 0;
case WM_MOUSEMOVE:
if (wParam & MK_LBUTTON) pCtrl->LButtonDrag(MAKEPOINTS(lParam));
return 0;
case WM_CAPTURECHANGED:
pCtrl->CaptureChanged();
return 0;
case WM_DESTROY:
SetWinLong<SplitController*>(hwnd, 0);
delete pCtrl;
return 0;
}
return ::DefWindowProc(hwnd, message, wParam, lParam);
}
Это, в значительной степени, стандартный код. Подробности, как обычно, находятся в методах контроллера. Конструктор очень прост.
SplitController::SplitController(HWND hwnd, CREATESTRUCT * pCreat) : _hwnd (hwnd), _hwndParent (pCreat->hwndParent) {}
Прорисовка более интересна. Мы должны имитировать эффекты 2.5-размерности Windows. Мы делаем это путем тщательного отбора перьев.
class Pens3d {
public:
Pens3d();
Pen& Hilight() { return _penHilight; }
Pen& Light() { return _penLight; }
Pen& Shadow() { return _penShadow; }
Pen& DkShadow() { return _penDkShadow; }
private:
Pen _penHilight;
Pen _penLight;
Pen _penShadow;
Pen _penDkShadow;
};
Pens3d::Pens3d() : _penLight(GetSysColor(COLOR_3DLIGHT)), _penHilight(GetSysColor(COLOR_3DHILIGHT)), _penShadow(GetSysColor(COLOR_3DSHADOW)), _penDkShadow(GetSysColor(COLOR_3DDKSHADOW)) {}
void SplitController::Paint() {
PaintCanvas canvas(_hwnd);
{
PenHolder pen(canvas, _pens.Light());
canvas.Line(0, 0, 0, _cy - 1);
}
{
PenHolder pen(canvas, _pens.Hilight());
canvas.Line(1, 0, 1, _cy - 1);
}
{
PenHolder pen(canvas, _pens.Shadow());
canvas.Line(_cx - 2, 0, _cx - 2, _cy - 1);
}
{
PenHolder pen(canvas, _pens.DkShadow());
canvas.Line(_cx - 1, 0, _cx - 1, _cy - 1);
}
}
Более сложной является обработка сообщений от мыши, хотя значительная часть этого кода довольно стандартна. Мы должны обработать перемещение мыши и нажатие кнопки.
void SplitController::LButtonDown(POINTS pt) {
_hwnd.CaptureMouse();
// Find x offset of splitter
// with respect to parent client area POINT
ptOrg = {0, 0};
--">Книги схожие с «Применение Windows API» по жанру, серии, автору или названию:
Джон Роббинс - Отладка приложений для Microsoft .NET и Microsoft Windows Жанр: Современные российские издания Год издания: 2004 |
Джон Роббинс - Отладка Windows-приложений Жанр: Отладка, тестирование и оптимизация ПО Год издания: 2009 Серия: Для программистов |
Олег Брылев - Афганская ловушка Жанр: Новейшая история Год издания: 2014 |
Олег Пауллер - Псы войны. Дневники Шеннона Жанр: Приключения Год издания: 2018 |