Lazarus и onKeyPress

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Lazarus и onKeyPress

Сообщение eevee » 29.12.2009 17:59:10

надо: при нажатии на кнопку заменять введенный символ на что то своё

результат: если локаль стоит UTF-8, по заменить символ на UTF-8 просто не представляется возможным... Долго искал обозначение семи байт в UTF8Key, но так и не понял что к чему... Не хочет он вставлять UTF8 русский символ в Memo, хоть тресни...
если локаль koi8-r, то примерно тоже самое, только отследить нажатие русской кнопки проще...

Может у меня просто лыжи не едут? Кто нибудь сталкивался?
eevee
новенький
 
Сообщения: 63
Зарегистрирован: 29.12.2009 17:52:44
Откуда: Саратов

Re: Lazarus и onKeyPress

Сообщение alexs » 29.12.2009 20:37:32

Посмотри onUTF8KeyPress
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Lazarus и onKeyPress

Сообщение eevee » 30.12.2009 09:04:37

Код: Выделить всё
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
новенький
 
Сообщения: 63
Зарегистрирован: 29.12.2009 17:52:44
Откуда: Саратов

Re: Lazarus и onKeyPress

Сообщение Vadim » 30.12.2009 09:54:30

eevee писал(а):оба кода не работают...

Странно... У меня вот этот код работает на ура:
Код: Выделить всё
procedure TForm1.Memo1UTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
begin
  UTF8Key := 'ф';
end;

Может быть Вы не совсем верно выразили свою мысль? Возможно под словом "не работает" Вы имели в виду, что выполнение идёт не так, как Вы задумывали? ;)
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Lazarus и onKeyPress

Сообщение eevee » 30.12.2009 10:02:33

Ну... Возможно ))) Присвоения не просходит вообще.... То есть если написать
Код: Выделить всё
procedure TForm1.Memo1UTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
begin
  UTF8Key := 'g';
end;

то все работает ок, как только присваиваю русскую букву - не работает...

Объясню как не работает...
При присвоении UTF8Key := 'ф'; либо не важно какой русской буквы при нажимании в Memo выводятся нажимаемые символы, а не ожидаемое 'ф'. Если присваиваю что нить латинское, цифры и тд и тп - то при вводе все символы меняются на то, что присваивал...

P.S. OS Linux Gentoo, locale KOI8-R
eevee
новенький
 
Сообщения: 63
Зарегистрирован: 29.12.2009 17:52:44
Откуда: Саратов

Re: Lazarus и onKeyPress

Сообщение Vadim » 30.12.2009 10:19:12

Гм... :)
Если я пишу это:
Код: Выделить всё
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;

то у меня сначала в мемо выводится Ф, а потом та буква, которую я нажал на клавиатуре. :D
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Lazarus и onKeyPress

Сообщение eevee » 30.12.2009 10:22:59

Код: Выделить всё
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;     


Вот ЭТО работает!!!! Но, к сожалению, это только костыли.... Человеческого нифига ничего нет... (((
eevee
новенький
 
Сообщения: 63
Зарегистрирован: 29.12.2009 17:52:44
Откуда: Саратов

Re: Lazarus и onKeyPress

Сообщение eevee » 11.01.2010 13:57:56

Никто ничего путевого пока не нашел?....
eevee
новенький
 
Сообщения: 63
Зарегистрирован: 29.12.2009 17:52:44
Откуда: Саратов

Re: Lazarus и onKeyPress

Сообщение alexs » 11.01.2010 20:49:56

Почитай на википедии статью о кодировках - в частности о 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;

Это для того, чтобы снять выделение в строке ввода, после того как туда перешёл фокус ввода.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Lazarus и onKeyPress

Сообщение eevee » 18.01.2010 10:17:56

Что то плохо понял идею... Можно поподробнее? Мне надо заменять в Memo при нажимании русские буквы на другие русские. Именно при нажатии. То есть нажал кнопку А, в коде сделал замену на Ф и в итоге в Memo напечатается Ф. Вот именно такая реализация не работает
eevee
новенький
 
Сообщения: 63
Зарегистрирован: 29.12.2009 17:52:44
Откуда: Саратов

Re: Lazarus и onKeyPress

Сообщение wavebvg » 18.01.2010 13:44:24

Я бы посоветовал сделать "прослойку" (можно даже вшить её в lcl обработчик), чтобы преобразовывать по ранее описному принципу кириллицу и прочую 2+байтовую фигню к подобающему виду.
wavebvg
постоялец
 
Сообщения: 354
Зарегистрирован: 28.02.2008 04:57:35

Re: Lazarus и onKeyPress

Сообщение Odyssey » 18.01.2010 22:18:47

eevee
У строк в паскале первый байт -- это длина (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; не подавляет нажатую клавишу.
Odyssey
энтузиаст
 
Сообщения: 580
Зарегистрирован: 29.11.2007 17:32:24

Re: Lazarus и onKeyPress

Сообщение eevee » 25.01.2010 10:20:51

Забавно :D
У меня вот такой вот код
Код: Выделить всё
procedure TMainForm.MemoKeyPress(Sender: TObject; var Key: char);
begin
  Key := Utf8ToAnsi('Ф')[1];
end;

Выводит только букву Ф и то при условии, что нажали только ее :D
eevee
новенький
 
Сообщения: 63
Зарегистрирован: 29.12.2009 17:52:44
Откуда: Саратов

Re: Lazarus и onKeyPress

Сообщение swa1 » 25.01.2010 11:24:05

Может дело в том что кроме KeyPress есть еще, KeyDown и KeyUp.
Я сам не так давно занимался подобным, нужно было набирать два первых символа русские....
так вот, очередность событий у них следующая
KeyDown
KeyPress
Печать символа
KeyUp

Именно по этому:
Vadim писал(а):то у меня сначала в мемо выводится Ф, а потом та буква, которую я нажал на клавиатуре. :D

По тому, как по мне, лучше цепляться к самому последнему событию. Вот так примерно будет у тебя для букФы Ф
Код: Выделить всё
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;
Аватара пользователя
swa1
новенький
 
Сообщения: 80
Зарегистрирован: 25.09.2007 11:04:08
Откуда: Ялта

Re: Lazarus и onKeyPress

Сообщение eevee » 25.01.2010 17:41:36

Данный код не работает совсем. Как я писал ранее - дело именно в кривой реализации под linux. Будем ждать улучшений....
eevee
новенький
 
Сообщения: 63
Зарегистрирован: 29.12.2009 17:52:44
Откуда: Саратов

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 39

Рейтинг@Mail.ru