Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Подпивка до DWORD и string в UNICODE


Автор: Ak47black 1.11.2006, 16:44
Хочю узнать как правильно в дельфи делать aligned on DWORD boundaries и переводить string в UNICODE когда работаешь с файлами.
Изобрел сооственный код который все это делает, но просто интересно как другие подходят к этой проблемме? Изобретают или есть какие-то готовые функции или чтот в этом роде.

Автор: ivan219 1.11.2006, 18:13
А можеш своим кодом поделится???

Автор: Ak47black 1.11.2006, 18:40
Выглядит примерно так 
Код

var
  UniResult: array of Char;
  Zstring: String;
begin
   Zstring:= 'SomeTextToConvert';
   u:= 1;
   SetLength(UniResult,Length(Zstring)*2+2);    
   for e:=1 to Length(Zstring) do
   begin
     UniResult[u]:= UpCase(Zstring[e]);
     Inc(u);
     UniResult[u]:= #0;
     Inc(u);
   end;
   if (Length(UniResult)mod 4)<>0 then 
     SetLength(UniResult,Length(UniResult)+(4-(Length(UniResult) mod 4)));
end;


Автор: Snowy 1.11.2006, 18:53
Ручная перекодировка?
Оригинально smile
Велосипеды снова в моде smile

Автор: Ak47black 1.11.2006, 18:59
 smile  Ага. Когда надо уложиться в малое время без интернета то такое возможно. Snowy Вот я и хочю узнать как это по нормальному сделать

Автор: Quadr0 1.11.2006, 19:07
...

Автор: Guedda 1.11.2006, 19:32
Quadr0, по-моему, код Ak47black немного проще, да и занимает гораздо меньше места... Поэтому за его код не стоит судить, мол, велосипед. Я сам этим методом пользуюсь.

Автор: Snowy 1.11.2006, 19:47
Блин. Винда зачем нам дана?
Вот код, который работает, корректно обходя глюки WideString Delphi7:
Код
function StrToWide(s: string; CodePage: dword = 1251): string;
var d: dword;
begin
  d := MultiByteToWideChar(CodePage, 0, PChar(s), -1, nil, 0);
  if d = 0 then begin
    CodePage := 3;
    d := MultiByteToWideChar(CodePage, 0, PChar(s), -1, nil, 0);
  end;
  SetLength(result, d  * 2 - 1);
  MultiByteToWideChar(CodePage, 0, PChar(s), -1, Pointer(result), d);
end;
Если использовать встроенные средства Delphi, то конечно будет короче. Но глючно.
Этот код должен работать корректно. Правда я не проверял ;) Но должен.
В отличии от дельфи, он пытается сконвертить в указанную нами кодировку, а не в кодировку системы.
Т.к. это не всегда возможно, то я добавил ещё проверку на успешность.
Если не получилось, то конвертить в локаль, установленную через SetThreadLocale (если конечно мы не забыли этого сделать, как я писал в теме про борьбу с ?????). Если мы не указывали, то конвертнётся в системную локаль, как у дельфи по дефолту.

Автор: Quadr0 1.11.2006, 19:47
...

Автор: Ak47black 1.11.2006, 19:48
Спасибо свем кто ответил.
Ситуация мне прояснилась.  smile 

Автор: Guedda 1.11.2006, 19:57
Quadr0, извини, не всмотрелся в код... Думал, что код просто перекодирует строку... А оказывается он файл меняет полностью...  smile 

Автор: Snowy 1.11.2006, 20:03
Нужно будет посмотреть, в Turbo код также глючит, как и в D7 или нет...
Раскопал причину глюка с автоперекодировкой.
Теперь думаю, можно ли это поправить гибко, а не "намертво прибить русский, но чтоб работало"...
Guedda, перекодирока в дельфи пишется в одну строчку - простым приравниванием.
Другое дело, что эта автоперекодировка глючит в нерусских виндах.
Уже не одно копьё на этом сломано smile

Добавлено @ 20:06 
Я дал функцию, которая перекодирует корректно в любых (надеюсь) виндах.
Теперь вот ковыряю в сторону, как дельфи научить делать также при автоконвертации.

Добавлено @ 20:08 
Да, кстати. В
  UniStr := WideString(AnsiStr);
WideString - лишнее.
Достаточно просто прировнять - без приведения.
Код
var
  s: string
  w: WideString;
begin
  s := 'Привет';
  w := s;

Автор: Snowy 1.11.2006, 20:21
Абалдеть.
Глюк не только в дельфи, но и в винде...
Есть над чем поработать...

Добавлено @ 20:24 
Интересно, если любимая нами локаль 1049 вовсе не русская, то тогда чья?
Если верить MSDN'у, то русская.
Но тогда почему с русской локалью ассоциирована кодировка Latin1?

Добавлено @ 20:24 
Зато локаль 1024 русская smile

Автор: Quadr0 1.11.2006, 20:31
...

Автор: Snowy 1.11.2006, 21:11
Да, глюки отсюда.
А под дефолтовой кодировкой понимается кодировка, ассоциированная с локалью треда.
Отсюда и решение (в известном топике) с SetThreadLocale.
Вот только заметил ещё одну бяку.
Русская локаль 1049 (она же $409). Но с ней винда почему-то ассоциирует кодировку 1252 - Latin1.
А вот это уже косяк.
Вот если дельфе вдолбить SystemDefaultCodepage вместо тройки 1251, да добавить SetThreadLocale $409, то всё должно быть Ок.
Но это требует корректировки system.pas, т.к. дефолтная локаль там приватна и не модифицируется извне system.pas

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)