if (include_refresh && ratemenu_up) {
if (selectrate<numrates-1) {
selectrate++;
UpdateRateMenuSurface();
}
} else {
newindex=selectmode+1;
if (newindex>nmodes) {
selectmode=newindex;
UpdateModeMenuSurface();
}
}
break;
case VK_LEFT:
if (include_refresh && ratemenu_up) break;
newindex=selectmode-rows;
if (newindex>=0) {
selectmode=newindex;
UpdateModeMenuSurface();
}
break;
case VK_RIGHT:
if (include_refresh && ratemenu_up) break;
newindex=selectmode+rows;
if (newindex<nmodes) {
selectmode=newindex;
UpdateModeMenuSurface();
}
break;
case VK_RETURN:
if (include_refresh) {
if (ratemenu_up) {
int rate=refresh_rates[selectmode][selectrate];
ActivateDisplayMode(selectmode, rate);
x=y=0;
ratemenu_up=FALSE;
} else {
CreateRateMenuSurface();
UpdateRateMenuSurface();
ratemenu_up=TRUE;
}
} else {
if (selectmode!=GetCurDisplayMode()) {
ActivateDisplayMode(selectmode);
x=y=0;
}
}
break;
case 'S':
SaveSurface(primsurf, 'SuperSwitch.bmp');
break;
default:
DirectDrawWin::OnKeyDown(nChar, nRepCnt, nFlags);
}
}
Все case-секции оператора switch были изменены для работы с новым меню. При нажатии клавиши Escape программа по-прежнему завершает работу, если меню частот в данный момент не отображается; тем не менее, если меню присутствует на экране, клавиша Escape просто скрывает его. Действие клавиш со стрелками также зависит от состояния меню. Если меню частот отображается, стрелки и изменяют выделенную частоту, а если нет — выделенный пункт в меню видеорежимов.
Самые существенные различия связаны с обработкой клавиши Enter. Если во время нажатия клавиши Enter меню частот не отображается, мы вызываем функции CreateRateMenuSurface() и UpdateRateMenuSurface() и присваиваем флагу ratemenu_up значение TRUE. Давайте рассмотрим эти две функции. Функция CreateRateMenuSurface() выглядит так:
BOOL SuperSwitchWin::CreateRateMenuSurface() {
if (ratemenusurf) ratemenusurf->Release(), ratemenusurf=0;
int rates=refresh_rates[selectmode].GetSize();
ratemenusurf=CreateSurface(80, rates*12+22);
return TRUE;
}
Сначала эта функция освобождает существующую поверхность (если таковая была создана ранее). Затем она определяет количество частот для выделенного в меню видеорежима и рассчитывает по ним размеры поверхности меню частот. Поверхность создается версией CreateSurface (), которой передаются ширина и высота новой поверхности.
Функция UpdateRateMenuSurface() отвечает за отображение текста меню. Выглядит она так:
BOOL SuperSwitchWin::UpdateRateMenuSurface() {
RECT rect;
GetSurfaceRect(ratemenusurf, rect);
rect.left++;
rect.top++;
rect.right--;
rect.bottom--;
if (!ClearSurface(ratemenusurf, 0, 200, 132)) TRACE('first Clear failed
');
if (!ClearSurface(ratemenusurf, 0, 128, 100, &rect)) TRACE('second Clear failed
');
HDC hdc;
ratemenusurf->GetDC(&hdc);
SelectObject(hdc, smallfont);
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, ratetextshadow);
ExtTextOut(hdc, 6, 4, 0, 0, rateheader, strlen(rateheader), 0);
SetTextColor(hdc, ratetextcolor);
ExtTextOut(hdc, 5, 3, 0, 0, rateheader, strlen(rateheader), 0);
CArray<DWORD,DWORD>& ratelist=refresh_rates[selectmode];
numrates=ratelist.GetSize();
for (int i=0; i<numrates; i++) {
char buf[10];
int len=sprintf(buf, '%d hz', ratelist[i]);
SetTextColor(hdc, ratetextshadow);
ExtTextOut(hdc, 11, i*12+18, 0, 0, buf, len, 0);
if (i==selectrate) SetTextColor(hdc, ratehighlightcolor);
else SetTextColor(hdc, ratetextcolor);