Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π“Ρ€Π°Ρ„ΠΈΠΊΠ° для Windows срСдствами DirectDrawΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 27

Автор Бтэн Π’Ρ€ΡƒΡ…ΠΈΠ»ΡŒΠΎ

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π΄Π°Π²Π°ΠΉΡ‚Π΅ рассмотрим Π½ΠΎΠ²Ρ‹Π΅ ΠΈ измСнившиСся ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ класса. Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ menusurf ΠΈΠ· ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Switch Π±Ρ‹Π» ΠΏΠ΅Ρ€Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ Π² modemenusurf ΠΏΠΎ Ρ‚ΠΎΠΉ ΠΆΠ΅ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π΅, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π±Ρ‹Π»ΠΈ ΠΏΠ΅Ρ€Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒΡŽ мСню Π²ΠΈΠ΄Π΅ΠΎΡ€Π΅ΠΆΠΈΠΌΠΎΠ². Π”Π°Π»Π΅Π΅ Π² классС появились ΡˆΠ΅ΡΡ‚ΡŒ Π½ΠΎΠ²Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…. Π― снова ΠΏΡ€ΠΈΠ²Π΅Π΄Ρƒ объявлСния Π½ΠΎΠ²Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… класса ΠΈΠ· листинга 4.6:

LPDIRECTDRAWSURFACE ratemenusurf;

int selectrate;

int numrates;

BOOL ratemenu_up;

BOOL include_refresh;

CArray<DWORD,DWORD> refresh_rates[MAXDISPLAYMODES];

ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ ratemenusurf прСдставляСт собой ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° интСрфСйс DirectDrawSurface ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒΡŽ мСню частот. Π’ Ρ†Π΅Π»Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… selectrate ΠΈ numrates хранятся соотвСтствСнно тСкущая выдСлСнная частота ΠΈ ΠΎΠ±Ρ‰Π΅Π΅ количСство ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌΡ‹Ρ… частот. ЛогичСская пСрСмСнная ratemenu_up ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, отобраТаСтся Π»ΠΈ мСню частот Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚.

Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ логичСской ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ include_refresh опрСдСляСтся Π²Ρ‹Π±ΠΎΡ€ΠΎΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, сдСланным Π² ΠΎΠΊΠ½Π΅ Π΄ΠΈΠ°Π»ΠΎΠ³Π° ΠΏΡ€ΠΈ стартС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Если эта пСрСмСнная Ρ€Π°Π²Π½Π° TRUE, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° создаСт ΠΈ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ мСню со списком частот для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ Π²ΠΈΠ΄Π΅ΠΎΡ€Π΅ΠΆΠΈΠΌΠ°. Если пСрСмСнная Ρ€Π°Π²Π½Π° FALSE, частоты Π½Π΅ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°ΡŽΡ‚ΡΡ. НаконСц, массив refresh_rates ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ для хранСния Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… частот ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π²ΠΈΠ΄Π΅ΠΎΡ€Π΅ΠΆΠΈΠΌΠ°. Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠΈΠΌΠΎΠ΅ массива опрСдСляСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ косвСнно Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ StoreModeInfo() ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ UpdateRateMenusurface()

Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ прилоТСния 

Как ΡƒΠΏΠΎΠΌΠΈΠ½Π°Π»ΠΎΡΡŒ Π²Ρ‹ΡˆΠ΅, ΠΏΠ΅Ρ€Π΅Π΄ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ DirectDraw ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° SuperSwitch Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ SuperSwitchWin::OnCreate() Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ΅ ΠΎΠΊΠ½ΠΎ. ПослС Π²Ρ‹Π²ΠΎΠ΄Π° Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π° функция Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Π²Π΅Ρ€ΡΠΈΡŽ OnCreate() класса DirectDrawWin. Код Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ SuperSwitchWin::OnCreate() выглядит Ρ‚Π°ΠΊ:

int SuperSwitchWin::OnCreate(LPCREATESTRUCT lpCreateStruct) {

 IntroDialog introdialog;

 if (introdialog.DoModal()!=IDOK) return -1;

 include_refresh=introdialog.include_refresh;

 if (DirectDrawWin::OnCreate(lpCreateStruct)==-1) return -1;

 if (include_refresh) ddraw2->EnumDisplayModes(DDEDM_REFRESHRATES, 0, this, StoreModeInfo);

 return 0;

}

