Класс CursorWin
Программа Cursor, как и все остальные программы этой книги, построена на базе структурных классов
DirectDrawWin и
DirectDrawApp. Эти классы остались неизменными, а вся специфика приложения реализуется классом
CursorWin. На практике функциональность курсора мыши, вероятно, следовало бы встроить в структурный класс. И все же для наглядности я объединил код для работы с курсором со специфическим кодом приложения. Класс CursorWin приведен в листинге 7.1.
Листинг 7.1. Класс CursorWin
class CursorWin : public DirectDrawWin { public: CursorWin(); protected: //{{AFX_MSG(CursorWin) afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnDestroy(); afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized); //}}AFX_MSG DECLARE_MESSAGE_MAP() private: int SelectDriver(); int SelectInitialDisplayMode(); BOOL CreateCustomSurfaces(); void DrawScene(); void RestoreSurfaces(); private: BOOL InitMouse(); BOOL InitKeyboard(); BOOL UpdateDelaySurface(); private: //------- Функции потока ввода ------ static DWORD MouseThread(LPVOID); BOOL UpdateCursorSimpleCase(int curx, int cury, int oldcurx, int oldcury); BOOL UpdateCursorComplexCase(int curx, int cury, int oldcurx, int oldcury); private: //------- Данные мыши ------- static LPDIRECTINPUTDEVICE mouse; static CCriticalSection critsection; static CWinThread* mousethread; static CEvent* mouse_event[2]; static int cursor_width; static int cursor_height; static LPDIRECTDRAWSURFACE cursor; static LPDIRECTDRAWSURFACE cursor_under; static LPDIRECTDRAWSURFACE cursor_union; static int curx, cury; static int oldcurx, oldcury; static CList<MouseClickData, MouseClickData> mouseclickqueue; private: //------- Данные приложения ------- LPDIRECTINPUT dinput; LPDIRECTINPUTDEVICE keyboard; LPDIRECTDRAWSURFACE coil[coil_frames]; LPDIRECTDRAWSURFACE dm_surf; int dm_index; DWORD menubarfillcolor; HFONT largefont, smallfont; };
|
Класс
CursorWin объявляет три обработчика сообщений:
OnCreate(), OnDestroy() и
OnActivate(). Функция
OnCreate() инициализирует DirectDraw, DirectInput и поток ввода. Функция
OnDestroy() освобождает интерфейсы DirectX и завершает поток ввода. Функция
OnActivate() обеспечивает захват мыши и клавиатуры на период активности приложения.
Следующие пять функций наследуются от класса
DirectDrawWin:
- SelectDriver()
- SelectInitialDisplayMode()
- CreateCustomSurfaces()
- DrawScene()
- RestoreSurfaces()
Мы достаточно часто видели эти функции в других приложениях и знаем, что они делают, поэтому не будем рассматривать их. Исключением является функция
DrawScene(), которая представляет некоторый интерес, потому что помимо создания нового кадра занимается синхронизацией основного потока с потоком ввода.
Затем объявляются функции
InitMouse() и
InitKeyboard(). Эти функции используются функцией
OnCreate() и отвечают за инициализацию объектов DirectInput, предназначенных для работы с мышью и клавиатурой. Функция
InitKeyboard() совпадает с одноименными функциями программ Qwerty и Smear из
главы 6, поэтому она также не рассматривается. Однако функция
InitMouse() помимо инициализации мыши запускает поток ввода. Вскоре мы рассмотрим эту функцию.
Функция
UpdateDelaySurface() готовит к выводу поверхность меню задержки. Она выводит текст меню и выделяет текущую задержку.
Далее в классе
CursorWin объявляются три функции потока мыши:
- MouseThread()
- UpdateCursorSimpleCase()
- UpdateCursorComplexCase()
Функция
MouseThread() реализует поток ввода. Когда основной поток создает поток ввода, он передает указатель на статическую функцию
MouseThread(). Созданный поток использует эту функцию в качестве точки входа и продолжает выполнять ее до возврата из функции или вызова функции
AfxEndThread(). Функция
MouseThread() обновляет изображение курсора с помощью функций
UpdateCursorSimpleCase() и
UpdateCursorComplexCase().
В оставшейся части класса
CursorWin объявляются две группы переменных. Первая группа относится к работе с мышью. Все эти переменные объявлены статическими, чтобы статическая функция
MouseThread() могла к ним обратиться (а также потому, что доступ к статическим переменным осуществляется чуть быстрее).
Обратите внимание: в число переменных мыши входят объекты классов
CCriticalSection, CEvent и
CWinThread, предназначенные для синхронизации двух потоков нашей программы.
Мы объявляем два указателя на объекты
CEvent — один используется для оповещений DirectInput, а второй сигнализирует о завершении потока.
Вторая группа переменных не относится к работе с мышью. В нее входит массив указателей на интерфейсы
DirectDrawSurface, через которые мы обращаемся к отдельным кадрам анимации спирали.
Содержание Назад Вперед
Forekc.ru
Рефераты, дипломы, курсовые, выпускные и квалификационные работы, диссертации, учебники, учебные пособия, лекции, методические пособия и рекомендации, программы и курсы обучения, публикации из профильных изданий