Lazarus и onKeyPress
Модератор: Модераторы
Lazarus и onKeyPress
надо: при нажатии на кнопку заменять введенный символ на что то своё
результат: если локаль стоит UTF-8, по заменить символ на UTF-8 просто не представляется возможным... Долго искал обозначение семи байт в UTF8Key, но так и не понял что к чему... Не хочет он вставлять UTF8 русский символ в Memo, хоть тресни...
если локаль koi8-r, то примерно тоже самое, только отследить нажатие русской кнопки проще...
Может у меня просто лыжи не едут? Кто нибудь сталкивался?
результат: если локаль стоит UTF-8, по заменить символ на UTF-8 просто не представляется возможным... Долго искал обозначение семи байт в UTF8Key, но так и не понял что к чему... Не хочет он вставлять UTF8 русский символ в Memo, хоть тресни...
если локаль koi8-r, то примерно тоже самое, только отследить нажатие русской кнопки проще...
Может у меня просто лыжи не едут? Кто нибудь сталкивался?
Код: Выделить всё
procedure TForm1.Memo1UTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
begin
UTF8Key := SysToUTF8('ф');
end;
Код: Выделить всё
procedure TForm1.Memo1UTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
begin
UTF8Key := 'ф';
end;
оба кода не работают... если подставляю латинскую букву, символ, цифру - всё ок, если русскую букву, то просто ничего не присваивается...
Добавлено спустя 9 минут 20 секунд:
еще бы как нить узнать значение UTF8Key, что за String[7] такой...
Код: Выделить всё
TUTF8Char = String[7];eevee писал(а):оба кода не работают...
Странно... У меня вот этот код работает на ура:
Код: Выделить всё
procedure TForm1.Memo1UTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
begin
UTF8Key := 'ф';
end;Может быть Вы не совсем верно выразили свою мысль? Возможно под словом "не работает" Вы имели в виду, что выполнение идёт не так, как Вы задумывали?
Ну... Возможно ))) Присвоения не просходит вообще.... То есть если написать
то все работает ок, как только присваиваю русскую букву - не работает...
Объясню как не работает...
При присвоении UTF8Key := 'ф'; либо не важно какой русской буквы при нажимании в Memo выводятся нажимаемые символы, а не ожидаемое 'ф'. Если присваиваю что нить латинское, цифры и тд и тп - то при вводе все символы меняются на то, что присваивал...
P.S. OS Linux Gentoo, locale KOI8-R
Код: Выделить всё
procedure TForm1.Memo1UTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
begin
UTF8Key := 'g';
end;
то все работает ок, как только присваиваю русскую букву - не работает...
Объясню как не работает...
При присвоении UTF8Key := 'ф'; либо не важно какой русской буквы при нажимании в Memo выводятся нажимаемые символы, а не ожидаемое 'ф'. Если присваиваю что нить латинское, цифры и тд и тп - то при вводе все символы меняются на то, что присваивал...
P.S. OS Linux Gentoo, locale KOI8-R
Гм... 
Если я пишу это:
то у меня всё равно выводятся только те буквы, которые я нажимаю на клавиатуре.
А если я пишу это:
то у меня сначала в мемо выводится Ф, а потом та буква, которую я нажал на клавиатуре.
Если я пишу это:
Код: Выделить всё
procedure TForm1.Memo1UTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
begin
UTF8Key := 'g';
end;то у меня всё равно выводятся только те буквы, которые я нажимаю на клавиатуре.
А если я пишу это:
Код: Выделить всё
procedure TForm1.Memo1UTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
begin
UTF8Key := 'Ф';
Memo1.Lines.Add(UTF8Key);
end;то у меня сначала в мемо выводится Ф, а потом та буква, которую я нажал на клавиатуре.
Код: Выделить всё
procedure TForm1.Memo1UTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
var
tempkey: string[7];
begin
//showmessage(inttostr(ord(UTF8Key[0]))+' '+inttostr(ord(UTF8Key[1]))+' '+inttostr(ord(UTF8Key[2]))+' '+inttostr(ord(UTF8Key[3]))+' '+inttostr(ord(UTF8Key[4]))+' '+inttostr(ord(UTF8Key[5]))+' '+inttostr(ord(UTF8Key[6])));
tempkey := UTF8Key;
tempkey[0] := #2;
tempkey[1] := #209;
tempkey[2] := #132;
tempkey[3] := #0;
UTF8Key := tempkey;
end; // 209 132 - это буква ф
// 2 208 186 0 70 6 19 - вот что я вижу при вводе русского символа showmessage'м
как я понял, первый байт отвечает за кодировку:
1 - латиница, цифры, буквы и тд и тп
2 - русские символы
второй байт и третий - содержит 2 байта юникода для кириллицы
четвертый байт - завершающий ввод - 0
пятый и далее - мусор в памяти
при латинском вводе будет что нить наподобие такого: 1 125 0 xxx xxx xxx xxx
Предупреждая вопросы о том, что я может что нить не так понял...
если я нажму 'g' = 1 103 0 0 70 6 19
заменяю второй байт на что нить из латинской кодировки - все работает! Вот что происходит с русским языком - я не знаю...
P.S. До перевода Лазаруса на Юникод проблем не было вообще... Так что учитывая данную ситуацию и то, что Лазарус теперь ничего кроме Юникода не понимает - это просто испортить IDE для Паскаля под *nix и подарок тем, у кого Windows...
Добавлено спустя 4 минуты 25 секунд:
Спасибо за идею!!!!!!!!!!!!!!
Код: Выделить всё
procedure TForm1.Memo1UTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
var
tempkey: string[7];
begin
tempkey := UTF8Key;
UTF8Key := #0;
tempkey[0] := #02;
tempkey[1] := #209;
tempkey[2] := #132;
tempkey[3] := #0;
Memo1.Lines.Add(tempkey);
end;
Вот ЭТО работает!!!! Но, к сожалению, это только костыли.... Человеческого нифига ничего нет... (((
Никто ничего путевого пока не нашел?....
- alexs
- долгожитель
- Сообщения: 4066
- Зарегистрирован: 15.05.2005 23:17:07
- Откуда: г.Ставрополь
- Контактная информация:
Почитай на википедии статью о кодировках - в частности о UTF8 - не нужно будет изобратетать велосипед и разбираться до бата в символах.
Вот тебе кусок реального кода. При нажатии клавиши (если фокус в списке) в строку поиска переносится нажатый символ и фокус переходит в неё-же.
Это для того, чтобы снять выделение в строке ввода, после того как туда перешёл фокус ввода.
Код: Выделить всё
procedure Tp45SprClientsForm.RxDBGrid1UTF8KeyPress(Sender: TObject;
var UTF8Key: TUTF8Char);
begin
if (UTF8Key >='0') then
begin
FindEdit.SetFocus;
FindEdit.Text:=UTF8Key;
FindEdit.SelStart:=1;
UTF8Key:='';
end;
end;
Вот тебе кусок реального кода. При нажатии клавиши (если фокус в списке) в строку поиска переносится нажатый символ и фокус переходит в неё-же.
Код: Выделить всё
FindEdit.SelStart:=1;Это для того, чтобы снять выделение в строке ввода, после того как туда перешёл фокус ввода.
Что то плохо понял идею... Можно поподробнее? Мне надо заменять в Memo при нажимании русские буквы на другие русские. Именно при нажатии. То есть нажал кнопку А, в коде сделал замену на Ф и в итоге в Memo напечатается Ф. Вот именно такая реализация не работает
Я бы посоветовал сделать "прослойку" (можно даже вшить её в lcl обработчик), чтобы преобразовывать по ранее описному принципу кириллицу и прочую 2+байтовую фигню к подобающему виду.
eevee
У строк в паскале первый байт -- это длина (1 для символов из ASCII диапазона, и 2 для кириллицы в UTF-8), остальное это байты собственно символов в UTF-8. С Utf8KeyPress похоже баг, у меня тоже воспроизводится. Под виндой с Memo работает конструкция
Но это по двум причинам: 1) под виндой работает Utf8ToAnsi, потому что ANSI (cp1251) там системная кодировка, и 2) там Memo соглашается принимать ANSI символы в OnKeyPress.
Как этот код будет вести себя в Gentoo с KOI-8R сказать затрудняюсь, лучше попробовать. В крайнем случае посмотреть, какие коды туда приходят при нажатии "кириллических" клавиш -- в KOI8-R или cp1251.
А это будет только добавлять в хвост Memo, для добавления в позицию курсора код нужно усложнять. Хотя у меня на svn версии даже оно не работает, UTF8Key := #0; не подавляет нажатую клавишу.
У строк в паскале первый байт -- это длина (1 для символов из ASCII диапазона, и 2 для кириллицы в UTF-8), остальное это байты собственно символов в UTF-8. С Utf8KeyPress похоже баг, у меня тоже воспроизводится. Под виндой с Memo работает конструкция
Код: Выделить всё
procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: char);
begin
Key := Utf8ToAnsi('ф')[1];
end;
Но это по двум причинам: 1) под виндой работает Utf8ToAnsi, потому что ANSI (cp1251) там системная кодировка, и 2) там Memo соглашается принимать ANSI символы в OnKeyPress.
Как этот код будет вести себя в Gentoo с KOI-8R сказать затрудняюсь, лучше попробовать. В крайнем случае посмотреть, какие коды туда приходят при нажатии "кириллических" клавиш -- в KOI8-R или cp1251.
Код: Выделить всё
procedure TForm1.Memo1UTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
var
tempkey: string[7];
begin
tempkey := UTF8Key;
UTF8Key := #0;
tempkey[0] := #02;
tempkey[1] := #209;
tempkey[2] := #132;
tempkey[3] := #0;
Memo1.Lines.Add(tempkey);
end;А это будет только добавлять в хвост Memo, для добавления в позицию курсора код нужно усложнять. Хотя у меня на svn версии даже оно не работает, UTF8Key := #0; не подавляет нажатую клавишу.
Забавно
У меня вот такой вот код
Выводит только букву Ф и то при условии, что нажали только ее
У меня вот такой вот код
Код: Выделить всё
procedure TMainForm.MemoKeyPress(Sender: TObject; var Key: char);
begin
Key := Utf8ToAnsi('Ф')[1];
end;
Выводит только букву Ф и то при условии, что нажали только ее
Может дело в том что кроме KeyPress есть еще, KeyDown и KeyUp.
Я сам не так давно занимался подобным, нужно было набирать два первых символа русские....
так вот, очередность событий у них следующая
KeyDown
KeyPress
Печать символа
KeyUp
Именно по этому:
По тому, как по мне, лучше цепляться к самому последнему событию. Вот так примерно будет у тебя для букФы Ф
Я сам не так давно занимался подобным, нужно было набирать два первых символа русские....
так вот, очередность событий у них следующая
KeyDown
KeyPress
Печать символа
KeyUp
Именно по этому:
Vadim писал(а):то у меня сначала в мемо выводится Ф, а потом та буква, которую я нажал на клавиатуре.
По тому, как по мне, лучше цепляться к самому последнему событию. Вот так примерно будет у тебя для букФы Ф
Код: Выделить всё
procedure TForm1.Memo1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
var
Str:String;
i:integer;
begin
i:=Memo1.SelStart;
Str:=Memo1.Text;
if (Str<>'') and (Key in [VK_A..VK_Z]) then //обрабатываем только буковки
begin
UTF8Insert( 'Ф', Str,i); //вставляем букФу
UTF8Delete( Str, i+1,1);// удаляем что было
Memo1.Text:=Str;
Memo1.SelStart:=UTF8Length(Str);
end;
end; Данный код не работает совсем. Как я писал ранее - дело именно в кривой реализации под linux. Будем ждать улучшений....
