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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Русские символы в OnKeyPress (Delphi 2009) 
:(
    Опции темы
former
Дата 24.5.2009, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


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

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



При обработке события OnKeyPress нет реакции на русские символы. Кто-нибудь сталкивался?
Использую следующий код:
Код

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if (Key in ['A'..'D', 'F'..'Z', 'a'..'d', 'f'..'z', 'А'..'Я', 'а'..'я', 'ё',
              '/','|', '\', '>', '<', '!', '@', '#', '$', '%', '+', '-',
              '^', '&', '*', '(', ')', '=', '_', '?', '"', '№', ';', ':', '{',
              '}', '[', ']', '`', '~', ' ']) then Key:=#0
  else if Key='.' then Key:=',';
end;



--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
Rrader
  Дата 24.5.2009, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

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



Компилятор ведь ругается. Цифры фильтруешь? Так измени код на противоположный, с учетом warning'а


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
Keeper89
Дата 24.5.2009, 13:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



former, у меня реагирует и на кириллицу (не печатает) - (D2007).


--------------------
PM MAIL WWW   Вверх
Rrader
  Дата 24.5.2009, 14:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

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



Keeper89, потому что там Char = AnsiChar. В 2009 получаем:
Цитата

[DCC Warning] Unit1.pas(28): W1050 WideChar reduced to byte char in set expressions.  Consider using 'CharInSet' function in 'SysUtils' unit.



--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
Keeper89
Дата 24.5.2009, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Rrader, пардон, не увидел в теме сообщение версию Delphi. Тогда, действительно, нужно изменить код.


--------------------
PM MAIL WWW   Вверх
former
Дата 24.5.2009, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


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

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



Цитата(Rrader @  24.5.2009,  13:49 Найти цитируемый пост)
Компилятор ведь ругается. Цифры фильтруешь? Так измени код на противоположный, с учетом warning'а 

Компилятор не ругается.
Цитата(Keeper89 @  24.5.2009,  13:56 Найти цитируемый пост)
former, у меня реагирует и на кириллицу (не печатает) - (D2007). 

D2009, поэтому проблема с юникодом.

Rrader, попробовал следующий код, но результата нет
Код

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
var CharSet: set of Char;
begin
  CharSet := ['а', 'б', 'в'];
  //if Key in charSet then Key:=#0;
  if CharInSet(Key,CharSet)=true then Key:=#0;
end;



--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
Rrader
  Дата 24.5.2009, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

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



Хм, AnsiChar(Key) некорректно обрабатывает кириллицу. И по CPU понятно, почему так, и знаю обходные пути, но не знаю, это баг Delphi или нет? Не смог ничего нагуглить. 


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
CodeMonkey
Дата 24.5.2009, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

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



Нет, это не баг, учите матчасть ;)
По-определению множества в Паскале - в нём не может быть больше 256 элементов. Вопрос: ну и как же вы уложите в множество 65536 элементов (WideChar)? А никак. Отсюда следует, что такой вещи как set of WideChar не существует в природе. Откуда снова следует, что в "Key in ['А'..'Я']" равно как и "CharInSet(Key, ['А'..'Я'])" участвует что угодно, кроме WideChar-ов. 
Про множества пора забывать. Использовать их можно только с латиницей, со всем остальным - другие функции (LastDelimiter, Ord, >= и т.п.). См. также.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
former
Дата 24.5.2009, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


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

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



CodeMonkey, вот цитата из твоей ссылки:
Цитата

Sets of Characters

Probably the most common code idiom that will draw the attention of the compiler is the use of characters in sets. In the past, a character was one byte, so holding characters in a set was no problem. But now, Char is declared as a WideChar, and thus cannot be held in a set any longer. So, if you have some code that looks like this:

procedure TDemoForm.Button1Click(Sender: TObject);
var
  C: Char;
begin
  C := Edit1.Text[1];

  if C in ['a'..'z', 'A'..'Z'] then
  begin
   Label1.Caption := 'It is there';
end;
end;

and you compile it, you’ll get a warning that looks something like this:

[DCC Warning] Unit1.pas(40): W1050 WideChar reduced to byte char in set expressions.  Consider using 'CharInSet' function in 'SysUtils' unit.

You can, if you like, leave the code that way – the compiler will “know” what you are trying to do and generate the correct code. However, if you want to get rid of the warning, you can use the new CharInSet function:

  if CharInSet(C, ['a'..'z', 'A'..'Z']) then
  begin
   Label1.Caption := 'It is there';
  end;

The CharInSet function will return a Boolean value, and compile without the compiler warning.


Нет, все таки проблема с кириллицей.

Цитата

со всем остальным - другие функции (LastDelimiter, Ord, >= и т.п.)

 smile 


--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
Rrader
  Дата 24.5.2009, 17:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

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



CodeMonkey, я немного не о том. Понятно, что множество не может быть из WideChar. Я о том, что преобразование AnsiChar('а') дает '0'. Т.е. если в Key идет кириллический символ, то он не может нормально преобразоваться. Вот это баг или нет? smile 

Просто так все работает, если преобразовать магически:
Код

if AnsiString(Key)[1] in ['а', 'б', {etc}] then 
  Key := #0;



