Операционная система Microsoft Windows 3.1 для программиста -том 2

Файл 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.


Содержание раздела