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

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

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

 backsurf->BltFast(curx, cury, cursor, 0, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT);

 primsurf->Flip(0, DDFLIP_WAIT);

 while (primsurf->GetFlipStatus(DDGFS_ISFLIPDONE)!=DD_OK);

 // Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ Π΄Π΅Π»Π°Ρ‚ΡŒ (ΠΆΠ΄Π°Ρ‚ΡŒ, ΠΏΠΎΠΊΠ° закончится

 // ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ страниц)

 int x, y;

 BOOL newclick=FALSE;

 int count=mouseclickqueue.GetCount();

 while (count--) {

  MouseClickData mc=mouseclickqueue.RemoveTail();

  if (mc.button==0) {

   x=mc.x;

   y=mc.y;

   newclick=TRUE;

  }

 }

 critsection.Unlock();

 //------ ΠšΠΎΠ½Π΅Ρ† синхронизированной сСкции -------

 //------ Π‘Π΄Π΅Π»Π°Ρ‚ΡŒ ΠΏΠ°ΡƒΠ·Ρƒ Π² соотвСтствии с Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠΉ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ ----

 if (delay_value[dm_index]!=0) Sleep(delay_value[dm_index]);

 //------ ΠžΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ мСню Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ --------

 if (newclick) {

  int max_index=sizeof(delay_value)/sizeof(int)-1;

  int menux=screen_width-dm_width+dm_margin;

  int menuw=dm_width-dm_margin*2;

  if (x>=menux && x<=menux+menuw) {

   int index=(y-dm_header)/dm_entrysize;

   if (index>=0 && index<=max_index && index!=dm_index) {

    dm_index=index;

    UpdateDelaySurface();

   }

  }

 }

}

Ѐункция DrawScene() состоит ΠΈΠ· сСми этапов:

1. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° клавиши Escape.

2. ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ° Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠ°Π΄Ρ€Π° Π²ΠΎ Π²Ρ‚ΠΎΡ€ΠΈΡ‡Π½ΠΎΠΌ Π±ΡƒΡ„Π΅Ρ€Π΅.

3. ОбновлСниС курсора (Ρ‚Π°ΠΊΠΆΠ΅ Π²ΠΎ Π²Ρ‚ΠΎΡ€ΠΈΡ‡Π½ΠΎΠΌ Π±ΡƒΡ„Π΅Ρ€Π΅).

4. ΠŸΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ страниц.

5. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ событий ΠΌΡ‹ΡˆΠΈ.

6. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ событий ΠΌΡ‹ΡˆΠΈ.

7. ОбновлСниС повСрхности мСню Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ.

ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ этап выполняСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ GetDeviceState() интСрфСйса DirectInputDevice. Если Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ΠΎ Π½Π°ΠΆΠ°Ρ‚ΠΈΠ΅ клавиши Escape, функция посылаСт сообщСниС WM_CLOSE, сигнализируя ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ прилоТСния.

ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ° Π²Ρ‚ΠΎΡ€ΠΈΡ‡Π½ΠΎΠ³ΠΎ Π±ΡƒΡ„Π΅Ρ€Π° (этап 2) Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Π΅Π³ΠΎ стираниС ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² Π½Π΅Π³ΠΎ внСэкранной повСрхности. Для ΠΏΠ΅Ρ€Π΅Π±ΠΎΡ€Π° повСрхностСй ΠΈΠ· массива coil ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ статичСская цСлая пСрСмСнная (массив coil подготавливаСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ CustomSurfaces(), ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΌΡ‹ Π½Π΅ рассматриваСм).

