Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник
Коллекция курьезных вопросов из форумов
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »

OemToChar


dmk ©   (12.10.19 11:52

Всем привет!

Сделал поиск имен файлов в RAR-архивах (информация открытая). Вроде все извлекается, но в корректный Unicode не переводится. Использую OemToChar. Получается такое имя (между цифрами знак вопроса):
0853_POSM_(03-2017)\PDF\Блокнот-каталог (170?230 мм) Листовые материалы v05.pdf.
Пробовал MultiByteToWideChar, но получается тоже самое.
Что может быть не так?


dmk ©   (12.10.19 11:54[1]

Процедура, которая обрабатывает архивы:
procedure TRarForm.OpenFiles(AFiles: TStringArray);
var
 i, K, N: Integer;
 F: TFile64;
 HeadBlock: THeadBlock;
 FHeader: THeaderBlock;
 FHighHeader: THighPackHeader;
 R, BR, PackSize, PassPos: QWord;
 FExt, SP, FName, SubStr: string;
 AName: AnsiString;
 NumFiles, NumFolders: Integer;
 FP: Double;
 Found, ADir, AnyFile: Boolean;
 AddSizeBlock: Boolean;
 HighPackBlock: Boolean;

const
 FAny = '*';
 FAllFiles = '*.*';

label
 Finish;

begin
 // Инициализация
 FStop := False;
 RarMemo.Lines.Clear;
 StopButton.Enabled := True;
 CountLabel.Caption := 'Обработано: 0 из 0';

 // Строка для поиска
 SubStr := StrEdit.Text;
 AnyFile := (SubStr = FAny) or (SubStr = FAllFiles);

 // 1 часть от общего кол-ва архивов
 FP := (1.0 / AFiles.NumItems) * 100.0;

 // По всему списку файлов
 for i := AFiles.Lo to AFiles.Hi do
 begin
   // Имя файла из списка
   FName := AFiles.Get(i);
   FExt := ExtractFileExt(FName);

   // Прогресс
   TotalBar.Progress := Round(i * FP);
   Found := False;

   if (FName <> '') and (FExt = '.rar') then
   begin
     // Создаем объект файл
     F := TFile64.Create;
     F.OpenExisting(FName, fmOpenRead);

     // Разделитель
     SP := '';
     for K := 1 to Length(FName) do SP := SP + '– ';

     // Добавим имя в список
     RarMemo.Lines.Add(FName);
     RarMemo.Lines.Add(SP);

     F.Seek(0); // Начало файла
     NumFiles := 0; // Кол-во файлов в архиве
     NumFolders := 0; // Кол-во папок в архиве

     // Ищем файловый блок ($74)
     repeat
       // Читаем 7 байт
       F.Read(@HeadBlock, SizeOf(HeadBlock), R);
       BR := R; // Всего прочитано из блока

       PackSize := 0;

       // Тип файла - директория
       ADir := (Byte(HeadBlock.HeadFlags) and $E0) = $E0;

       // Если это файловый заголовок
       if (HeadBlock.HeadType = $74) then
       begin
         // Дополнительные блоки в заголовках
         AddSizeBlock := (HeadBlock.HeadFlags and $8000) <> 0;
         HighPackBlock := (HeadBlock.HeadFlags and $100) <> 0;

         // AddSize-блок
         if AddSizeBlock then
         begin
           // Читаем заголовок AddSize
           F.Read(@FHeader, SizeOf(FHeader), R);
           BR := (BR + R); // Всего прочитано из блока

           // HighPack-блок
           if HighPackBlock then
           begin
             F.Read(@FHighHeader, SizeOf(FHighHeader), R);
             BR := (BR + R); // Всего прочитано из блока

             // Размер пропуска HighPack-блок
             PackSize := FHighHeader.HighPackSize * $100000000 + FHeader.PackedSize;
           end
           else
           begin
             // Размер пропуска AddSize-блок
             PackSize := FHeader.PackedSize;
           end;
         end;

         // Выводим только файлы (без папок)
         if (not ADir) then
         begin
           //---------------------------------------------
           // Читаем имя файла
           //---------------------------------------------

           SetLength(AName, FHeader.NameSize);
           SetLength(FName, FHeader.NameSize);

           ZeroMemory(@AName[1], FHeader.NameSize);
           ZeroMemory(@FName[1], FHeader.NameSize * 2);

           F.Read(@AName[1], FHeader.NameSize, R);
           BR := (BR + R); // Прочитано из блока

           //---------------------------------------------
           // Конвертируем имя в Unicode
           //---------------------------------------------

           OemToChar(PAnsiChar(AName), PChar(FName));

           //---------------------------------------------
           // Проверяем условия поиска
           //---------------------------------------------

           if (AnyFile) then
           begin
             RarMemo.Lines.Add(FName);
             Found := True;
           end
           else
           begin
             // Ищем подстроку
             N := Pos(SubStr, FName);

             if (N <> 0) then
             begin
               RarMemo.Lines.Add(FName);
               Found := True;
             end;
           end;
         end;//if (not ADir)

         // Пропустим остаток от заголовка FHeader
         F.Seek(F.Pos + QWord(HeadBlock.HeadSize) - BR);
         // Пропустим упакованный файл после имени файла в заголовке
         F.Seek(F.Pos + PackSize);

         // Кол-во файлов обработано
         if ADir then
           Inc(NumFolders) else
           Inc(NumFiles);

         // Пропустим сообщения
         Application.ProcessMessages;

         // Остановка по требованию
         if FStop then goto Finish;
       end
       else
       begin
         // Прокручиваем остаток из Head-блока
         if (HeadBlock.HeadSize > SizeOf(HeadBlock)) then
         begin
           PassPos := F.Pos + QWord(HeadBlock.HeadSize - SizeOf(HeadBlock));
           if (PassPos < F.Size) then F.Seek(PassPos) else Break;
         end;
       end;

     until (F.Pos >= F.Size);

     // Закроем файл
     F.Free(@F);

     if Found then
     begin
       // Добавим пустую линию
       RarMemo.Lines.Add('');

       // Кол-во элементов в архиве
       RarMemo.Lines.Add('Файлов: ' + IntToStr(NumFiles));
       RarMemo.Lines.Add('Папок: ' + IntToStr(NumFolders));
     end;
   end//if (FName <> '')
   else
   begin
     // Добавим имя в список
     RarMemo.Lines.Add('Неизвестный тип файла: ' + FName);
   end;

   TotalBar.Progress := 100;

   // Добавим 1 линию
   RarMemo.Lines.Add('');

   // Кол-во обработанных файлов
   CountLabel.Caption := 'Обработано: ' + IntToStr(i + 1) + ' из ' + IntToStr(AFiles.NumItems);
 end;//for

Finish:

 StopButton.Enabled := False;

 if FStop then
 begin
   FStop := False;
   F.Free(@F);

   RarMemo.Lines.Add('');
   RarMemo.Lines.Add('Поиск прерван пользователем ...');
 end;

 // Ждем 1/4 секунды
 Sleep(250);
 TotalBar.Progress := 0;
end;


dmk ©   (18.10.19 15:14[2]

Заменить ? на × удалось, а вот вывести в TMemo не удалось.


dmk ©   (18.10.19 15:16[3]

Ибо символ × (U0215) из кодировки UTF8, а TMemo отказывается UTF8 понимать.
В Caption окна выводится нормально, а вот VCL-компоненты вообще не понимают UTF8.


None   (20.10.19 13:59[4]

Как удалось-то?
Кодируйте не в UTF8, а в Unicode-16.


None   (20.10.19 14:03[5]

Ето?: https://unicode-table.com/ru/00D7/


None   (20.10.19 14:04[6]

В самом низу там расписаны вариации...


dmk ©   (20.10.19 21:20[7]

>Кодируйте не в UTF8, а в Unicode-16.
Так и удалось.


версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо