За разбирачи

2 отговора 213 прегледа
#1

За разбирачи

Пичове, имам много шибан проблем... значи правя едно програмче, което има многоезикова поддръжка... всичко е супер, ама... ето проблема:
Нали знаете някои езици (напр. френски, немски и т.н.) имат някои по-нестандартни символи, най-ве4е букви с чавки (точки, вълнички, удерения и т.н.), като нашето "Й"... въпроса е, че като плясна такъв символ в програмчето и буквата си стои, но в момента, който се запише в базата и чавката изчезва и става обикновена буква... става въпорс за InterBase, без БДЕ, забравих да спомена... чавките се запазват САМО ако Виндовса е пуснат със съответните за езика регионални настройки... тва не ме устройва, щото аз искам да има хем бълграски, хем френски, хем таджикистански... какво ли не пробвах: слагах чар-сет на базата (както и на всяко поле) "уни-код" - не ще... слагах чар-сет за съотвения език - не ще... качвах тука някакви лангуич-драйвери - не ще и не ще, докато не пуснеш Виндовса на тоя език...
Кофти... ако някой е имал подобен проблем и го е решил, моля да сподели...

Отговор
в отговор на Raymond #2

Re: За разбирачи

Не съм разбирач, но...
Това с UNICODE на полетата на базата - добре. Не познавам добре InterBase, зарязах го преди 6-7 години, за сега работя с MS SQL, но поне там това е част от решението.
Втората част от решението е начина по който подаваш данните в InterBase - като String или WideString. Ако си ги подаваш като String - всичко зависи от езиковите настройки. Виж, ако данните ги подаваш като WideString, тогава си независим от езиците. Втората част си има и подробности малки
Може да си работиш с String (предполагам, че и това искаш), но когато подаваш данните към базата, да ги преобръщаш в WideString, взимайки в предвид езика - не използвай директо кастване от типа на:
var
a:String;
b:WideString;
begin
b:= WideString(a);
end;

защото нищо няма да направиш - да, ще имаш WideString, но той ще е базиран отново на локалните настройки на езика.

Използвай функциите по-долу, като подаваш и езика на който е стринга, за Гръцки например

b:=StringToWideStringEx(a, 1253):

function StringToWideStringEx(const S: string; CodePage: Word): WideString;

var
InputLength,
OutputLength: Integer;

begin
InputLength := Length(S);
OutputLength := MultiByteToWideChar(CodePage, 0, PChar(S), InputLength, nil, 0);
SetLength(Result, OutputLength);
MultiByteToWideChar(CodePage, 0, PChar(S), InputLength, PWideChar(Result), OutputLength);
end;

//--------------------------------------------------------------------------------------------------

function WideStringToStringEx(const WS: WideString; CodePage: Word): string;

var
InputLength,
OutputLength: Integer;

begin
InputLength := Length(WS);
OutputLength := WideCharToMultiByte(CodePage, 0, PWideChar(WS), InputLength, nil, 0, nil, nil);
SetLength(Result, OutputLength);
WideCharToMultiByte(CodePage, 0, PWideChar(WS), InputLength, PChar(Result), OutputLength, nil, nil);
end;

Не забравай да видиш дали Windows-а потдържа тази кодова таблица, иначе ще получиш грешка при WideCharToMultiByte и MultiByteToWideChar

Това може да направиш така:

function EnumCodePagesProc(lpCodePageString : pchar ):DWORD; stdcall;
begin
ListBox1.Items.Add(lpCodePageString);
result := 1;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if not EnumSystemCodePages(@EnumCodePagesProc, CP_INSTALLED ) then
ShowMessage(SysErrorMessage(GetLastError));
end;


И накрая, това няма да ти запази стринговете в базата на ФРЕНСКИ, или ТАДЖИКСКИ, но поне се надявам да не липсват точките, вълничките и т.н.

За пълна потдръжка на езика, е малко по-сложно, но се надявам и това да ти свърши работа...

И още нещо в допълнение. Навсякъде където по-горе съм писал "езика", имай в предвид Code Page. А кратък списък на Code Pages, може да намериш тук

Отговор
в отговор на Ивaнчo #3

Re: За разбирачи

Разбирач си, Иванчо, и още как... ще пробвам тия неща, дано стане... мерси много...

Отговор