Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Код виpтуальной клавиши в символ (строку). Как?


Автор: kalexi 1.12.2009, 23:43
Я с помощью GetAsyncKeyState определяю активно нажатую клавишу, точнее ее код. 
Мне нужно перевести ее в текст на активном языке если это тест, цифра или символ, и в название клавиши в ином случае (Ctrl, Enter,...). 
Сделал большой массив со всеми клавишами, но поиск отбирает много процессорного времени, а это плохо хотябы потому, что GetAsyncKeyState не успевает и пропускает некоторые нажатия.

В результате наткнулся на 2 функции: GetKeyNameText и ToAscii

Цитата
Функция GetKeyNameText

Функция GetKeyNameText извлекает строку, которая представляет название клавиши.

Синтаксис
Код
int GetKeyNameText(
    LONG lParam,    // второй параметр сообщения клавиатуры
    LPTSTR lpString,    // адрес буфера с именем клавиши
    int nSize    // максимальная длина строки с именем клавиши
);



Функция ToAscii

Функция ToAscii переводит заданный код виртуальной клавиши и состояние клавиатуры в соответствующий символ или символы Windows. Функция переводит код, используя язык ввода данных и физическую раскладку символов на клавиатуре, идентифицированную данным дескриптором раскладки символов.

Синтаксис
Код
int ToAscii
(
    UINT uVirtKey,    // код виртуальной клавиши
    UINT uScanCode,    // скэн-код
    PBYTE lpKeyState,    // адрес массива состояния клавиши
    LPWORD lpChar,    // буфер для трансляции клавиши
    UINT uFlags    // флажок активного меню
);



Но пока не совсем разобрался как с ними работать, а именно у них присутствует больше параметров, чем у меня данных. Например lParam - я ведь не сообщение принимаю.

Как с ними работать, посоветуйте пожалуйста.

Автор: Snowy 2.12.2009, 12:07
Код
function GetKeyName(Code: Integer): string;
var
  KeyName: array[0..255] of Char;
begin
  result := '';
  Code := MapVirtualKey(Code, 0);
  if Code <> 0 then
    if GetKeyNameText(Code shl 16, KeyName, SizeOf(KeyName)) > 0 then
      Result := KeyName;
end;
Вот только GetAsyncKeyState не определяет активно нажатую клавишу, а определяет - нажата ли конкретная клавиша...

Автор: Snowy 2.12.2009, 12:34
Наверное имелось ввиду что-то вроде этого:
Код
function GetKeys: string;
var
  i, c: integer;
  KeyName: array[0..255] of Char;
  ks:      TKeyboardState;
begin
  Result := '';
  GetKeyboardState(ks); // Берём состояние всех клавиш
  for i := 0 to 128 do // Перебираем клавиши
    if ks[i] and 128 > 0 then // Если в данный момент нажата
    begin
      c := MapVirtualKey(i, 0);
      if GetKeyNameText(c shl 16, KeyName, SizeOf(KeyName)) > 0 then // Получаем имя клавиши
        Result := Result + '+' + KeyName;
    end;
  Result := Copy(Result, 2, Length(result));
end;
Функция вернёт строку со списком нажатых клавиш

Автор: kalexi 2.12.2009, 14:46
Большое спасибо. А как тогда использовать ToAscii?

Автор: Snowy 2.12.2009, 15:27
Цитата(kalexi @  2.12.2009,  14:46 Найти цитируемый пост)
А как тогда использовать ToAscii?
Эта функция для получения печатного символа клавиши (получить то, что будет в поле ввода, при наборе текста)
Код
function GetKey(Code: Integer): Char;
var ks:      TKeyboardState;
begin
  GetKeyboardState(ks);
  ToAscii(Code, Code, ks, PAnsiChar(@result), 0);
end;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)