Π‘Π½Π°Ρ‡Π°Π»Π° ΠΌΡ‹ создаСм ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ класса IntroDialog β€” этот класс-ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ° Π±Ρ‹Π» сгСнСрирован ClassWizard. Π”ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ΅ ΠΎΠΊΠ½ΠΎ отобраТаСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ CDialog::DoModal(), которая Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΊΠΎΠ΄ IDOK Π² случаС наТатия ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΌ ΠΊΠ½ΠΎΠΏΠΊΠΈ OK. Если ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ΅ ΠΎΠΊΠ½ΠΎ Π΄Ρ€ΡƒΠ³ΠΈΠΌ способом (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, наТимая ΠΊΠ½ΠΎΠΏΠΊΡƒ Cancel), функция OnCreate() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΊΠΎΠ΄ –1, Ρ‡Ρ‚ΠΎ для MFC являСтся ΠΏΡ€ΠΈΠ·Π½Π°ΠΊΠΎΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ прилоТСния. Если Π±Ρ‹Π»Π° Π½Π°ΠΆΠ°Ρ‚Π° ΠΊΠ½ΠΎΠΏΠΊΠ° OK, ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ include_refresh присваиваСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² зависимости ΠΎΡ‚ состояния Ρ„Π»Π°ΠΆΠΊΠ° Π² Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠΌ ΠΎΠΊΠ½Π΅.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Π²Π΅Ρ€ΡΠΈΡŽ OnCreate() класса DirectDrawWin, Π³Π΄Π΅ ΠΈ происходит инициализация DirectDraw. Ѐункция составляСт список Π²ΠΈΠ΄Π΅ΠΎΡ€Π΅ΠΆΠΈΠΌΠΎΠ², Π°ΠΊΡ‚ΠΈΠ²ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ исходный Ρ€Π΅ΠΆΠΈΠΌ ΠΈ создаСт повСрхности прилоТСния. Если Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ OnCreate() Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ Π½Π΅ΡƒΠ΄Π°Ρ‡Π΅ΠΉ, ΠΌΡ‹ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅ΠΌ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, возвращая ΠΊΠΎΠ΄ –1.

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ шаг β€” ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠ΅ составлСниС списка Π²ΠΈΠ΄Π΅ΠΎΡ€Π΅ΠΆΠΈΠΌΠΎΠ². На этот Ρ€Π°Π· ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ EnumDisplayModes() Π² ΠΏΠ΅Ρ€Π²ΠΎΠΌ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π΅ пСрСдаСтся Ρ„Π»Π°Π³ DDEDM_REFRESHRATES, согласно ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π²ΠΈΠ΄Π΅ΠΎΡ€Π΅ΠΆΠΈΠΌ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ Π² список ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ Ρ€Π°Π·Ρƒ для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΠΎΠΉ частоты. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΌΡ‹ смоТСм ΠΏΠΎΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ список частот для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π²ΠΈΠ΄Π΅ΠΎΡ€Π΅ΠΆΠΈΠΌΠ°. Π§Π΅Ρ‚Π²Π΅Ρ€Ρ‚Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ EnumDisplayModes() β€” функция косвСнного Π²Ρ‹Π·ΠΎΠ²Π° StoreModeInfo(), которая выглядит Ρ‚Π°ΠΊ:

HRESULT WINAPI SuperSwitchWin::StoreModeInfo(LPDDSURFACEDESC desc, LPVOID p) {

 DWORD w=desc->dwWidth;

 DWORD h=desc->dwHeight;

 DWORD d=desc->ddpfPixelFormat.dwRGBBitCount;

 DWORD r=desc->dwRefreshRate;

 SuperSwitchWin* win=(SuperSwitchWin*)p;

 int index=win->GetDisplayModeIndex(w, h, d);

 win->refresh_rates[index].Add(r);

 return DDENUMRET_OK;

}

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ StoreModeInfo()> пСрСдаСтся ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° структуру DDSURFACEDESC с описаниСм ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠ³ΠΎ Π²ΠΈΠ΄Π΅ΠΎΡ€Π΅ΠΆΠΈΠΌΠ°. Π’ описаниС Π²Ρ…ΠΎΠ΄ΠΈΡ‚ частота смСны ΠΊΠ°Π΄Ρ€ΠΎΠ² (ΠΏΠΎΠ»Π΅ dwRefreshRate), Π° Ρ‚Π°ΠΊΠΆΠ΅ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ опрСдСляСтся индСкс Ρ€Π΅ΠΆΠΈΠΌΠ°. Π—Π°Ρ‚Π΅ΠΌ этот индСкс ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для сохранСния частоты Π²ΠΈΠ΄Π΅ΠΎΡ€Π΅ΠΆΠΈΠΌΠ° Π² массивС.

ПослС Π²Ρ‹Ρ…ΠΎΠ΄Π° ΠΈΠ· Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ OnCreate() класс DirectDrawWin Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ CreateCustomSurfaces(). По ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΎΠΉ Switch эта функция Π½Π΅ измСнилась; ΠΎΠ½Π° ΠΏΠΎ-ΠΏΡ€Π΅ΠΆΠ½Π΅ΠΌΡƒ создаСт Ρ‚Ρ€ΠΈ повСрхности, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ новая ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ (ratemenusurface) создаСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² случаС нСобходимости. 

