//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
BOOL CreateFlippingSurfaces();
private:
int SelectDriver();
int SelectInitialDisplayMode();
BOOL CreateCustomSurfaces();
void DrawScene();
void RestoreSurfaces();
private:
BOOL InitKeyboard();
BOOL InitMouse();
private:
LPDIRECTINPUT dinput;
LPDIRECTINPUTDEVICE mouse;
LPDIRECTINPUTDEVICE keyboard;
LPDIRECTDRAWSURFACE sphere;
int x, y;
};
В классе объявлены три обработчика:
• OnCreate()
• OnDestroy()
• OnActivate()
Функция OnCreate() инициализирует DirectInput, а также готовит к работе мышь и клавиатуру. Функция OnDestroy() освобождает объекты DirectInput, инициализированные функцией OnCreate(). Функция OnActivate() захватывает клавиатуру в начале работы и при повторной активизации приложения.
Затем следует переопределенная функция DirectDrawWin::CreateFlippingSurfaces(). Нам не нужна переключаемая первичная поверхность, которая по умолчанию предоставляется классом DirectDrawWin, поэтому мы переопределяем эту функцию и создаем первичную поверхность, неспособную к переключению страниц.
Следующие пять функций присутствуют в большинстве наших программ. Внимания среди них заслуживает разве что функция DrawScene (). Она обнаруживает ввод с клавиатуры или от мыши и соответствующим образом обновляет экран.
Затем класс SmearWin объявляет функции InitMouse() и InitKeyboard(). Функция OnCreate() возлагает на них ответственность за инициализацию устройств.
Наконец, мы объявляем несколько переменных. Переменная dinput — указатель на интерфейс DirectInput, она используется для работы с DirectInput после инициализации. Переменные mouse и keyboard указывают на интерфейсы DirectInputDevice, они инициализируются функциями InitMouse() и InitKeyboard() соответственно. Указатель на поверхность sphere и целые переменные x и y предназначены для вывода и позиционирования единственной поверхности приложения.
Функция OnCreate() инициализирует DirectInput, а затем инициализирует мышь и клавиатуру функциями InitMouse() и InitKeyboard(). Она выглядит так:
int SmearWin::OnCreate(LPCREATESTRUCT lpCreateStruct) {
HRESULT r=DirectInputCreate(AfxGetInstanceHandle(), DIRECTINPUT_VERSION, &dinput, 0);
if (r!=DI_OK) {
AfxMessageBox('DirectInputCreate() failed');
return -1;
}
if (InitMouse()==FALSE) return -1;
if (InitKeyboard()==FALSE) return -1;
if (DirectDrawWin::OnCreate(lpCreateStruct) == -1) return -1;
return 0;
}
DirectInput инициализируется функцией DirectInputCreate(). При успешном вызове в переменную dinput заносится указатель на созданный объект DirectInput. Остальные аргументы DirectInputCreate() рассматривались в программе Qwerty.
Затем мы вызываем функции, которые инициализируют мышь и клавиатуру. Они рассматриваются ниже. Функция OnCreate() завершается вызовом версии OnCreate() базового класса, инициализирующим DirectDraw.
Функция InitMouse() (см. листинг 6.5) готовит мышь к работе.
Листинг 6.5. Функция InitMouse()
BOOL SmearWin::InitMouse() {
HRESULT r;
r = dinput->CreateDevice(GUID_SysMouse, &mouse, 0);
if (r!=DI_OK) {
TRACE('CreateDevice(mouse) failed
');
return FALSE;
}
r = mouse->SetDataFormat(&c_dfDIMouse);
if (r!=DI_OK) {
TRACE('mouse->SetDataFormat() failed
');
return FALSE;
}
r = mouse->SetCooperativeLevel(GetSafeHwnd(), DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
if (r!=DI_OK) {
TRACE('mouse->SetCooperativeLevel() failed
');
return FALSE;
}
DIPROPDWORD property;
property.diph.dwSize=sizeof(DIPROPDWORD);
property.diph.dwHeaderSize=sizeof(DIPROPHEADER);
property.diph.dwObj=0;
property.diph.dwHow=DIPH_DEVICE;
property.dwData=64;
r = mouse->SetProperty(DIPROP_BUFFERSIZE, &property.diph);
if (r!=DI_OK) {
TRACE('mouse->SetProperty() failed (buffersize)
');
return FALSE;
}
return TRUE;
}
Функция InitMouse() включает в себя четыре этапа:
1. Создание объекта DirectInputDevice, представляющего мышь.
2. Определение формата данных, получаемых от мыши.
3. Установку уровня кооперации для мыши.
4. Инициализацию буфера данных устройства.
Функция CreateDevice() интерфейса DirectInput (первый этап) создает экземпляр интерфейса DirectInputDevice, представляющего системную мышь: