powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / таблица соответствия QWERTY и ЙЦУКЕН
25 сообщений из 30, страница 1 из 2
таблица соответствия QWERTY и ЙЦУКЕН
    #39556733
ЙЦУКЕНQWERTY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
подскажите простой способ перекодирования символов набранных в "неправильной" раскладке клавиатуры.
например, когда юзер набирает текст глядя на кириллические символы клавы, а раскладка включена EN, а не RU.
и наоборот.
мне в голову приходит только один вариант - сделать константные таблицы и по ним искать соответствующие символы в другой раскладке.
есть ещё способы?
...
Рейтинг: 0 / 0
таблица соответствия QWERTY и ЙЦУКЕН
    #39556761
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
таблица соответствия QWERTY и ЙЦУКЕН
    #39556792
ЙЦУКЕН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
таблица соответствия QWERTY и ЙЦУКЕН
    #39556849
ЙЦУКЕНQWERTY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
не фурычит
...
Рейтинг: 0 / 0
таблица соответствия QWERTY и ЙЦУКЕН
    #39556852
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЙЦУКЕНQWERTY
Код: pascal
1.
2.
3.
4.
 if KLayout = $04090409 then //English
    KLayout := $04190419
  else if KLayout = $04190419 then //Russian
    KLayout := $04090409;


Откуда такие значения?
...
Рейтинг: 0 / 0
таблица соответствия QWERTY и ЙЦУКЕН
    #39556856
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поставь бряк в этом место и посмотрю на
ЙЦУКЕНQWERTY
Код: pascal
1.
  KLayout := GetKeyboardLayout(0);
...
Рейтинг: 0 / 0
таблица соответствия QWERTY и ЙЦУКЕН
    #39556859
LSV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ставь себе SynEdit. Там есть сабжевая фича. Удобно, чо.
...
Рейтинг: 0 / 0
таблица соответствия QWERTY и ЙЦУКЕН
    #39556861
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЙЦУКЕН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
таблица соответствия QWERTY и ЙЦУКЕН
    #39556864
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЙЦУКЕН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
таблица соответствия QWERTY и ЙЦУКЕН
    #39556869
ЙЦУКЕНQWERTY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
wadmanПоставь бряк в этом место и посмотрю на
ЙЦУКЕНQWERTY
Код: pascal
1.
  KLayout := GetKeyboardLayout(0);

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

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


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

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

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

СПАСИБО, _Vasilisk_ и wadman !
...
Рейтинг: 0 / 0
таблица соответствия QWERTY и ЙЦУКЕН
    #39557054
ЙЦУКЕН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
таблица соответствия QWERTY и ЙЦУКЕН
    #39557094
fd00ch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЙЦУКЕНQWERTYмне в голову приходит только один вариант - сделать константные таблицы и по ним искать соответствующие символы в другой раскладкенапомни, почему не был выбран этот вариант?))
...
Рейтинг: 0 / 0
таблица соответствия QWERTY и ЙЦУКЕН
    #39557098
ЙЦУКЕНQWERTY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
fd00ch, дык не кошерно же
...
Рейтинг: 0 / 0
таблица соответствия QWERTY и ЙЦУКЕН
    #39557215
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЙЦУКЕН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
таблица соответствия QWERTY и ЙЦУКЕН
    #39557216
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вообще, если Вы работаете не с текстом, а с клавиатурой, то вместо
_Vasilisk_
Код: pascal
1.
FillChar(LStates[0], Length(LStates) * SizeOf(LStates[0]), 0);

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

и будет Вам счастье без всяких проверок
...
Рейтинг: 0 / 0
таблица соответствия QWERTY и ЙЦУКЕН
    #39557400
ЙЦУКЕН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
таблица соответствия QWERTY и ЙЦУКЕН
    #39557746
ЙЦУКЕН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
таблица соответствия QWERTY и ЙЦУКЕН
    #39557795
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЙЦУКЕНQWERTY
Код: pascal
1.
Res := ToAsciiEx(VkKey, 0, LStates, @Result, 0, CRussian);

За использование неинициализированной переменной можно сильно отгрести
...
Рейтинг: 0 / 0
таблица соответствия QWERTY и ЙЦУКЕН
    #39557799
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЙЦУКЕН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
25 сообщений из 30, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / таблица соответствия QWERTY и ЙЦУКЕН
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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