- •Лабораторный практикум «Основы разработки приложений Windows» Книга 2
- •Часть 1. Теоретические сведения4
- •Часть 2. Лабораторный практикум73
- •Часть 1 Теоретические сведения
- •1. Основы архитектурЫ защищенного режима Регистры процессора
- •Адресация памяти
- •2. Логические шрифты Создание логических шрифтов
- •Вывод на экран текстовых строк
- •3. Таймеры Windows Организация и обслуживание таймеров
- •Мультимедийные таймеры
- •Измерение интервалов времени
- •Организация периодического процесса
- •Задание однократного интервала времени
- •4. Дочерние окна Создание и использование дочерних окон
- •Окна предопределенных классов в главном окне
- •5. Вывод растровых изображений
- •Процедура вывода растрового изображения
- •Компоновка составных изображений
- •6. Обслуживание файлов в 32-разрядных приложениях Windows
- •Базовые операции с файлами Открытие и создание файла
- •Запись и чтение файла
- •Файлы, проецируемые в память
- •7. Процессы и потоки
- •Создание дочернего процесса
- •Создание дочернего потока
- •Синхронизация потоков Общие характеристики объектов Windows
- •Синхронизация с помощью состояний потока
- •Синхронизация с помощью событий
- •Критические секции и защита данных
- •8. Библиотеки динамической компоновки
- •Часть 2 Лабораторный практикум Работы лабораторного практикума Работа 1. Создание логических шрифтов
- •Работа 2. Таймеры Windows(индивидуальное задание а)
- •Работа 3. Дочернее окно в главном окне приложения
- •Работа 4. Вывод растровых изображений с использованием совместимой памяти
- •Работа 5. Измерение временных характеристик программы с помощью мультимедийного таймера
- •Работа 6. Вывод движущихся изображений с синхронизацией от системного таймера (индивидуальное задание b)
- •Работа 7. Повышение качества движущихся изображений с помощью совместимой памяти
- •Работа 8. Движение изображения по фоновому рисунку
- •Работа 9. Работа с файлами (индивидуальное задание c)
- •Работа 10. Стандартные диалоги Windows для работы с файлами
- •Работа 11. Проецирование файла в память
- •Работа 12. Потоки (индивидуальное задание d)
- •Работа 13. Синхронизация потоков с помощью событий
- •Работа 14. Защита данных с помощью критической секции
- •Работа 15. Библиотеки динамической компоновки
- •Работа 16. Передача параметров в функции dll-библиотек
- •Индивидуальные задания лабораторного практикума
- •Задание c2.Массив записываемых в файл данных должен представлять собой последовательный ряд из 2000 целых четных чисел.
- •Лабораторный практикум «Основы разработки приложений Windows» Книга 2
Файлы, проецируемые в память
Как известно, процессор не может работать с содержимым файла, находящегося на диске, – для обращения к какому-либо участку файла этот участок необходимо сначала прочитать в память. Если же требуется не просто обработать данные из файла, а модифицировать его содержимое, то к операции чтения файла добавляется еще и операция его записи. Поэтому стандартная для 16-разрядных приложений процедура работы с дисковым файлом (в наиболее полном виде, когда требуется модификация файла) включает по меньшей мере четыре этапа:
открытие файла на диске;
чтение требуемого участка файла в созданную заранее программную переменную;
модификация этой программной переменной по заданному алгоритму;
запись модифицированной переменной на то же место в файле на диске.
Обычно работа с файлом требует обращения не к одному его участку, а к нескольким, и тогда перечисленные выше операции приходится выполнять повторно. Во многих случаях, особенно при обслуживании обширных баз данных, программа по ходу своего выполнения запрашивает различные участки файла сотни и тысячи раз, и если эти запросы происходят не упорядоченно, а вразбивку, как это обычно и бывает, то каждое обращение к файлу требует выполнения операций физического чтения или записи, что существенно замедляет скорость выполнения программы, поскольку скорость работы диска в тысячи раз меньше скорости процессора.
Значительно более эффективным было бы чтение всегофайла в оперативную память. В этом случае потребуется только одна операция физического чтения в начале сеанса работы и одна операция физической записи в конце сеанса. Однако такая методика возможна только при работе с файлами относительно небольшого размера.
Windowsпредоставляет для 32-разрядных приложений чрезвычайно удобный механизм работы с файлом, вообще исключающий (с точки зрения программиста) операции физического чтения или записи. Сущность этого механизма, называемого проецированием файла в память, заключается в том, что конкретный файл включается в состав физической памяти, а затем в адресном пространстве приложения резервируется область достаточного размера и часть физической памяти, включающая в себя файл, отображается на эту область. Дальнейшие операции с файлом заменяются операциями с его отображением (проекцией) в адресном пространстве приложения.
Процедура создания и использования проекции файла (рис. 6.1) распадается на несколько этапов:
открытие (или, возможно, создание) файла обычным образом с помощью функции CreateFile();
создание в физической памяти объекта “проекция файла” с помощью функции CreateFileMapping();
выделение в линейном пространстве области адресов для проекции файла и отображение этой области на проекцию файла в физической памяти с помощью функции MapViewOfFile(), которая возвращает указатель на выделенную область;
обращение (чтение или запись) к выделенной области линейных адресов (фактически смещений) посредством указателя, так же, как это выполняется для любых массивных переменных.
Рис. 6.1. Процесс проецирования файла в память
Рассмотрим содержательную часть программы, осуществляющей проецирование файла в память и работу с его проекцией. Будем считать, что файл с именем 1.datсостоит из 1000 чисел типаint(и занимает, следовательно, на диске пространство 4000 байт).
/*Операция открытия существующего файла*/
hFile=CreateFile("1.dat",GENERIC_READ,
0,NULL,OPEN_EXISTING,0,NULL);
/*Создание в памяти объекта "проекция файла"*/
HANDLE hMem=CreateFileMapping
(hFile,NULL,PAGE_READONLY,0,0,NULL);
/*Отображение линейных адресов на проекцию файла */
int* ptr = (int*)MapViewOfFile(hMem,FILE_MAP_READ,0,0,0);
/*Чтение участков файла*/
intx=ptr[0];//Чтение первого данного из файла
inty=ptr[999];//Чтение последнего данного из файла
В приведенном примере файл был открыт только для чтения (параметр GENERIC_READфункцииCreateFile()). Соответственно, такой же атрибут получила проекция файла в физической памяти (параметрPAGE_READONLY), а также и выделенная область линейных адресов (параметрFILE_MAP_READ). Если в проецируемый файл предполагается выполнять запись новых данных, тогда для соответствующих параметров вызываемых функций следует указать значенияGENERIC_READ|GENERIC_WRITE,PAGE_READWRITEиFILE_MAP_ALL_ACCESS.
Файл с данными может состоять из данных любого типа. Поэтому функция MapViewOfFile(), которая должна выполнять свою работу для любых типов данных, возвращает в соответствии со своим прототипом обобщенный указатель типаLPVOID. При использовании возвращаемого этой функцией значения его необходимо преобразовать в указатель на конкретный тип данных, содержащихся в файле. В нашем случае файл заполнен числами типаint, и возвращаемое значение явным образом преобразуется в типint*. Если бы файл был заполнен, например, байтовыми переменными типаcharилиBYTE, то и указатель на проекцию файла следовало получить такого же типа:
BYTE* ptr = (BYTE*)MapViewOfFile(...);
Четвертый и пятый параметры функции CreateFileMapping()позволяют задать размер проекции файла. Указание в качестве параметров нулевых значений заставляет Windows спроецировать весь файл.
Функция MapViewOfFile()позволяет при необходимости получить отображение на линейные адреса любой части файла, для чего следует указать смещение отображения от начала файла (третий и четвертый параметр функции), а также размер отображения (пятый параметр). Если требуется спроецировать весь файл (как в нашем примере), на месте всех этих трех параметров указываются нули.