Хлопоты с инициализацией мыши и клавиатуры закончены, теперь можно получать от них данные. Функция DrawScene() (см. листинг 6.6) через указатели mouse и keyboard обращается к обоим устройствам и получает от них данные.
Листинг 6.6. Функция SmearWin::DrawScene()
| void SmearWin::DrawScene() { static char key[256]; keyboard->GetDeviceState( sizeof(key), &key );
if ( key[DIK_ESCAPE] & 0x80 ) PostMessage( WM_CLOSE ); BOOL done=FALSE; while (!done) { DIDEVICEOBJECTDATA data; DWORD elements=1; HRESULT r=mouse->GetDeviceData( sizeof(data), &data, &elements, 0 ); if (r==DI_OK && elements==1) { switch(data.dwOfs) { case DIMOFS_X: x+=data.dwData; break; case DIMOFS_Y: y+=data.dwData; break; } } else if (elements==0) done=TRUE; } BltSurface( primsurf, sphere, x, y, TRUE ); } |
Каждый элемент буфера представлен структурой DIDEVICEOBJECTDATA. Эта структура используется независимо от типа устройства, поэтому ее поля были сделаны универсальными. DirectInput определяет структуру DIDEVICEOBJECTDATA следующим образом:
| typedef struct { DWORD dwOfs; DWORD dwData; DWORD dwTimeStamp; DWORD dwSequence; } DIDEVICEOBJECTDATA, *LPDIDEVICEOBJECTDATA; |
Программа Smear реагирует только на перемещение мыши по осям x и y, поэтому после вызова функции GetDeviceData() поле dwOfs сравнивается с константами DIMOFS_X и DIMOFS_Y.
Поле dwData определяет новые значения осевых координат и кнопок. Поскольку мы используем относительные значения, содержимое этого поля равно смещению по данной оси с момента получения последних данных. Следовательно, оно может быть и отрицательным. Поле dwData используется для обновления переменных x и y.
Поля dwTimeStamp и dwSequence содержат информацию о том, когда произошло данное событие. Поле dwTimeStamp определяет время в миллисекундах (о том, как интерпретируется эта величина, можно подробно узнать в описании функции Win32 GetTickCount()). Поле dwSequence определяет порядок наступления событий. События с меньшими номерами наступили раньше, однако несколько событий могут иметь одинаковые порядковые номера. Например, если мышь или рукоять джойстика смещается по диагонали, события для координат x и y будут иметь одинаковые номера.
Вернемся к функции DrawScene(). Цикл ввода извлекает элементы буфера до тех пор, пока буфер не опустеет. Этот цикл выглядит так:
|
while (!done) { DIDEVICEOBJECTDATA data; DWORD elements=1; HRESULT r=mouse->GetDeviceData( sizeof(data), &data, &elements, 0 ); if (r==DI_OK && elements==1) { switch(data.dwOfs) { case DIMOFS_X: x+=data.dwData; break; case DIMOFS_Y: y+=data.dwData; break; } } else if (elements==0) done=TRUE; } |
|
BltSurface( primsurf, sphere, x, y, TRUE ); |