Определения и глобальные переменные
Так как объем нашей книги ограничен, мы решили не приводить по одному примеру приложений на каждый метод работы с файлами (синхронный, асинхронный, отображение файла на память), а совместить все в одном приложении.
Для этого мы сделали три определения, показанных ниже:
#define SYNCHRONOUS_IO 1 // синхронные операции
#define ASYNCHRONOUS_IO 2 // асинхроные операции
#define MEMORYMAPPED_IO 3 // отображение на память
Каждая из этих строк соответствует одному из режимов работы с файлами.
Для того чтобы исходные тексты были оттранслированы для использования нужного вам режима работы с файлами, необходимо определить значение макропеременной FILEOP. Это можно сделать одним из трех способов:
//#define FILEOP SYNCHRONOUS_IO
//#define FILEOP ASYNCHRONOUS_IO
#define FILEOP MEMORYMAPPED_IO
Перед трансляцией исходных текстов приложения вы должны выбрать одну из этих строк, закрыв две другие символами комментария. При этом с помощью операторов условной трансляции, расположенных в исходных текстах приложения, будет выбран нужный вариант исходного текста.
Строка включения файла определений oem2char.h должна расплагаться после строки определения макропеременной FILEOP, так как в этом файле тоже имеются операторы условной трансляции.
В глобальной переменной fConversionType хранится текущий режим преобразования, который можно изменить при помощи диалоговой панели Conversion Options, показанной на рис. 1.3. Сразу после запуска приложения в этой переменной хранится значение OEM_TO_ANSI, в результате чего приложение будет выполнять перекодировку из OEM в ANSI. Функция диалога диалоговой панели Conversion Options может записать в переменную fConversionType значение ANSI_TO_OEM. В результате приложение будет перекодировать текстовые файлы из ANSI в OEM.
Далее в области глобальных переменных определены переменные для хранения идентификаторов файлов hSrcFile, hDstFile, а также буфер cBuf размером 2048 байт:
HANDLE hSrcFile;
#if FILEOP != MEMORYMAPPED_IO
HANDLE hDstFile;
CHAR cBuf[2048];
#endif
В переменной hSrcFile хранится идентификатор исходного файла. Что же касается переменной hDstFile, то она предназначена для хранения идентификатора файла, в который будет записан результат перекодировки. Эта переменная, а также буфер для временного хранения перекодируемых данных cBuf не нужны при работе с использованием отображения файла в память. Поэтому если значение макропеременной FILEOP не равно константе MEMORYMAPPED_IO, строки определения переменной hDstFile и буфера cBuf пропускаются при трансляции исходных текстов приложения.
В начале своей работы приложение DiskInfo получает список имен дисков в виде текстовых строк. Каждая такая строка закрыта двоичным нулем, а последняя - двумя нулевыми байтами. Адрес списка приложение записывает в глобальную переменную lpLogicalDriveStrings.
После получения списка имен приложение сканирует его с целью подсчета количества дисковых устройств. Это количество сохраняется в глобальной переменной nNumDirves.
Далее приложение заказывает память для массива структур типа DISKINFO:
typedef struct tagDISKINFO
{
char szDriveName[10]; // имя диска
UINT nDriveType; // тип диска
char szVolumeName[30]; // имя тома
DWORD dwVolumeSerialNumber; // серийный номер
DWORD dwMaxFileNameLength; // длина имени
DWORD dwFileSystemFlags; // системные флаги
char szFileSystemName[10]; // имя файловой системы
int iImage; // номер пиктограммы
DWORD dwFreeSpace; // свободное пространство
DWORD dwTotalSpace; // общий объем диска
} DISKINFO;
В каждой структуре этого массива будет храниться информация о соответствующем логическом диске, такая, например, как имя и тип диска, имя тома и так далее. В процессе работы приложение будет отображать и обновлять информацию, записанную в массиве.
Адрес массива структур DISKINFO хранится в глобальной переменной pdi.
В глобальном массиве szAppName хранится текстовая строка с названием приложения. Это название будет использовано приложением STIME для поиска главного окна приложения RCLOCK.
В глобальных переменных cxChar и cyChar хранятся метрики шрифта с фиксированной шириной символов, которые будут определены на этапе создания главного окна приложения при обработке сообщения WM_CREATE.
Структура rc типа RECT предназначена для хранения размеров окна рабочего стола.
Буфер szBuf используется для хранения данных, передаваемых из приложения STIME при помощи сообщения WM_COPYDATA.
Помимо всего прочего в области глобальных переменных определен массив szServerAppName, в котором хранится имя приложения RCLOCK. Это имя будет использовано в функции WinMain для поиска главного окна серверного приложения.
Идентификатор главного окна найденного приложения RCLOCK хранится в глобальной переменной hWndServer. Этот идентификатор используется для посылки сообщения WM_COPYDATA функцией SendMessage.
В области глобальных переменных определена структура cd типа COPYDATASTRUCT, которая совместно с глобальным буфером szBuf используется для передачи текстовой строки в приложение RCLOCK.
Кроме того, определен буфер szTerminated, в котором находится строка символов Terminated. Эта строка передается в приложение RCLOCK перед завершением работы приложения STIME.