На этапах 3, 4 ΠΈ 5 ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° обращаСтся ΠΊ рСсурсам, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ Π²Π²ΠΎΠ΄Π°, поэтому Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ критичСской сСкциСй. ΠžΠ±ΡŠΠ΅ΠΊΡ‚ класса CCriticalSection (critsection), ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Π½Ρ‹ΠΉ Π² классС CursorWin (см. листинг 7.1), блокируСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ Lock(). Π­Ρ‚Π° функция пытаСтся ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ критичСской сСкции. Если ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° оказываСтся ΡƒΠ΄Π°Ρ‡Π½ΠΎΠΉ, функция Π·Π°Ρ…Π²Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ ΠΊΡ€ΠΈΡ‚ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΡΠ΅ΠΊΡ†ΠΈΡŽ ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ. ПослС этого ΠΌΠΎΠΆΠ½ΠΎ смСло Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с совмСстными рСсурсами β€” ΠΏΠΎΡ‚ΠΎΠΊ Π·Π°Π²Π΅Π΄ΠΎΠΌΠΎ ΠΎΠ±Π»Π°Π΄Π°Π΅Ρ‚ ΠΌΠΎΠ½ΠΎΠΏΠΎΠ»ΡŒΠ½Ρ‹ΠΌ ΠΏΡ€Π°Π²ΠΎΠΌ доступа ΠΊ Π½ΠΈΠΌ. Если Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Lock() Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‚ΠΊΠ°Π·Π°Π½ΠΎ Π² доступС (ΠΈΠ·-Π·Π° Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎ критичСская сСкция Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π·Π°Ρ…Π²Π°Ρ‡Π΅Π½Π° ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ Π²Π²ΠΎΠ΄Π°), функция Lock() Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ основной ΠΏΠΎΡ‚ΠΎΠΊ Π΄ΠΎ освобоТдСния критичСской сСкции.

На этапС 3 ΠΌΡ‹ сохраняСм содСрТимоС области Π²Ρ‚ΠΎΡ€ΠΈΡ‡Π½ΠΎΠ³ΠΎ Π±ΡƒΡ„Π΅Ρ€Π°, занятой курсором, Π° Π·Π°Ρ‚Π΅ΠΌ рисуСм курсор Π² Π±ΡƒΡ„Π΅Ρ€Π΅. ОбС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ BltFast() интСрфСйса DirectDrawSurface.

На этапС 4 выполняСтся ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ страниц, ΠΎΠ΄Π½Π°ΠΊΠΎ ΠΎΠ½ΠΎ происходит слоТнСС, Ρ‡Π΅ΠΌ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ. Π­Ρ‚ΠΎ связано с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ функция Flip() интСрфСйса DirectDrawSurface Π½Π° самом Π΄Π΅Π»Π΅ Π½Π΅ выполняСт ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ. Она лишь ΠΏΡ€ΠΈΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Π΅ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ страницы ΠΈ послС этого Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ. ЀактичСскоС ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ страниц происходит послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ Π±ΡƒΠ΄ΡƒΡ‚ Π·Π°ΠΊΠΎΠ½Ρ‡Π΅Π½Ρ‹ всС Ρ€Π°Π½Π΅Π΅ Π½Π°Ρ‡Π°Ρ‚Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π±Π»ΠΈΡ‚Ρ‚ΠΈΠ½Π³Π° Π²ΠΎ Π²Ρ‚ΠΎΡ€ΠΈΡ‡Π½Ρ‹ΠΉ Π±ΡƒΡ„Π΅Ρ€. Для Π½Π°ΡˆΠΈΡ… Ρ†Π΅Π»Π΅ΠΉ этого нСдостаточно. Нам Π½ΡƒΠΆΠ½ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ страниц Π±Ρ‹Π»ΠΎ Π·Π°ΠΊΠΎΠ½Ρ‡Π΅Π½ΠΎ Π΄ΠΎ ΠΊΠΎΠ΄Π° критичСской сСкции, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС ΠΏΠΎΡ‚ΠΎΠΊ Π²Π²ΠΎΠ΄Π° смоТСт ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½ΡƒΡŽ ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ Π²ΠΎ врСмя ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ страниц. Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ†ΠΈΠΊΠ»Π° while ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ GetFlipStatus() интСрфСйса DirectDrawSurface ΠΌΡ‹ ΠΎΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌ DirectDraw Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ страниц Π½Π΅ закончится (Π² DirectDraw Π½Π΅ прСдусмотрСна Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° ΠΏΠΎ этой ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, Π½ΠΎ Π΄Π°ΠΆΠ΅ Ссли Π±Ρ‹ ΠΎΠ½Π° ΠΈ Π±Ρ‹Π»Π°, ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ страниц происходит слишком быстро ΠΈ Π½Π΅ ΠΎΠΏΡ€Π°Π²Π΄Ρ‹Π²Π°Π΅Ρ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ°).

