Чтение онлайн

на главную - закладки

Жанры

Графика для Windows средствами DirectDraw

Трухильо Стэн

Шрифт:

//----- простой случай: прямоугольники нового

// и старого курсора не перекрываются -----

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, показывая тем самым, что функция должна снимать блокировку при установке хотя бы одного из этих событий.

Когда любое из двух событий переходит в установленное состояние, функция Lock завершается, и мы проверяем код возврата. Если выясняется, что было установлено событие завершения потока (обозначенное константой quit_event_index), мы выходим из функции MouseThread, тем самым завершая поток. В противном случае активизация потока вызвана событием мыши, поэтому мы переходим к обработке новых данных.

Однако сначала необходимо захватить критическую секцию с помощью объекта critsection. Для получения данных нам придется обращаться к очереди событий от кнопок мыши и к первичной поверхности, поэтому выполнение этого кода следует синхронизировать с основным потоком.

Мы в цикле получаем данные от объекта DirectInputDevice, представляющего мышь, с помощью функции GetDeviceData. Если получены данные о перемещении мыши, происходит обновление переменных curx и cury. Если получены данные о нажатии кнопок, они заносятся в очередь событий.

Когда цикл получения данных завершается (поскольку в буфере не остается элементов), мы проверяем переменные curx и cury и убеждаемся, что курсор не вышел за пределы экрана (вместо того чтобы писать код частичного отсечения курсора, мы выбираем простой путь и требуем, чтобы курсор всегда полностью оставался на экране).

Наконец, мы проверяем новое положение курсора. Если перемещение курсора не обнаружено, критическая секция освобождается,

а объект CMultiLock снова используется для блокировки по обоим событиям. Если курсор переместился в другое положение, мы вызываем одну из двух функций обновления курсора в зависимости от того, перекрывается ли старая область курсора с новой. Если области перекрываются, вызывается функция UpdateCursorComplexCase; в противном случае вызывается функция UpdateCursorSimpleCase.

Начнем с более простой функции UpdateCursorSimpleCase (см. листинг 7.6).

Листинг 7.6. Функция UpdateCursorSimpleCase

BOOL CursorWin::UpdateCursorSimpleCase(int curx, int cury, int oldcurx, int oldcury) {

 RECT src;

 HRESULT r;

 //------ Блиттинг 1: стирание старого курсора ----------

 r=primsurf->BltFast(oldcurx, oldcury, cursor_under, 0, DDBLTFAST_WAIT);

 if (r!=DD_OK) {

TRACE("Blt 1 failed\n");

CheckResult(r);

 }

 //------ Блиттинг 2: сохранение области под новым курсором ------

 src.left=curx;

 src.top=cury;

 src.right=curx+cursor_width;

 src.bottom=cury+cursor_height;

 r=cursor_under->BltFast(0, 0, primsurf, &src, DDBLTFAST_WAIT);

 if (r!=DD_OK) {

TRACE("Blt 2 failed\n");

CheckResult(r);

 }

 //------ Блиттинг 3: рисование нового курсора ----------

 r=primsurf->BltFast(curx, cury, cursor, 0, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT);

 if (r!=DD_OK) {

TRACE("Blt 3 failed\n");

CheckResult(r);

 }

 return TRUE;

}

С помощью трех последовательных вызовов функции BltFast интерфейса DirectDrawSurface, функция UpdateCursorSimpleCase стирает существующий курсор, сохраняет область под новым курсором и рисует новый курсор.

В UpdateCursorComplexCase функция BltFast вызывается пять раз. Два дополнительных блиттинга предназначены для копирования обновляемой части первичной поверхности на вспомогательную поверхность (cursor_union) и обратно. Функция UpdateCursorComplexCase приведена в листинге 7.7.

Листинг 7.7. Функция UpdateCursorComplexCase

BOOL CursorWin::UpdateCursorComplexCase(int curx, int cury, int oldcurx, int oldcury) {

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

Инвестиго, из медика в маги 2

Рэд Илья
2. Инвестиго
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Инвестиго, из медика в маги 2

Конструктор

Семин Никита
1. Переломный век
Фантастика:
попаданцы
альтернативная история
4.50
рейтинг книги
Конструктор

Блуждающие огни 4

Панченко Андрей Алексеевич
4. Блуждающие огни
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Блуждающие огни 4

Ох уж этот Мин Джин Хо 1

Кронос Александр
1. Мин Джин Хо
Фантастика:
попаданцы
5.00
рейтинг книги
Ох уж этот Мин Джин Хо 1

Черный Маг Императора 11

Герда Александр
11. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Черный Маг Императора 11

Кодекс Крови. Книга ХIV

Борзых М.
14. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХIV

Девочка для Генерала. Книга первая

Кистяева Марина
1. Любовь сильных мира сего
Любовные романы:
остросюжетные любовные романы
эро литература
4.67
рейтинг книги
Девочка для Генерала. Книга первая

Ты не мой Boy 2

Рам Янка
6. Самбисты
Любовные романы:
современные любовные романы
короткие любовные романы
5.00
рейтинг книги
Ты не мой Boy 2

Брачный сезон. Сирота

Свободина Виктория
Любовные романы:
любовно-фантастические романы
7.89
рейтинг книги
Брачный сезон. Сирота

Вор (Журналист-2)

Константинов Андрей Дмитриевич
4. Бандитский Петербург
Детективы:
боевики
8.06
рейтинг книги
Вор (Журналист-2)

Наследник павшего дома. Том IV

Вайс Александр
4. Расколотый мир
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наследник павшего дома. Том IV

Адвокат Империи 2

Карелин Сергей Витальевич
2. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Адвокат Империи 2

Законы Рода. Том 6

Flow Ascold
6. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 6

Барон Дубов 4

Карелин Сергей Витальевич
4. Его Дубейшество
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Барон Дубов 4