Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Определение клавиши по её коду, в зависимости от раскладки. 
:(
    Опции темы
CynicRus
Дата 14.4.2013, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 248
Регистрация: 31.5.2012

Репутация: 1
Всего: 5



Приветствую уважаемых форумчан. Пишу средство автоматизации написания скрипта для AutoIt (типа Script writter). Соответственно мне нужно определить, какая именно клавиша была нажата. Код клавиш я ловлю без проблем, но следующим этапом мне нужно определить именно значение этой клавиши по коду. В зависимости от раскладки. Пробую я делать это следующим способом:
Код

function GetCharFromVirtualKeyUnicode (Key : Word;Layout: HKL) : WideString;
var
  WBuff         : array [0..255] of WideChar;
  KeyboardState : TKeyboardState;
  UResult       : Integer;
  PC: array [0..25] of char;

begin
  Result := '';
  GetKeyBoardState (KeyboardState);
  ZeroMemory(@WBuff[0], SizeOf(WBuff));
  UResult := ToUnicodeEx(key, MapVirtualKeyEx(key, 0,Layout), KeyboardState, WBuff, Length(WBuff), 0,Layout);
  if UResult > 0 then
    SetString(Result, WBuff, UResult)
  else if UResult = -1 then
    Result := WBuff;
end;

 но при таком подходе в результате я получаю клавишу в той раскладке, которая была при запуске процедуры. Тоесть если первой была английская раскладка то я получаю:

Код

//Key = t
  KeyDown(84);
  KeyUp(84);
//Key = e
  KeyDown(69);
  KeyUp(69);
//Key = s
  KeyDown(83);
  KeyUp(83);
//Key = t
  KeyDown(84);
  KeyUp(84);


Затем меняю раскладку на русскую, пишу тест и в результате получаю:
Код

//Key = n
  KeyDown(78);
  KeyUp(78);
//Key = t
  KeyDown(84);
  KeyUp(84);
//Key = c
  KeyDown(67);
  KeyUp(67);
//Key = n
  KeyDown(78);
  KeyUp(78);

 вместо тест. Вот собственно вопрос, как же определить какая клавиша была нажата в зависимости от текущей раскладки клавиатуры?

PS:

на всяrий случай приваожу процедуру хука клавиш:
Код

function LowLevelKeyboardProc(nCode: LongInt; wParam: wParam;
  lParam: lParam): Longint; Stdcall;
const
  RPT_WPARAM_DATA = '%s';
  RPT_LPARAM_DATA = '%d';
var
 oHookItem: THookItem;
 iVKey:integer;
 sVKey:string;
 StrResult: String;
 Time,SubTime,PressedTime,Res: integer;
 Layout: HKL;
begin
  Time:=0;SubTime:=0;PressedTime:=0;
  if nCode = HC_ACTION then
    Result := CallNextHookEx(kHook, nCode, WParam, LParam);
  case WParam of
    WM_KEYDOWN: begin StrResult := Format(RPT_WPARAM_DATA, ['']); SubTime:=GetTickCount; end;
    WM_SYSKEYDOWN: begin StrResult := Format(RPT_WPARAM_DATA, ['']); SubTime:=GetTickCount; end;
  end;
  StrResult := Format(RPT_LPARAM_DATA, [PKbdDllHookStruct(LParam)^.vkCode]);
  if (Wparam=WM_KEYUP) or (Wparam=WM_SYSKEYUP) then
   begin
    StrResult:='';
    Time:=GetTickCount;
    PressedTime:=SubTime-Time;
   end;
   sVKey:=StrResult;
  if StrResult<>'' then
   iVKey:=StrToInt(StrResult) //Получаем iVKey нажатой клавиши
  else iVKey:=0;
  if not eq(SVKey,'') and (iVKey<>0) then
    begin
      oHookItem:=Hooks.AddItem;
      oHookItem.ItemType:=false;
      oHookItem.KeyCode:=iVKey;
      Layout:= GetKeyboardLayout(wParam);
      oHookItem.VirtualKey:=GetCharFromVirtualKeyUnicode(iVKey,Layout);
      //oHookItem.VirtualKey:=GetCharFromVirtualKey(iVKey);
     // oHookItem.VirtualKey:=chr(iVKey);
      oHookItem.PressedTime:=PressedTime;
    end;
end;




Это сообщение отредактировал(а) CynicRus - 14.4.2013, 13:00
PM MAIL   Вверх
Beltar
Дата 14.4.2013, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: нет
Всего: 7



Я так понял, ты символьный код ловишь, лучше скан-код клавиши ловить.
http://ru.wikipedia.org/wiki/Скан-код тута и таблица


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
CynicRus
Дата 14.4.2013, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 248
Регистрация: 31.5.2012

Репутация: 1
Всего: 5



Я ловлю и символьный и скан-код. Однако, как я понял из вашего ответа - вы предлагаете ловить скан-код и руками его по таблице переводить, через case of? Я полагаю есть путь значительно проще, средствами ОС без велосипедов.
PM MAIL   Вверх
Beltar
Дата 14.4.2013, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: нет
Всего: 7



Я сам не ловил, но, наверное, есть готовые константы, чтобы таблицу руками не вбивать. Сути проблемы я не понял, нужно именно символы, или клавиши?


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
CynicRus
Дата 14.4.2013, 16:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 248
Регистрация: 31.5.2012

Репутация: 1
Всего: 5



Нужно получить какой именно символ вбил пользователь. В или D - клавиша одна, а символы в зависимости от раскладки разные.
PM MAIL   Вверх
Beltar
Дата 14.4.2013, 21:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: нет
Всего: 7



Т. е. тебе надо узнать раскладку в конкретный момент времени для конкретного приложения?


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
kami
Дата 15.4.2013, 00:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



В свое время делал так:
Код

Layout:=GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow, @ProcessID));


Добавлено через 13 минут и 1 секунду
Кстати,
Цитата(CynicRus @  14.4.2013,  12:58 Найти цитируемый пост)
я получаю клавишу в той раскладке, которая была при запуске процедуры. 

это естественно, т.к. LL-хуки вызываются всегда в контексте "своего" процесса.

Это сообщение отредактировал(а) kami - 15.4.2013, 00:00
PM MAIL WWW   Вверх
TechnoMag
Дата 27.9.2013, 08:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 122
Регистрация: 20.3.2010

Репутация: нет
Всего: нет



PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0830 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.