Файл oem3ansi\oem3ansi.cpp
// ---------------------------------------- // Перекодировка текстового файла // из OEM в ANSI с использованием // дополнительной таблицы перекодировки // ----------------------------------------
#define STRICT #include <windows.h>
#include <commdlg.h>
#include <mem.h>
// Прототипы функций HFILE GetSrcFile(void);
HFILE GetDstFile(void);
void Oem3Ansi(HFILE, HFILE);
// Указатель на таблицу перекодировки, // которая будет загружена из ресурсов char far * lpXlatTable;
// ------------------------------- // Функция WinMain // -------------------------------
#pragma argsused int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { HFILE hfSrc, hfDst;
// Положение ресурса в файле HRSRC hResource;
// Идентификатор таблицы перекодировки HGLOBAL hXlatTable;
// Определяем расположение ресурса hResource = FindResource(hInstance, "XlatTable", "XLAT");
// Получаем идентификатор ресурса hXlatTable = LoadResource(hInstance, hResource);
// Фиксируем ресурс в памяти, получая его адрес lpXlatTable = (char far *)LockResource(hXlatTable);
// Если адрес равен NULL, при загрузке или // фиксации ресурса произошла ошибка if(lpXlatTable == NULL) { MessageBox(NULL, "Error", "Resource loading error", MB_OK);
return(-1);
}
// Открываем входной файл. hfSrc = GetSrcFile();
if(!hfSrc) return 0;
// Открываем выходной файл hfDst = GetDstFile();
if(!hfDst) return 0;
// Выполняем перекодировку файла Oem3Ansi(hfSrc, hfDst);
// Закрываем входной и выходной файлы _lclose(hfSrc);
_lclose(hfDst);
UnlockResource(hXlatTable);
FreeResource(hXlatTable);
return 0; }
// ------------------------------- // Функция GetSrcFile // Выбор файла для перекодировки // -------------------------------
HFILE GetSrcFile(void) { OPENFILENAME ofn;
char szFile[256]; char szFileTitle[256]; char szFilter[256] = "Text Files\0*.txt;*.doc\0Any Files\0*.*\0"; HFILE hf;
szFile[0] = '\0'; memset(&ofn, 0, sizeof(OPENFILENAME));
// Инициализируем нужные нам поля ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = NULL; ofn.lpstrFilter = szFilter; ofn.nFilterIndex = 1; ofn.lpstrFile = szFile; ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFileTitle = szFileTitle; ofn.nMaxFileTitle = sizeof(szFileTitle);
ofn.lpstrInitialDir = NULL; ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; // Выбираем входной файл if (GetOpenFileName(&ofn)) { hf = _lopen(ofn.lpstrFile, OF_READ);
return hf; } else return 0; }
// ------------------------------- // Функция GetDstFile // Выбор файла для записи // результата перекодировки // -------------------------------
HFILE GetDstFile(void) { OPENFILENAME ofn;
char szFile[256]; char szFileTitle[256]; char szFilter[256] = "Text Files\0*.txt;*.doc\0Any Files\0*.*\0";
HFILE hf;
szFile[0] = '\0';
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = NULL; ofn.lpstrFilter = szFilter; ofn.nFilterIndex = 1; ofn.lpstrFile = szFile; ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFileTitle = szFileTitle; ofn.nMaxFileTitle = sizeof(szFileTitle);
ofn.lpstrInitialDir = NULL; ofn.Flags = OFN_HIDEREADONLY;
// Выбираем выходной файл if (GetSaveFileName(&ofn)) {
// При необходимости создаем файл hf = _lcreat(ofn.lpstrFile, 0);
return hf; } else return 0; }
// ------------------------------- // Функция Oem3Ansi // Перекодировка файла // -------------------------------
void Oem3Ansi(HFILE hfSrcFile, HFILE hfDstFile) { // Счетчик прочитанных байт int cbRead;
// Буфер для считанных данных BYTE bBuf[2048];
// Читаем в цикле файл и перекодируем его, // записывая результат в другой файл do { // Читаем в буфер 2048 байт из входного файла cbRead = _lread(hfSrcFile, bBuf, 2048);
// Выполняем дополнительную перекодировку // по таблице, загруженной из ресурсов for(int i=0;i < cbRead; i++) { bBuf[i] = lpXlatTable[bBuf[i]]; }
// Перекодируем содержимое буфера // из OEM в ANSI OemToAnsiBuff(bBuf, bBuf, cbRead);
// Сохраняем содержимое буфера в // выходном файле _lwrite(hfDstFile, bBuf, cbRead);
// Завершаем цикл по концу входного файла } while (cbRead != 0);
}
В начале работы приложение ищет и загружает из ресурсов в память дополнительную таблицу перекодировки:
hResource = FindResource(hInstance, "XlatTable", "XLAT");
hXlatTable = LoadResource(hInstance, hResource);
После этого ресурс фиксируется в памяти:
lpXlatTable = (char far *)LockResource(hXlatTable);
Адрес зафиксированного ресурса (таблицы перекодировки) записывается в глобальную переменную lpXlatTable. Если этот адрес равен значению NULL, выводится сообщение об ошибке и работа приложения завершается.
После этого приложение OEM3ANSI открывает входной и выходной файлы и выполняет перекодировку, вызывая функцию Oem3Ansi.
Перед завершением работы приложение расфиксирует и удаляет ресурс из памяти:
UnlockResource(hXlatTable);
FreeResource(hXlatTable);
Функция Oem3Ansi выполняет те же действия, что и функция Oem2Ansi из приложения OEM2ANSI, рассмотренного в предыдущем томе. Дополнительно перед перекодировкой из OEM в ANSI (которую выполняет функция OemToAnsiBuff из программного интерфейса Windows) функция Oem3Ansi в цикле перекодирует прочитанный из файла буфер, пользуясь дополнительной таблицей перекодировки, загруженной из ресурсов:
for(int i=0;i < cbRead; i++) { bBuf[i] = lpXlatTable[bBuf[i]]; } OemToAnsiBuff(bBuf, bBuf, cbRead);
Файл описания ресурсов приложения OEM3ANSI (листинг 1.23) содержит описание единственного ресурса. Тип этого ресурса мы определили сами как XLAT.