ГрафичСский Π²Ρ‹Π²ΠΎΠ΄ 

Π”Π°Π²Π°ΠΉΡ‚Π΅ посмотрим, ΠΊΠ°ΠΊ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ SuperSwitch Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π° функция DrawScene(). Она ΠΏΠΎΡ…ΠΎΠΆΠ° Π½Π° ΠΎΠ΄Π½ΠΎΠΈΠΌΠ΅Π½Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΈΠ· ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Switch, Π·Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ Π²Ρ‹Π±ΠΎΡ€Π΅ Π²ΠΈΠ΄Π΅ΠΎΡ€Π΅ΠΆΠΈΠΌΠ° новая вСрсия Π΄ΠΎΠ»ΠΆΠ½Π° ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Ρ‚ΡŒ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ со списком частот. Ѐункция DrawScene() выглядит Ρ‚Π°ΠΊ:

void SuperSwitchWin::DrawScene() {

 ClearSurface(backsurf, 0);

 BltSurface(backsurf, bmpsurf, x, y);

 x+=xinc; y+=yinc;

 const CRect& displayrect=GetDisplayRect();

 if (x<-160 || x>displayrect.right-160) {

  xinc=-xinc;

  x+=xinc;

 }

 if (y<-100 || y>displayrect.bottom-100) {

  yinc=-yinc;

  y+=yinc;

 }

 backsurf->BltFast(0, 0, modemenusurf, 0, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT);

 if (ratemenu_up) {

  DWORD w,h;

  GetSurfaceDimensions(ratemenusurf, w, h);

  backsurf->BltFast((320-w)/2, (200-h)/2, ratemenusurf, 0, DDBLTFAST_WAIT);

 }

 UpdateFPSSurface();

 if (displayfps) {

  int x=displayrect.right-fpsrect.right;

  int y=displayrect.bottom-fpsrect.bottom;

  backsurf->BltFast(x, y, fpssurf, &fpsrect, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT);

 }

 primsurf->Flip(0, DDFLIP_WAIT);

}

Код, ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°ΡŽΡ‰ΠΈΠΉ мСню частот, располоТСн Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΊΠΎΠ΄Π° мСню Π²ΠΈΠ΄Π΅ΠΎΡ€Π΅ΠΆΠΈΠΌΠΎΠ² (ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ мСню частот выводится ΠΏΠΎΠ²Π΅Ρ€Ρ… мСню Π²ΠΈΠ΄Π΅ΠΎΡ€Π΅ΠΆΠΈΠΌΠΎΠ²). ΠŸΡ€ΠΈΡΡƒΡ‚ΡΡ‚Π²ΠΈΠ΅ мСню частот опрСдСляСтся состояниСм Ρ„Π»Π°Π³Π° ratemenu_up. ΠŸΡ€ΠΈ Π²Ρ‹Π²ΠΎΠ΄Π΅ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ мСню частот выравниваСтся ΠΏΠΎ Ρ†Π΅Π½Ρ‚Ρ€Ρƒ повСрхности мСню Π²ΠΈΠ΄Π΅ΠΎΡ€Π΅ΠΆΠΈΠΌΠΎΠ². 

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ Π²Π²ΠΎΠ΄Π° 

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΠΊΠΎΠ΄ для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ Π²Π²ΠΎΠ΄Π° ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с мСню частот. ΠœΡ‹ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ OnKeyDown() (листинг 4.7).


Листинг 4.7. Ѐункция SuperSwitch::OnKeyDown()

void SuperSwitchWin::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:

  if (!include_refresh || !ratemenu_up) {

   PostMessage(WM_CLOSE);

   break;

  }

  if (ratemenu_up) {

   ratemenu_up=FALSE;

   if (ratemenusurf)     ratemenusurf->Release(), ratemenusurf=0;

  }

  break;

 case VK_UP:

  if (include_refresh && ratemenu_up) {

   if (selectrate>0) {

    selectrate--;

    UpdateRateMenuSurface();

   }

  } else {

   newindex=selectmode-1;

   if (newindex>=0) {

    selectmode=newindex;

    UpdateModeMenuSurface();

   }

  }

  break;

 case VK_DOWN:

  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 просто скрываСт Π΅Π³ΠΎ. ДСйствиС клавиш со стрСлками Ρ‚Π°ΠΊΠΆΠ΅ зависит ΠΎΡ‚ состояния мСню. Если мСню частот отобраТаСтся, стрСлки Β­ ΠΈ ΠΈΠ·ΠΌΠ΅Π½ΡΡŽΡ‚ Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½ΡƒΡŽ частоту, Π° Ссли Π½Π΅Ρ‚ β€” Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ ΠΏΡƒΠ½ΠΊΡ‚ Π² мСню Π²ΠΈΠ΄Π΅ΠΎΡ€Π΅ΠΆΠΈΠΌΠΎΠ².