Char w Delphi XE - jak rozpoznać polskie litery (unicode)

0

Mam problem z poniższą procedurą.

procedure EditKeyPress(Sender: TObject; var Key: Char);
begin
  if Key in ['a'..'z','ę','ł'] then else Key := #0;
end;

Procedura działa w D7 ale w XE już nie a to z tego powodu że typ char zajmuje 2 bajty i jest to typ widechar. I teraz jeśli Key = 'ł' to nie rozpoznaje tej literki pośród zdeklarowanych w nawiasach kwadratowych. Jakiś pomysł jak to ugryść?

Próbowałem tak ale też nie działa

  If AnsiUpperCase(Key)[1] in ['ę','ó','ą','ś','ł','ż','ź','ć','ń','Ę','Ó','Ą','Ś','Ł','Ż','Ź','Ć','Ń','0'..'9','a'..'z','A'..'Z','"',' ','-',#13,#8,#2,#22] then else Key:=#0;

Oraz także tak jak w dokumentacji Delphi

var
  charSet: set of AnsiChar;
begin
  charSet := ['ę','ó','ą','ś','ł','ż','ź','ć','ń','Ę','Ó','Ą','Ś','Ł','Ż','Ź','Ć','Ń','0'..'9','a'..'z','A'..'Z','"',' ','-',#13,#8,#2,#22];
  If AnsiChar(Key) in charSet then else Key:=#0;
end;

Rożnica taka że rozpoznaję ł oraz ń ale ś, ć nadal nie rozpoznaje

0

Wszystko dlatego, że polskie znaki diakrytyczne w kodzie ASCII mają inne kody, niż w Unicode; Zobacz pod ten link - http://en.wikipedia.org/wiki/Polish_code_pages - są tam podane heksadecymalne kody znaków diakrytycznych w Unicode (pierwszy wiersz tabelki), które są inne, niż w ASCII;

Na przykład znak Ą - w ASCII ma kod 0xA5, a w Unicode 0x104;

Dodatkowo jeśli kod ten ma być przenośny między różnymi wersjami Delphi, to odpowiednimi dyrektywami możesz sprawdzić wersję kompilatora i jeśli jest stara - wykorzystać stary kod, a jeśli jest nowsza (z Unicode) to wykonać sprawdzenie według kodów Unicode;

PS. Skasowałem poprzednie wywody z posta (szkoda miejsca); Za utrudnienia przepraszam - zamotałem się.

1

Pod starymi i nowymi Delphi nawet bez dyrektyw kompilatora zadziała:

if not ((Key in ['a'..'z']) or (Key = string('ę')[1]) or (Key = string('ł')[1])) then
   Key:= #0;

PS:
Nie pytajcie mnie dlaczego tak jak niżej się skompiluje a NIE działa:

if not (Key in ['a'..'z', string('ę')[1], string('ł')[1]]) then
   Key:= #0;
0

W racja @kAzek - nie pomyślałem, że można wykorzystać do tego rzutowanie; Jednak niepotrzebnie wykorzystujesz do tego typ String, skoro można krócej zapisać z rzutowaniem na Char:

if not (Key in ['a' .. 'z', Char('ę'), Char('ł')]) then
  Key := #0;

i nie będzie problemów z tym, że nie wiadomo czemu nie będzie poprawnie działać :]

2

@furious programming Przykro mi muszę Cię rozczarować to też nie zadziała pod XE5 (i pod innymi Unicode pewnie też a w D7 działa) ale faktycznie można tak jak podałem tylko rzutować od razu na Char czyli:

if not ((Key in ['a'..'z']) or (Key = Char('ę')) or (Key = Char('ł'))) then
   Key:= #0;

Sugerowane przez środowisko użycie funkcji CharInSet jak niżej też NIE działa:

if not CharInSet(Key, ['a' .. 'z', Char('ę'), Char('ł')]) then
    Key := #0;
0

Pytanie brzmi, po co chcesz rozpoznawać polskie litery.
W 100% przypadków, w których chcemy „rozpoznawać polskie litery” tak naprawdę powinno się obsłużyć takie czy inne kodowanie znaków - w pełni - konwertując czy sortując znaki według tego właśnie kodowania i określonych ustawień regionalnych.

Tak więc źle do tematu podchodzisz.

0

Dzięki wam za wszelką pomoc bardzo się przydała.

Azarien Dlaczego źle, a jak mam innym sposobem obsłużyć to co jest np wpisywane do edita? Chyba najprościej wykorzystać zdarzenie

onKeyPress(Sender: TObject; var Key: Char);
0

Też kiedyś walczyłem z problemem CharInSet + polskie znaki i tak wykombinowałem (działa pod Unicode):

function PolskiZnak(Znak: Char): Boolean; //sprawdzenie, czy znak należy do grupy polskich znaków
begin
  result := false;
  case Znak of
   'ą','ę','ć','ł','ń','ó','ś','ź','ż',
   'Ą','Ę','Ć','Ł','Ń','Ó','Ś','Ź','Ż': result := true;
  end;
end;

czyli zamiast:

 
if Key in ['ą','ę','ć','ł',...] then ...
 lub
if CharInSet(Key, ['ą','ę','ć','ł',...]) then ... 

dajesz:

 
if PolskiZnak(Key) then ...
0

Jeśli chcesz sprawdzić w elegancki sposób czy dany znak jest literą w unicode, należy użyć funkcji

function IsLetter(C: Char): Boolean;

z modułu System.Character. Nie jestem pewny czy funkcja i moduł istnieje dla XE (od XE2 na pewno).

1 użytkowników online, w tym zalogowanych: 0, gości: 1