С помощью трех последовательных вызовов функции BltFast интерфейса DirectDrawSurface, функция UpdateCursorSimpleCase стирает существующий курсор, сохраняет область под новым курсором и рисует новый курсор.
В UpdateCursorComplexCase функция BltFast вызывается пять раз. Два дополнительных блиттинга предназначены для копирования обновляемой части первичной поверхности на вспомогательную поверхность (cursor_union) и обратно. Функция UpdateCursorComplexCase приведена в листинге 7.7.
Листинг 7.7. Функция UpdateCursorComplexCase
BOOL CursorWin::UpdateCursorComplexCase(int curx, int cury, int oldcurx, int oldcury) {
RECT src;
HRESULT r;
int unionx=min(curx, oldcurx);
int uniony=min(cury, oldcury);
int unionw=max(curx, oldcurx)-unionx+cursor_width;
int unionh=max(cury, oldcury)-uniony+cursor_height;
Пользуясь одной из этих двух функций, поток ввода обновляет курсор. При этом удается избежать мерцания и разрушения текущего изображения на первичной поверхности.
Завершение приложения
Осталось лишь поговорить о том, как завершается работа приложения. Эта тема неоднократно рассматривалась, и ее можно было бы пропустить, но для программы Cursor она важна из-за наличия дополнительного потока. Мы должны не только послать потоку ввода сигнал о завершении, но и проследить за тем, чтобы поток завершился до уничтожения объекта устройства мыши и поверхностей DirectDraw. В противном случае он может попытаться обратиться к мыши или обновить первичную поверхность после того, как соответствующие объекты перестанут существовать. Функция OnDestroy выглядит так: