Инициализация DirectInput

Откройте файл main.cpp и найдите код функции WinMain(). В ней вы найдете обычный код создания объектов Windows, за которым следует код инициализации DirectInput и устройства клавиатуры, выглядящий так:

// Инициализация DirectInput
iResult = iInitDirectInput();
if(iResult != INPUTERROR_SUCCESS) {
MessageBox(hWnd, "DirectInput Error",
"Unable to initialize Direct Input.", MB_ICONERROR);
vCleanup();
exit(1);
}
// Инициализация клавиатуры DI
iResult = iInitKeyboard(hWnd);
if(iResult != INPUTERROR_SUCCESS) {
MessageBox(hWnd, "DirectInput Error",
"Unable to initialize Keyboard.", MB_ICONERROR);
vCleanup();
exit(1);
}

В приведенном выше коде вызываются две функции: iInitDirectInput() и iInitKeyboard(). Вызов первой из них инициализирует главный объект DirectInput, а вызов второй создает устройство клавиатуры.
Функция iInitDirectInput()
Функция iInitDirectInput() — это мое собственное творение и я использую ее для создания главного объекта DirectInput. Код, используемый мной для создания упомянутого объекта должен выглядеть для вас очень знакомым, поскольку я уже описывал его в предыдущем разделе главы. Здесь я привожу полный код функции:

int iInitDirectInput(void)
{
HRESULT hReturn;

// Не пытаться создать Direct Input, если он уже создан
if(!pDI) {
// Создаем объект DInput
if(FAILED(hReturn = DirectInput8Create(
g_hInstance, DIRECTINPUT_VERSION,
IID_IDirectInput8, (VOID**)&pDI, NULL))) {
return(INPUTERROR_NODI);
}
}
else {
return(INPUTERROR_DI_EXISTS);
}
return(INPUTERROR_SUCCESS);
}

В приведенном выше коде я сперва проверяю, существует ли объект DirectInput. Если да, мне не надо создавать еще один объект. В этом случае функция возвращает код ошибки, говорящий вызывающей программе, что объект уже создан.

В следующем блоке кода выполняется вызов функции DirectInput8Create() для создания объекта DirectInput. Как только он будет успешно выполнен, моя функция возвращает WinMain() код успешного завершения. В результате этих действий глобальный указатель pDI будет содержать ссылку на созданный при вызове функции объект DirectInput.

Функция iInitKeyboard()
Теперь, когда у нас есть действующий объект ввода в форме глобального указателя pDI, можно создать интерфейс объекта клавиатуры. Здесь выходит на сцену моя функция iInitKeyboard(). В ней я создаю устройство клавиатуры, устанавливаю буфер клавиатуры, задаю режим доступа, захватываю клавиатуру и получаю раскладку клавиатуры. Вот как выглядит код функции:

int iInitKeyboard(HWND hWnd)
{
HRESULT hReturn = 0;
DIPROPDWORD dipdw;

// Не пытайтесь создать клавиатуру дважды
if(pKeyboard) {
return(INPUTERROR_KEYBOARDEXISTS);
}
// Выход, если не найден интерфейс DirectInput
else if (!pDI) {
return(INPUTERROR_NODI);
}

// Получаем интерфейс устройства системной клавиатуры
if(FAILED(hReturn = pDI->CreateDevice(
GUID_SysKeyboard,
&pKeyboard,
NULL))) {
return(INPUTERROR_NOKEYBOARD);
}

// Создаем буфер для хранения данных клавиатуры
ZeroMemory(&dipdw, sizeof(DIPROPDWORD));
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = KEYBOARD_BUFFERSIZE;

// Устанавливаем размер буфера
if(FAILED(hReturn = pKeyboard->SetProperty(
DIPROP_BUFFERSIZE,
&dipdw.diph))) {
return(INPUTERROR_NOKEYBOARD);
}
// Устанавливаем формат данных клавиатуры
if(FAILED(hReturn = pKeyboard->SetDataFormat(
&c_dfDIKeyboard))) {
return(INPUTERROR_NOKEYBOARD);
}
// Устанавливаем уровень кооперации для монопольного доступа
if(FAILED(hReturn = pKeyboard->SetCooperativeLevel(
hWnd,
DISCL_NONEXCLUSIVE | DISCL_FOREGROUND
))) {
return(INPUTERROR_NOKEYBOARD);
}
// Захватываем устройство клавиатуры
pKeyboard->Acquire();
// Получаем раскладку клавиатуры
g_Layout = GetKeyboardLayout(0);
return(INPUTERROR_SUCCESS);
}

Гм-м — многовато кода для простой инициализации клавиатуры, не так ли? В действительности все не так уж и плохо, если учесть чего мы с помощью этого кода достигнем.

Первая часть кода проверяет не проинициализирован ли уже указатель pKeyboard. Если да, объект клавиатуры уже создан ранее и функция возвращает код ошибки, извещающий нас об этом. В следующей проверке мы убеждаемся, что существует объект ввода pDI. Если инициализация DirectInput не выполнена, нет смысла пытаться создать объект клавиатуры!

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