На этапС 5 ΠΌΡ‹ провСряСм ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ событий ΠΌΡ‹ΡˆΠΈ. Π­Π»Π΅ΠΌΠ΅Π½Ρ‚Ρ‹ ΠΈΠ·Π²Π»Π΅ΠΊΠ°ΡŽΡ‚ΡΡ ΠΈΠ· ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ, ΠΏΠΎΠΊΠ° ΠΎΠ½Π° Π½Π΅ опустССт. ΠšΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ Π»Π΅Π²ΠΎΠΉ (Π½ΡƒΠ»Π΅Π²ΠΎΠΉ) ΠΊΠ½ΠΎΠΏΠΊΠΈ ΠΌΡ‹ΡˆΠΈ ΡΠΎΡ…Ρ€Π°Π½ΡΡŽΡ‚ΡΡ для дальнСйшСго использования.

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

Π­Ρ‚Π°ΠΏ 6 Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ синхронизации, поэтому ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ CCriticalSection::Unlock(). Если ΠΊ этому ΠΌΠΎΠΌΠ΅Π½Ρ‚Ρƒ ΠΏΠΎΡ‚ΠΎΠΊ Π²Π²ΠΎΠ΄Π° Π±Ρ‹Π» Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ ΠΈ ΠΎΠΆΠΈΠ΄Π°Π» доступа ΠΊ своСй критичСской сСкции, Π²Ρ‹Π·ΠΎΠ² Unlock() ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ Π΅ΠΌΡƒ Π²ΠΎΠΉΡ‚ΠΈ Π² Π½Π΅Π΅.

На этапС 7 обновляСтся ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ мСню Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ β€” Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ слСдовало Π±Ρ‹ ΡΠΏΡ€ΡΡ‚Π°Ρ‚ΡŒ Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΌ классС управлСния мСню. Но, ΠΊΠ°ΠΊ ΡƒΠΆΠ΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΠ»ΠΎΡΡŒ Π² этой Π³Π»Π°Π²Π΅, я Ρ€Π΅ΡˆΠΈΠ» ΡΠΎΠΊΡ€Π°Ρ‚ΠΈΡ‚ΡŒ количСство Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΈ классов Π² этой ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅, поэтому большая Ρ‡Π°ΡΡ‚ΡŒ ΠΊΠΎΠ΄Π° ΠΎΡΡ‚Π°Π»Π°ΡΡŒ «сырой». Π’Π°ΠΊ ΠΈΠ»ΠΈ ΠΈΠ½Π°Ρ‡Π΅, Π½Π° этапС 7 ΠΌΡ‹ провСряСм ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ послСднСго наТатия Π»Π΅Π²ΠΎΠΉ ΠΊΠ½ΠΎΠΏΠΊΠΈ ΠΌΡ‹ΡˆΠΈ ΠΈ Π² соотвСтствии с Π½ΠΈΠΌΠΈ обновляСм мСню.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΡ‹ Π·Π½Π°Π΅ΠΌ, ΠΊΠ°ΠΊ происходит ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ экрана Π² основном ΠΏΠΎΡ‚ΠΎΠΊΠ΅. Π”Π°Π²Π°ΠΉΡ‚Π΅ посмотрим, ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΏΠΎΡ‚ΠΎΠΊ Π²Π²ΠΎΠ΄Π°.

ΠŸΠΎΡ‚ΠΎΠΊ Π²Π²ΠΎΠ΄Π° 

Если Π½Π΅ ΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ Π΄Π²ΡƒΡ… Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, вСсь ΠΏΠΎΡ‚ΠΎΠΊ Π²Π²ΠΎΠ΄Π° Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Π² Π²ΠΈΠ΄Π΅ ΠΎΠ΄Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Ѐункция MouseThread() ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° Π² листингС 7.5.


Листинг 7.5. Ѐункция MouseThread()

