TextOut(hdc, 0, 0, buf, len);
fpssurf->ReleaseDC(hdc);
displayfps=TRUE;
framecount=0;
}
return TRUE;
}
Функция UpdateFPSSurface() использует переменную framecount для подсчета выведенных кадров. Переменная framecount обнуляется в двух случаях: при изменении видеорежима и при обновлении поверхности fpssurf заново вычисленным значением FPS.
Каждый раз, когда заданное количество кадров будет подготовлено и выведено на экран, функция timeGetTime() подсчитывает количество прошедших миллисекунд. По этой величине определяется текущий FPS приложения.
Значение FPS преобразуется в строку и выводится на поверхность FPS (после предварительной очистки поверхности функцией ClearSurface ()). После вывода текста переменная framecount обнуляется, и начинается новый интервал хронометража. Наконец, переменной displayfps присваивается значение TRUE; оно говорит о том, что на поверхности FPS находится допустимое значение, которое следует вывести на экран.
Возвращаясь к функции DrawScene() (см. листинг 4.4), мы видим, что код отображения fpssurf и переключения страниц выглядит так:
if (displayfps) {
int x=displayrect.right-fpsrect.right-1;
int y=displayrect.bottom-fpsrect.bottom-1;
backsurf->BltFast(x, y, fpssurf, 0, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT);
}
primsurf->Flip(0, DDFLIP_WAIT);
Если флаг displayfps равен TRUE, поверхность FPS следует вывести на экран. Однако сначала мы рассчитываем ее положение по известным размерам видеорежима и поверхности. Затем мы копируем поверхность fpssurf функцией BltFast (), после чего выводим на экран вторичный буфер функцией Flip() интерфейса DirectDrawSurface.
Задача функции DrawScene() выполнена — все три поверхности программы Switch выведены на экран. Тем не менее изучение приложения еще не закончено. Мы должны рассмотреть обработку пользовательского ввода.
Но перед тем как продолжить, я должен сделать одно замечание относительно программы Switch. Как мы видели во время рассмотрения ее кода, две из трех поверхностей программы имеют цветовые ключи для отображения прозрачных пикселей. Однако при запуске программы кажется, что анимационная поверхность (не имеющая цветового ключа) тоже является прозрачной. Почему? Потому что цвет фона растра (черный) совпадает с цветом вторичного буфера. Если изменить значение для заливки вторичного буфера, станет ясно, что анимационная поверхность на самом деле непрозрачна.
Обработка пользовательского ввода
При запуске программы Switch текст в нижней части меню подсказывает, какие клавиши управляют работой приложения. Клавиши со стрелками изменяют текущий выделенный видеорежим, клавиша Enter активизирует его (если он не является текущим), а клавиша Escape завершает работу программы. Все эти клавиши обрабатываются функцией OnKeyDown(), создаваемой ClassWizard. Ее код приведен в листинге 4.5.
Листинг 4.5. Функция SwitchWin::OnKeyDown()
void SwitchWin::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
int newindex;
int nmodes=GetNumDisplayModes();
if (nmodes>maxmodes) nmodes=maxmodes;
int rows=nmodes/menucols;
if (nmodes%menucols) rows++;
switch (nChar) {
case VK_ESCAPE:
PostMessage(WM_CLOSE);
break;
case VK_UP:
newindex=selectmode-1;
if (newindex>=0) {
selectmode=newindex;
UpdateMenuSurface();
}
break;
case VK_DOWN:
newindex=selectmode+1;
if (newindex<nmodes) {
selectmode=newindex;
UpdateMenuSurface();
}
break;
case VK_LEFT:
newindex=selectmode-rows;
if (newindex>=0) {
selectmode=newindex;
UpdateMenuSurface();
}
break;
case VK_RIGHT:
newindex=selectmode+rows;
if (newindex<nmodes) {
selectmode=newindex;
UpdateMenuSurface();
}
break;
case VK_RETURN:
if (selectmode != GetCurDisplayMode()) {
ActivateDisplayMode(selectmode);
x=y=0;
}
break;
case 'S':
SaveSurface(primsurf, 'switch.bmp');
break;
case 'M':
SaveSurface(menusurf, 'menusurf.bmp');
break;
case 'F':
SaveSurface(fpssurf, 'fpssurf.bmp');
break;
case 'T':
SaveSurface(bmpsurf, 'trisurf.bmp');