• Up()
• Down()
• Left()
• Right()
• Home()
• End()
• PageUp()
• PageDown()
Каждая из этих функций определяет положение поверхности по значениям переменных x, y, xlimit, ylimit, xscrollи yscroll. Код всех восьми функций приведен в листинге 5.9.
Листинг 5.9. Функции смещения поверхности
void BmpViewWin::Up(int inc) {
if (!yscroll) return;
if (y+inc<0) {
y+=inc;
update_screen=TRUE;
} else {
y=0;
update_screen=TRUE;
}
}
void BmpViewWin::Down(int inc) {
if (!yscroll) return;
if (y-inc>=ylimit) {
y-=inc;
update_screen=TRUE;
} else {
y=ylimit;
update_screen=TRUE;
}
}
void BmpViewWin::Left(int inc) {
if (!xscroll) return;
if (x+inc<0) {
x+=inc;
update_screen=TRUE;
} else {
x=0;
update_screen=TRUE;
}
}
void BmpViewWin::Right(int inc) {
if (!xscroll) return;
if (x-inc>=xlimit) {
x-=inc;
update_screen=TRUE;
} else {
x=xlimit;
update_screen=TRUE;
}
}
void BmpViewWin::Home() {
if (xscroll && x!=0) {
x=0;
update_screen=TRUE;
}
if (yscroll && y!=0) {
y=0;
update_screen=TRUE;
}
}
void BmpViewWin::End() {
if (yscroll) {
y=-(bmprect.Height()-displayrect.Height());
update_screen=TRUE;
}
if (xscroll) {
x=-(bmprect.Width()-displayrect.Width());
update_screen=TRUE;
}
}
void BmpViewWin::PageUp() {
if (yscroll) {
if (y-displayrect.Height()>0) {
y-=displayrect.Height();
update_screen=TRUE;
} else {
y=0;
update_screen=TRUE;
}
}
}
void BmpViewWin::PageDown() {
if (yscroll) {
if (y+displayrect.Height()<=ylimit) {
y+=displayrect.Height();
update_screen=TRUE;
} else {
y=ylimit;
update_screen=TRUE;
}
}
}
Обработчикам клавиш со стрелками ( Up(), Down(), Left(), Right()) можно передать необязательный аргумент, который определяет шаг прокрутки. Как видно из определения класса BmpViewWin (см. листинг 5.5), по умолчанию шаг прокрутки равен 4.
Заключение
В этой главе я упоминал о том, что загрузить растровое изображение на поверхность можно и другим, более простым способом. Вспомните — в интерфейс DirectDrawSurfaceвходит функция GetDC(), которая позволяет работать с поверхностями с помощью обычных функций Win32. Реализующая этот подход функция может выглядеть так:
BOOL CopyBmp(LPDIRECTDRAWSURFACE surface, HBITMAP bmp, int x, int y) {
if (bmp==0) {
TRACE("no bmp specified\n");
return FALSE;
}
if (surface==0) {
TRACE("no surface specified\n");
return FALSE;
}
HDC imageDC = CreateCompatibleDC(0);
SelectObject(imageDC, bmp);
BITMAP bitmap;
GetObject(bmp, sizeof(bitmap), &bitmap);
int w=bitmap.bmWidth;
int h=bitmap.bnHeight;
DDSURFACEDESC desc;
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD+HEIGHT |DDSC_WIDTH;
surface->GetSurfaceDesc(&desc);
HDC dc;
HRESULT result;
if ((result=surface->GetDC(&dc))==DD_OK)) {
Stretchblt(dc, 0, 0, desc.dwWidth, desc.dwHeight, imageDC, x, y, w, h, SRCCOPY);
surface->ReleaseDC(dc);
}
DeleteDC(imageDC);
return result==DD_OK;
}
Эта функция не имеет никакого отношения к программе этой главы, ее даже нет на CD-ROM. Она приведена с единственной целью — показать, что с помощью функции GetDC()интерфейса DirectDrawSurfaceи функции Win32 наподобие StretchBlt()можно легко скопировать растровое изображение Windows на поверхность. Разумеется, в этом случае приходится жертвовать скоростью, поскольку механизм GDI не отличается особым быстродействием, а его функции не поддаются оптимизации.
Не будем отклоняться от основной темы этой главы — прямого доступа к поверхностям. Загрузка растров на поверхности была всего лишь упражнением. Теперь, когда вы все знаете о блокировке поверхностей и форматах пикселей, вы сможете самостоятельно реализовать алгоритмы рисования линий, эффекты растрирования (dithering) и даже спрайты. Кроме того, можно включить в программу поддержку других файловых форматов.
В главе 6 мы узнаем, как наделить приложение поддержкой DirectInput. Обходя традиционные механизмы ввода Windows, DirectInput позволяет с максимальной эффективностью получать данные от таких устройств, как клавиатура или мышь.
Давайте отдохнем от DirectDraw и познакомимся с библиотекой DirectInput. Конечно, эта книга посвящена компьютерной графике, но ввод информации пользователем — необходимая часть любого графического приложения. Применение DirectInput улучшает работу программ, так как ввод обнаруживается и обрабатывается с максимальной скоростью. После краткого знакомства с DirectInput API мы обсудим различные схемы получения пользовательского ввода, поддерживаемые DirectInput. Знакомство закончится созданием двух приложений: Qwerty и Smear. Программа Qwerty использует DirectInput для ввода с клавиатуры, а Smear работает с мышью.
Читать дальше