DirectX Графика в проектах Delphi



Работа с клавиатурой - часть 4


const
SAMPLE_BUFFER_SIZE = 8;

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

procedure TfrmDX.FormCreate(Sender: TObject);
var
hRet : HRESULT;
begin
hRet := OnCreateDevice; // Инициализация устройства
if Failed (hRet) then MessageDlg(DIErrorString(Error), mtError,
[mbAbort], 0);
end;

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

function TfrmDX.ReadBufferedData : HRESULT;
var
didod : Array [0..SAMPLE_BUFFER_SIZE - 1] of TDIDEVICEOBJECTDATA;
dwElements : DWORD;
i : DWORD;
hRet : HRESULT;
s : String;
begin
if DIKeyboard = nil then begin
Result := DI_OK;
Exit
end;
// Считываем данные из буфера
hRet := DIKeyboard.GetDeviceData (SizeOf(TDIDEVICEOBJECTDATA),
@didod, dwElements, 0);
if Failed (hRet) then begin // Восстанавливаем связь
hRet := DIKeyboard.Acquire;
while hRet = DIERR_INPUTLOST do
hRet := DIKeyboard.Acquire;
end;
// Буфер не пустой
if dwElements <> 0 then
for i := 0 to dwElements - 1 do begin
if didod[i].dwData and $80 <> 0 // Клавиша нажата
then s := 'D'
else s := 'U';
Memol.Lines.Add (Format ('Ox%02x%s', [didod[i].dwOfs, s] ) ) ;
if didod[i] .dwOfs = DIK__ESCAPE then Close;
end;
Result := DI_OK; // Нулевое значение, признак успешности
end;

Метод GetDeviceData объекта, ассоциированного с устройством, позволяет осуществить собственно считывание данных из буфера. Смысл первого аргумента прозрачен: это размер структуры, предназначенной для хранения. Второй аргумент - указатель на массив элементов данной структуры. В качестве значения третьего аргумента устанавливается количество считанных из буфера данных. Последний аргумент может быть нулем или константой DIGDD_PEEK (во втором случае буфер не будет очищаться после считывания данных).
Если функция возвращает ненулевое значение, то, скорее всего, потеряна связь с устройством. Тогда необходимо снова установить эту связь, вызвав метод Acquire. В библиотеке Directlnput отсутствуют какие-либо специальные методы восстановления, а устанавливать связь можно сколько угодно раз, т. к. лишние вызовы этой функции игнорируются.
Скан-коды клавиш содержатся в поле dwOfs структуры TDIDEVICEOBJECTDATA, значение поля dwData позволяет узнать, какое событие произошло, нажата ли клавиша или отпущена. Если это значение равно 128, то клавиша опущена. В нашем примере к коду клавиши в этом случае приписывается буква "D", иначе - "U".
Вам не обязательно помнить наизусть коды всех клавиш, можете пользоваться символическими константами. Для примера я показал, как выделить нажатие клавиши <Esc>.
После завершения работы освобождаем устройство и память, занятую объектами:




Содержание  Назад  Вперед