--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
former
Дата 24.5.2009, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


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

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



Rrader, спасибо. +


--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
Rrader
  Дата 24.5.2009, 18:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

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



Да не за что. 
Код

procedure TForm1.Button1Click(Sender: TObject);
var
  W: WideChar;
  P: AnsiChar;
begin
  W := WideChar('б');
  P := AnsiChar(W);
  ShowMessage(String(P));
end;

Этот код демонстрирует баг (или фичу smile ). В D2009 получаем на экране символ '1', в других версиях Delphi, как и положено, 'б'. Но в CPU еще не смотрел, ясное дело, там вся суть отражена.

Так...Посмотрел в CPU, одно отличие:
Код

;W := WideChar('б'); - D2009
mov ax, $0431

;.............................................................

;W := WideChar('б'); - D7
mov ax, $00e1

Неудивительно, но как это изменить? Просто интересно.

Это сообщение отредактировал(а) Rrader - 24.5.2009, 18:16


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
Rrader
Дата 24.5.2009, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

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



Вот так можно:
Код

W := WideChar(Chr(Ord('б')));



--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
CodeMonkey
Дата 24.5.2009, 19:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

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



2 Rrader:
Чёрт, к сожалению, сейчас нет возможности погонять (нет Delphi под рукой). 
Вот, кстати, похожий (а может и связанный) случай с Unicode-символами в старых Delphi.

Цитата(former @  24.5.2009,  18:02 Найти цитируемый пост)
Rrader, спасибо. +

Эй, не вздумайте это использовать - это ни разу не решение! Вопрос-наводка: как это будет работать с языком для не-unicode программ <> русского ;)

По поводу решения - я бы в первую очередь прошерстил бы Character.pas - там должна быть куча функций диагностики, я бы поискал что-то вроде IsCharInCategory(Char, Cyrillic) - как я уже сказал, сейчас не могу посмотреть сам.
Далее, если бы это не сработало, я проверил бы по таблице символов, какие коды имеет кирилица в Unicode и обнаружил бы, что они также лежат монолитным диапазоном, как и в Ansi (да, с отдельной "Ё"), поэтому: if (Ord(Char) >= Ord('А')) and (Ord(Char) <= Ord('Я')) then (+ по аналогии на 'а'..'я' и 'Ё', 'ё').
Далее, если с диапазонами было бы плохо (скажем, не кирилицу проверяем), то я бы выписал фильтруемые символы в строку и: if LastDelimiter('абвгдеёжзийклмн...', Char) >= 0 then.

Добавлено через 2 минуты и 46 секунд
Цитата(former @  24.5.2009,  17:30 Найти цитируемый пост)
Нет, все таки проблема с кириллицей.

Сказал же: забудьте про множества. Не будет это работать для не латиницы.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
former
Дата 24.5.2009, 21:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


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

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



Цитата(CodeMonkey @  24.5.2009,  19:14 Найти цитируемый пост)
Эй, не вздумайте это использовать - это ни разу не решение! Вопрос-наводка: как это будет работать с языком для не-unicode программ <> русского ;)

В моем случае исключительно русский. Но, спасибо за совет. К сожалению, сейчс тоже нат среды под рукой. Завтра вечером посмотрю.




--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
Rrader
  Дата 25.5.2009, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

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



Цитата(CodeMonkey @  25.5.2009,  01:14 Найти цитируемый пост)
Вопрос-наводка: как это будет работать с языком для не-unicode программ <> русского ;)

Ясно дело, магия, но в чем тут прикол, а, CodeMonkeysmile Или вы про умляуты имеете в виду всякие?


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
CodeMonkey
Дата 25.5.2009, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

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



Цитата
но в чем тут прикол?

В том, что такая проверка не будет работать корректно.
Вроде как: у, Delphi 2009 - теперь и с поддержкой unicode! А реально мы проверкой "if AnsiString(Key)[1] in ['а', 'б', {etc}] then" убиваем весь хвалёный unicode на корню. 
В этом был смысл моего сообщения: пора забыть про множества и использовать другие механизмы.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Rrader
  Дата 25.5.2009, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

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



Т.е. проблема в том, что мы начинаем городить кривой код-огород. Очень тонко у вас эта мысль прослеживалась.


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
CodeMonkey
Дата 25.5.2009, 15:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

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



Ну не знаю, меня почему-то часто неверно понимают smile
Хотя, по-моему, я ровно это же сказал ещё в первом сообщении.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
former
Дата 25.5.2009, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


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

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



CodeMonkey, используя функции, на которые ты ссылался, 
Код

  //if (Ord(Key)>=Ord('а')) and (Ord(Key)>=Ord('я')) then Key:=#0;
  if LastDelimiter('абвгдеёжзийклмнопрстуфхцчшщъьэюя,./|\@;:"#№%^&?!*()-_=+~`', Key) >= 0 then Key:=#0;

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

Это сообщение отредактировал(а) former - 26.5.2009, 11:22


--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
CodeMonkey
Дата 26.5.2009, 08:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

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



Если писать так, как вы - так конечно...   smile  И даже не только то, что вы хотели ;)
Будьте внимательнее и вдумчивее. Кнопочка F1 ещё полезная есть.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

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

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

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


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

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


 




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


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

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