Вход/Регистрация
Графика для Windows средствами 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) {

  • Читать дальше
  • 1
  • ...
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: