Вход/Регистрация
Графика DirectX в Delphi
вернуться

Краснов Михаил

Шрифт:

Прежде всего, необходимо указать, задается ли исключительный доступ к устройству или нет (флаги DISCL_EXCLUSIVE и DISCL_NONEXCLUSIVE). В этом примере устанавливаю неисключительный доступ. Для стандартного устройства разница между ними невелика, библиотека Directlnput не может позволить никакому приложению захватить клавиатуру монопольно. Просто эксклюзивный доступ может привести к помехам в работе с устройством других приложений.

Помимо эксклюзивности обязательно необходимо задать активность режима (указать один из флагов DISCL^BACKGROUND или DISCL_FOREGROOND). Первый флаг соответствует режиму, когда приложение имеет доступ к устройству ввода всегда, даже когда не имеет активности. Если вы запустите две копии этой программы, то обе они будут реагировать на нажатие клавиш, и по нажатии клавиши <Esc> завершат работу обе копии.

Следующие действия при инициализации связаны с выбранной схемой получения доступа к данным. Можно использовать данные двух видов: непосредственные (immediate) и буферизованные (buffered).

При работе с клавиатурой по первой схеме приложение периодически опрашивает клавиши, получая данные о каждой из них: нажата она или нет. Вторая схема состоит в том, что приложение считывает буфер, в котором хранятся данные о произошедших со времени последнего опроса событиях связанных с устройством: какие клавиши были нажаты, какие были отпущены.

Наш пример позволяет применить обе схемы, но первоначально настроен на вторую, буферизованную, схему. Для нее надо задать размер буфера, и поэтому используется вспомогательная структура, передающаяся аргументом метода setProperty. Размер буфера мы задаем равным значению константы проекта:

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".

  • Читать дальше
  • 1
  • ...
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: