Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / таблица соответствия QWERTY и ЙЦУКЕН / 25 сообщений из 30, страница 1 из 2
21.11.2017, 12:40:49
    #39556733
ЙЦУКЕНQWERTY
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
подскажите простой способ перекодирования символов набранных в "неправильной" раскладке клавиатуры.
например, когда юзер набирает текст глядя на кириллические символы клавы, а раскладка включена EN, а не RU.
и наоборот.
мне в голову приходит только один вариант - сделать константные таблицы и по ним искать соответствующие символы в другой раскладке.
есть ещё способы?
...
Рейтинг: 0 / 0
21.11.2017, 12:58:22
    #39556761
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
...
Рейтинг: 0 / 0
21.11.2017, 13:30:36
    #39556792
ЙЦУКЕНQWERTY
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
wadman https://msdn.microsoft.com/en-us/library/windows/desktop/ms646307.aspx чо-то лыжи не едут :(

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
var
  res: Cardinal;
  KLayout: HKL;
const
  MAPVK_VK_TO_CHAR = 2;
  MAPVK_VK_TO_VSC = 0;
  MAPVK_VK_TO_VSC_EX = 4;
  MAPVK_VSC_TO_VK = 1;
  MAPVK_VSC_TO_VK_EX = 3;
begin
  KLayout := GetKeyboardLayout(0);

  if KLayout = $04090409 then //English
    KLayout := $04190419
  else if KLayout = $04190419 then //Russian
    KLayout := $04090409;

  Res := MapVirtualKeyEx(Ord('Q'), MAPVK_VK_TO_CHAR, KLayout);

  if Res > 0 then
    ShowMessage(Chr(Res));
end;
...
Рейтинг: 0 / 0
21.11.2017, 14:13:36
    #39556849
ЙЦУКЕНQWERTY
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
не фурычит
...
Рейтинг: 0 / 0
21.11.2017, 14:15:34
    #39556852
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
ЙЦУКЕНQWERTY
Код: pascal
1.
2.
3.
4.
 if KLayout = $04090409 then //English
    KLayout := $04190419
  else if KLayout = $04190419 then //Russian
    KLayout := $04090409;


Откуда такие значения?
...
Рейтинг: 0 / 0
21.11.2017, 14:16:09
    #39556856
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
Поставь бряк в этом место и посмотрю на
ЙЦУКЕНQWERTY
Код: pascal
1.
  KLayout := GetKeyboardLayout(0);
...
Рейтинг: 0 / 0
21.11.2017, 14:20:09
    #39556859
LSV
LSV
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
Ставь себе SynEdit. Там есть сабжевая фича. Удобно, чо.
...
Рейтинг: 0 / 0
21.11.2017, 14:20:26
    #39556861
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
ЙЦУКЕНQWERTY,

procedure TForm1.Button1Click(Sender: TObject);
const
CEnglish = $04090409;
CRussian = $04190419;
var
VK: Cardinal;
Scan: Cardinal;
Res: Integer;
LBuf: array[0..3] of Char;
LStates: TKeyboardState;
begin
VK := Ord('Q');
Scan := MapVirtualKey(VK, MAPVK_VK_TO_VSC);
FillChar(LStates[0], Length(LStates) * SizeOf(LStates[0]), 0);
Res := ToUnicodeEx(VK, Scan, LStates, @LBuf[0], Length(LBuf), 0, CRussian);
if Res > 0 then
Msg(LBuf);
Res := ToUnicodeEx(VK, Scan, LStates, @LBuf[0], Length(LBuf), 0, CEnglish);
if Res > 0 then
Msg(LBuf);
end;
...
Рейтинг: 0 / 0
21.11.2017, 14:21:02
    #39556864
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
ЙЦУКЕНQWERTY,

Забыл теги :((

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
procedure TForm1.Button1Click(Sender: TObject);
const
  CEnglish = $04090409;
  CRussian = $04190419;
var
  VK: Cardinal;
  Scan: Cardinal;
  Res: Integer;
  LBuf: array[0..3] of Char;
  LStates: TKeyboardState;
begin
  VK := Ord('Q');
  Scan := MapVirtualKey(VK, MAPVK_VK_TO_VSC);
  FillChar(LStates[0], Length(LStates) * SizeOf(LStates[0]), 0);
  Res := ToUnicodeEx(VK, Scan, LStates, @LBuf[0], Length(LBuf), 0, CRussian);
  if Res > 0 then
    Msg(LBuf);
  Res := ToUnicodeEx(VK, Scan, LStates, @LBuf[0], Length(LBuf), 0, CEnglish);
  if Res > 0 then
    Msg(LBuf);
end;
...
Рейтинг: 0 / 0
21.11.2017, 14:25:59
    #39556869
ЙЦУКЕНQWERTY
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
wadmanПоставь бряк в этом место и посмотрю на
ЙЦУКЕНQWERTY
Код: pascal
1.
  KLayout := GetKeyboardLayout(0);

дык именно так и сделал.
получил $04190419 и $04090409
...
Рейтинг: 0 / 0
21.11.2017, 14:26:09
    #39556870
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
wadmanОткуда такие значения?
Хм... Всегда считал, что $409 достаточно... В ресурсах такой ид, смена локали - аналогично. :)
...
Рейтинг: 0 / 0
21.11.2017, 14:30:15
    #39556881
ЙЦУКЕНQWERTY
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
_Vasilisk_
Код: pascal
1.
2.
3.
...
  Res := ToUnicodeEx(VK, Scan, LStates, @LBuf[0], Length(LBuf), 0, CRussian);
...

у меня делфи не юникодная
...
Рейтинг: 0 / 0
21.11.2017, 14:35:02
    #39556889
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
_Vasilisk_
Код: pascal
1.
ToUnicodeEx


ToAsciiEx тогда
...
Рейтинг: 0 / 0
21.11.2017, 14:38:42
    #39556894
ЙЦУКЕНQWERTY
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
сейчас пощупаем...
...
Рейтинг: 0 / 0
21.11.2017, 14:40:16
    #39556900
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
ЙЦУКЕНQWERTYу меня делфи не юникодная И что? Ну замените
_Vasilisk_
Код: pascal
1.
LBuf: array[0..3] of Char;

на
Код: pascal
1.
LBuf: array[0..3] of WideChar;

Все
...
Рейтинг: 0 / 0
21.11.2017, 14:46:58
    #39556911
ЙЦУКЕНQWERTY
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
заменил ToUnicodeEx на ToAsciiEx.
всё работает!! :)

СПАСИБО, _Vasilisk_ и wadman !
...
Рейтинг: 0 / 0
21.11.2017, 17:21:01
    #39557054
ЙЦУКЕНQWERTY
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
эх, рано радовался...
для кодов {}:"<> кириллические симбионты ХЪЖЭБЮ не находятся.
есть у кого-нить идеи?
код
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
function QwertyToRUS(Ch: Char): Char;
const
  CEnglish = $04090409;
  CRussian = $04190419;
  MAPVK_VK_TO_CHAR = 2;
  MAPVK_VK_TO_VSC = 0;
  MAPVK_VK_TO_VSC_EX = 4;
  MAPVK_VSC_TO_VK = 1;
  MAPVK_VSC_TO_VK_EX = 3;
var
  VK: Cardinal;
  Scan: Cardinal;
  Res: Integer;
  LStates: TKeyboardState;
  isLowerCase: boolean;
begin
  isLowerCase := Ch in ['a'..'z'];

  FillChar(LStates[0], Length(LStates) * SizeOf(LStates[0]), 0);
  VK := Ord(AnsiUpperCase(Ch)[1]);

  Scan := MapVirtualKey(VK, MAPVK_VK_TO_VSC);

  Res := ToAsciiEx(VK, Scan, LStates, @Result, 0, CRussian);

  if Res = 0 then
    Result := Ch
  else if Res < 0 then
    raise Exception.Create('The specified key is a dead key')
  else if Res > 1 then
    raise Exception.Create('The dead-key character (accent or diacritic) stored in the keyboard layout cannot be composed with the specified virtual key to form a single character')
  else if not isLowerCase then
    Result := AnsiUpperCase(Result)[1]
end;

...
Рейтинг: 0 / 0
21.11.2017, 18:27:38
    #39557094
fd00ch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
ЙЦУКЕНQWERTYмне в голову приходит только один вариант - сделать константные таблицы и по ним искать соответствующие символы в другой раскладкенапомни, почему не был выбран этот вариант?))
...
Рейтинг: 0 / 0
21.11.2017, 18:33:46
    #39557098
ЙЦУКЕНQWERTY
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
fd00ch, дык не кошерно же
...
Рейтинг: 0 / 0
21.11.2017, 23:23:36
    #39557215
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
ЙЦУКЕНQWERTYесть у кого-нить идеи?Есть. { это Shift + [ И если скан-код { скорее всего определяется правильно (хотя не факт, нужно смотреть), то в ToAsciiEx передаются в LStates нули. Следовательно ни одна клавиша больше не нажата. А скан код { совпадает со скан кодом [ и соответствует символу х в русской раскладке.

Аналогичную картину Вы увидите при работе с верхним регистром. Попробуйте как-то так
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
function QwertyToRUS(Ch: Char): Char;
const
  CEnglish = $04090409;
  CRussian = $04190419;
  MAPVK_VK_TO_CHAR = 2;
  MAPVK_VK_TO_VSC = 0;
  MAPVK_VK_TO_VSC_EX = 4;
  MAPVK_VSC_TO_VK = 1;
  MAPVK_VSC_TO_VK_EX = 3;
var
  VK: Cardinal;
  Scan: Cardinal;
  Res: Integer;
  LStates: TKeyboardState;
begin
  FillChar(LStates[0], Length(LStates) * SizeOf(LStates[0]), 0);
  VK := Ord(Ch);

  Scan := MapVirtualKey(VK, MAPVK_VK_TO_VSC);

  Res := ToAsciiEx(VK, Scan, LStates, @Result, 0, CEnglish);
  if Res <= 0 then
    raise Exception.Create('Что-то пошло не так');
  if Result <> Ch then begin  // А не нажат ли Shift?
    LStates[VK_SHIFT] := 1;
    Res := ToAsciiEx(VK, Scan, LStates, @Result, 0, CEnglish);
    if Res <= 0 then
      raise Exception.Create('Что-то пошло не так');
    if Result <> Ch then
      raise Exception.Create('Подсунули символ не в английской раскладке');
  end;
  Res := ToAsciiEx(VK, Scan, LStates, @Result, 0, CRussian);

  if Res = 0 then
    Result := Ch
  else if Res < 0 then
    raise Exception.Create('The specified key is a dead key')
  else if Res > 1 then
    raise Exception.Create('The dead-key character (accent or diacritic) stored in the keyboard layout cannot be composed with the specified virtual key to form a single character')
end;
...
Рейтинг: 0 / 0
21.11.2017, 23:27:49
    #39557216
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
А вообще, если Вы работаете не с текстом, а с клавиатурой, то вместо
_Vasilisk_
Код: pascal
1.
FillChar(LStates[0], Length(LStates) * SizeOf(LStates[0]), 0);

пишите
Код: pascal
1.
Win32Check(GetKeyboardState(LStates))

и будет Вам счастье без всяких проверок
...
Рейтинг: 0 / 0
22.11.2017, 12:08:30
    #39557400
ЙЦУКЕНQWERTY
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
_Vasilisk_ЙЦУКЕНQWERTYесть у кого-нить идеи?Есть. { это Shift + [ И если скан-код { скорее всего определяется правильно (хотя не факт, нужно смотреть), то в ToAsciiEx передаются в LStates нули. Следовательно ни одна клавиша больше не нажата. А скан код { совпадает со скан кодом [ и соответствует символу х в русской раскладке.

Аналогичную картину Вы увидите при работе с верхним регистром. Попробуйте как-то так
Код: pascal
1.
2.
3.
4.
5.
...
  if Result <> Ch then begin  // А не нажат ли Shift?
    LStates[VK_SHIFT] := 1;
    Res := ToAsciiEx(VK, Scan, LStates, @Result, 0, CEnglish);
...

во! отличная идея!
СПАСИБИЩЕ!!! :-)
...
Рейтинг: 0 / 0
22.11.2017, 18:03:52
    #39557746
ЙЦУКЕНQWERTY
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
всё оказалось и проще, и совсем не так как предполагалось...

1. массив TKeyboardState в данном контексте не влияет на результат никак.
2. скан-код нафиг не нужен (в данном конкретном случае)
3. нужен КОРРЕКТНЫЙ код виртуальной клавиши (virtual-key code)
4. MapVirtualKey в данном случае не годится, нужно использовать VkKeyScan.

окончательный рабочий вариант функции:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
function QwertyToRUS(Ch: Char): Char;
const
  CEnglish = $0409;
  CRussian = $0419;
var
  VkKey: SmallInt;
  Res: LongInt;
  LStates: TKeyboardState;

  function IsUpperCase(aKeyKode: SmallInt): boolean;
  begin
    Result := (aKeyKode and $100) <> 0;
  end;

begin
  Result := #0;

  VkKey := VkKeyScan(Ch);

  Res := ToAsciiEx(VkKey, 0, LStates, @Result, 0, CRussian);

  if Res = 0 then
    Result := Ch
  else if Res < 0 then
    raise Exception.Create('The specified key is a dead key')
  else if Res > 1 then
    raise Exception.Create('The dead-key character (accent or diacritic) stored in the keyboard layout cannot be composed with the specified virtual key to form a single character')
  else if IsUpperCase(VkKey) then
    Result := AnsiUpperCase(Result)[1];
end;
...
Рейтинг: 0 / 0
22.11.2017, 19:05:34
    #39557795
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
ЙЦУКЕНQWERTY
Код: pascal
1.
Res := ToAsciiEx(VkKey, 0, LStates, @Result, 0, CRussian);

За использование неинициализированной переменной можно сильно отгрести
...
Рейтинг: 0 / 0
22.11.2017, 19:12:09
    #39557799
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
таблица соответствия QWERTY и ЙЦУКЕН
ЙЦУКЕНQWERTY
Код: pascal
1.
2.
 else if IsUpperCase(VkKey) then
    Result := AnsiUpperCase(Result)[1];

Вот же любите вы раскладывать грабли
VkKeyScan functionReturn value

Type: SHORT
If the function succeeds, the low-order byte of the return value contains the virtual-key code and the high-order byte contains the shift state, which can be a combination of the following flag bits.
Return valueDescription1Either SHIFT key is pressed.
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / таблица соответствия QWERTY и ЙЦУКЕН / 25 сообщений из 30, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]