DWORD CursorWin::MouseThread(LPVOID p) {

 TRACE("starting mouse thread\n");

 CursorWin* win=(CursorWin*)p;

 while(TRUE) {

  CMultiLock mlock((CSyncObject**)mouse_event, 2);

  DWORD event=mlock.Lock(INFINITE, FALSE);

  if (event-WAIT_OBJECT_0==quit_event_index)  {

   TRACE("got quit message: quitting mouse thread\n");

   return 0;

  }

  critsection.Lock();

  oldcurx=curx;

  oldcury=cury;

  BOOL buffer_empty=FALSE;

  while (!buffer_empty) {

   DIDEVICEOBJECTDATA data;

   DWORD elements=1;

   if (mouse==0) {

    TRACE("invalid pointer: quitting mouse thread\n");

    return 0;

   }

   HRESULT r=mouse->GetDeviceData(sizeof(data), &data, &elements, 0);

   if (r==DI_OK && elements==1)   {

    static MouseClickData mc;

    switch data.dwOfs) {

    case DIMOFS_X:

     curx+=data.dwData;

     break;

    case DIMOFS_Y:

     cury+=data.dwData;

     break;

    case DIMOFS_BUTTON0:

     if (data.dwData & 0x80) {

      mc.x=curx;

      mc.y=cury;

      mc.button=0;

      mouseclickqueue.AddHead(mc);

     }

     break;

    case DIMOFS_BUTTON1:

     if (data.dwData & 0x80) {

      mc.x=curx;

      mc.y=cury;

      mc.button=1;

      mouseclickqueue.AddHead(mc);

     }

     break;

    }

   } else buffer_empty=TRUE;

  }

  if (curx<0) curx=0;

  if (cury<0) cury=0;

  if (curx>=screen_width-cursor_width) curx=screen_width-cursor_width-1;

  if (cury>=screen_height-cursor_height) cury=screen_height-cursor_height-1;

  if (curx==oldcurx && cury==oldcury) {

   //----- ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ курсора Π½Π΅ трСбуСтся ------

   goto nevermind;

  } else if (abs(curx-oldcurx) >= cursor_width || abs(cury-oldcury) >= cursor_height) {

   //----- простой случай: ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊΠΈ Π½ΠΎΠ²ΠΎΠ³ΠΎ

   // ΠΈ старого курсора Π½Π΅ ΠΏΠ΅Ρ€Π΅ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‚ΡΡ -----

   win->UpdateCursorSimpleCase(curx, cury, oldcurx, oldcury);

  } else {

   //----- слоТный случай: ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊΠΈ Π½ΠΎΠ²ΠΎΠ³ΠΎ

   // ΠΈ старого курсора ΠΏΠ΅Ρ€Π΅ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‚ΡΡ -----

   win->UpdateCursorComplexCase(curx, cury, oldcurx, oldcury);

  }

  nevermind:;

  critsection.Unlock();

 }

 TRACE("leaving mouse thread\n");

 return 0;

};

Ѐункция MouseThread() ΠΈΠΌΠ΅Π΅Ρ‚ ΠΎΠ΄ΠΈΠ½ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ β€” Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΠΎΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ AfxBeginThread() ΠΏΡ€ΠΈ создании ΠΏΠΎΡ‚ΠΎΠΊΠ° (см. листинг 7.3). ΠœΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π»ΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ this, поэтому сСйчас смоТСм ΠΏΡ€ΠΈΡΠ²ΠΎΠΈΡ‚ΡŒ Π΅Π³ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŽ Π½Π° класс CursorWin (пСрСмСнная win). Π’ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ MouseThread() ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ win Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ для доступа ΠΊ Ρ‡Π»Π΅Π½Π°ΠΌ класса CursorWin.

Ѐункция MouseThread() Π² Ρ†ΠΈΠΊΠ»Π΅ выполняСт Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ ΠΏΠΎ Π΄Π²ΡƒΠΌ событиям. Класс CMultiLock позволяСт Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΊΠ°ΠΊ ΠΏΠΎ событиям ΠΎΡ‚ ΠΌΡ‹ΡˆΠΈ, Ρ‚Π°ΠΊ ΠΈ ΠΏΠΎ ΡΠΎΠ±Ρ‹Ρ‚ΠΈΡŽ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΏΠΎΡ‚ΠΎΠΊΠ°. ЀактичСская Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° выполняСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ CMultiLock::Lock(). По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ функция Lock() Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΠΎΡ‚ΠΎΠΊ Π΄ΠΎ установки всСх (Π² Π΄Π°Π½Π½ΠΎΠΌ случаС  - Π΄Π²ΡƒΡ…) Π·Π°Π΄Π°Π½Π½Ρ‹Ρ… событий. ΠœΡ‹ измСняСм это ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ FALSE Π² качСствС Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° Lock(), показывая Ρ‚Π΅ΠΌ самым, Ρ‡Ρ‚ΠΎ функция Π΄ΠΎΠ»ΠΆΠ½Π° ΡΠ½ΠΈΠΌΠ°Ρ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ ΠΏΡ€ΠΈ установкС хотя Π±Ρ‹ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· этих событий.