10:16 Преобразование форматов текстовых документов. Формат MS DOS | |
Для текстовых документов существуют две совершенно различные кодировки — Windows и MS DOS. Обычно приложения Windows используют, естественно, для текстов кодировку Windows. Но если какие-то файлы должны читаться, например, в Norton Commander или в других приложениях DOS, надо применять кодировку MS DOS. Применение этой кодировки требуется также при разработке консольных приложений Win32. Для взаимного перевода текста в текст DOS и обратно в API Windows предусмотрены две процедуры: CharToOem — перевод в формат DOS, и OemToChar - перевод из формата DOS в «только текст». Они объявлены в модуле Windows. Для VCL Win32 объявления имеют вид:
Обе процедуры принимают два параметра типа PAnsiChar, первый из которых — указатель на строку переводимого текста, а второй — указатель на строку результата перевода. Приведу сначала пример консольного приложения VCL Win32:
Приложение выводит пользователю приглашение: «Привет! Введите свое имя:». Если пользователь в ответ вводит имя, например, «Иванов», то приложение затем печатает текст «Привет, Иванов» и ждет, пока пользователь нажмет клавишу Enter. Если бы приглашение пользователю выводилось простым оператором:
то пользователь увидел бы на экране абракадабру, в которой смог бы узнать только восклицательный знак и двоеточие. Это связано с тем, что консольное приложение работает в окне DOS, в котором символы кириллицы должны задаваться в кодировке MS DOS. Поэтому первый оператор приведенного выше кода переводит функцией CharToOem текст приглашения в эту кодировку. Далее обычной функцией Writeln этот текст выводится на экран. Функция Readln читает введенный пользователем ответ в строку S1. Если бы дальше эту строку надо было бы в какой-то момент выводить на экран, ее перекодировку можно было бы не делать. Но в данном приложении введенный текст надо объединить с текстом «Привет, ». Поэтому строка функцией OemToChar переводится в кодировку Windows, затем объединяется с требуемым текстом и затем переводится в кодировку MS DOS. После этого она может выводиться на экран.
В консольных приложениях VCL .NET никаких сложностей с отображением и чтением русских текстов не возникает. Так что в них нет необходимости использовать функции CharToOem и OemToChar. Приведенное выше приложение в VCL .NET существенно упрощается:
Теперь вернемся к основной теме данного раздела — кодировке документов. Если вы хотите включить в свое приложение VCL Win32 кнопку, осуществляющую перевод загруженного в компонент RichEditl текста из файла в формате DOS в текстовый формат (т.е. перевести абракадабру, которую видит пользователь, в нормальный текст), обработчик щелчка на этой кнопке может быть таким:
В обработчике вводится локальная переменная s типа string. Первый оператор обработчика устанавливает функцией SetLength размер этой строки равным размеру текста в окне RichEditl. Следующий оператор функцией OemToChar переводит текст, записанный в окне RichEditl, в текстовый формат и заносит результат в подготовленную строку s. А последний оператор возвращает эту строку в компонент RichEditl. Конечно, в реальном приложении, возможно, лучше аналогичный код вставить в процедуру открытия файла. Тогда после выбора пользователем файла можно определить, является ли он текстовым, т.е. с расширением ".txt" (способ определения расширения файла вы могли видеть в одном из рассмотренных примеров открывания файла). Если файл оказался с расширением ".txt", можно спросить у пользователя, требуется ли проводить преобразование формата из «текста DOS», и если требуется, то произвести указанные выше преобразования. Выше было рассмотрено преобразование формата текста окна RichEdit в приложениях VCL Win32. В приложениях VCL .NET подобное преобразование производится совершенно иначе. Дело в том, что функции CharToOem и OemToChar в VCL .NET объявлены иначе:
Параметр lpszSrc — это преобразуемая строка, а параметр lpszDst — это построитель строк класса StringBuilder, который воспринимает результат преобразования. Не будем останавливаться на причинах, по которым в обращениях к функциям API Windows в .NET в качестве выходных параметров задается StringBuilder. Для наших целей достаточно знать, что объект StringBuilder надо сначала создать с помощью его конструктора, в который передается размер строки, а после преобразования текста результирующую строку можно прочитать методом ToString. Прежде, чем рассматривать преобразование текста DOS, загруженного в окно RichEdit, надо отметить, что загрузка файла в формате DOS произойдет правильно, только если свойство PlainText окна RichEdit в этот момент установлено в false. Иначе текст загрузится, но его дальнейшее преобразование будет невозможным. Впрочем, по умолчанию PlainText = false. А теперь рассмотрим код, обеспечивающий перевод текста в формате DOS, загруженного в окно RichEdit1, в текстовый формат:
В коде вводится переменная SB класса StringBuilder. Первый выполняемый оператор создает объект SB вызовом его конструктора Create. В конструктор передается размер строки, которую может хранить объект. Этот размер задается как удвоенное число символов текста, поскольку каждый символ занимает 2 байта. Вызов функции OemToChar переводит текст RichEditl.Text и заносит результат в SB. На этом можно было бы закончить перевод и отобразить результат в окне оператором
Если вы это сделаете, то увидите, что текст перевелся и вместо абракадабры в окне появился русский текст. Но не перевелись символы новой строки и возврата каретки, которыми завершается каждая строка текста в окне RichEdit. Вместо них в окне отображаются непечатаемые символы, а разбиение исходного текста на строки пропало. Так что надо заменить эти непечатаемые символы обычными символами новой строки и возврата каретки. А чтобы не проводить эту замену непосредственно в тексте окна, результат перевода исходного текста заносится сначала в переменную S. Для замены символов в коде предусмотрены строковые переменные SCodel и SCode2. В первую из них заносятся символы новой строки и возврата каретки — #13#10. Затем для этой строки вызывается функция OemToChar, и результат переносится в переменную SCode2. Таким образом, в SCode2 создается комбинация символов, в которую переводится функцией OemToChar последовательность символов #13#10. Теперь надо заменить в строке S все вхождения символов SCode2 символами SCodel. Это делается в цикле while. В заключение строка S переносится в текст окна RichEditl. Рассмотрим теперь, как обеспечить возможность сохранения файла в формате текста DOS. Для этого в компонент SaveDialog, используемый при сохранении, можно ввести следующие фильтры: в формате RTF *.rtf только текст *.txt текст DOS *.txt Тогда процедуру сохранения в файле в приложении VCL Win32 можно оформить следующим образом:
Если пользователь в диалоге выбрал фильтр «текст DOS» (третий из указанных фильтров), то длина строки локальной переменной s устанавливается равной длине текста в окне редактирования, в нее читается переведенный с помощью функции CharToOem текст, а затем методами работы с текстовыми файлами строка записывается в указанный пользователем файл. Поскольку функция CharToOem объявлена в VCL .NET, как уже говорилось, иначе, код в приложении VCL .NET должен быть другим. Например, таким:
Если пользователь в диалоге выбрал фильтр "текст DOS", то создается объект SB класса StringBuilder и результат преобразования текста в формат DOS заносится в этот объект. Далее в промежуточной переменной s сохраняется исходный текст окна RichEditl и в это окно заносится преобразованный текст. Он сохраняется методом SaveToFile, после чего текст в окне восстанавливается. | |
|
Всего комментариев: 2 | |
| |