- •Лабораторный практикум «Основы разработки приложений 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
Работа 15. Библиотеки динамической компоновки
a. Неявное (статическое) подключение.В этом случаеDLL-библиотека автоматически проецируется на адресное пространство вызывающей программы еще в процессе ее запуска. Создайте проект с именем, например,DLL.IDEдля подготовки выполнимогоDLL-модуля. В окнеTargetTypeукажите тип приложенияDynamicLibrary(.dll). Исключите из проекта файлы .RC и .DEF.
В исходный текст программы DLL-библиотеки включите две прикладные функции-подпрограммы с произвольными именами (например,Func1иFunc2), которые вызовом функцииMessageBox()выводят в окно сообщения различающуюся информацию. Исходный текст библиотеки должен состоять только из этих функций (без функцииWinMain()). В начале программы, как обычно, должны быть описаны прототипы этих функций, в которых перед типом возвращаемого значения следует указать описатель__declspec (dllexport) (заметьте, что этот описатель начинается сдвухсимволов подчеркивания). Включите в текст программы директиву #includeдля подсоединения заголовочного файлаWindows.h.
В результате компиляции и компоновки должны создаться файлы DLL.DLLиDLL.LIB. Удостоверьтесь в этом.Не запускайтеполученный модульDLL.DLL; он предназначен не для самостоятельной работы, а для вызова из программы .EXE.
Создайте второй проект с именем, например, CPP.IDEдля подготовки выполнимого модулявызывающейпрограммы. В окнеTargetTypeэтого проекта укажите, как обычно, тип приложенияApplication(.exe).В состав проекта включите, помимо исходного файлаCPP.CPP, еще и файл библиотеки импортаDLL.LIB, с помощью которой осуществляется поиск и привязка к выполнимому модулю вызываемых в немDLL-библиотек.
В функцию WinMain()вызывающей программы включите сначала вывод в окно сообщения какой-либо информационной строки, чтобы при запуске программы удостовериться, что она начала работать, а затем – вызовы первой и второй функцийDLL-библиотеки. Перед функциейWinMain()опишите прототипы вызываемых функций с описателем__declspec (dllimport).
Откомпилируйте программу CPP.EXE. Запустив программу на выполнение, убедитесь, что она вызывает обе функции созданной вамиDLL-библиотеки. Просмотрите с помощью какого-либо текстового редактора содержимое файла библиотеки импортаDLL.LIBи найдите в нем “декорированные” компоновщиком имена ваших функций. Запишите эти имена, чтобы воспользоваться ими в следующем задании. Для определения “декорированных” имен можно также вызвать утилитуTDUMPв таком формате:
TDUMP имя_dll.DLL имя_dll.MAP.
b. Явное (динамическое) подключение.В этом случае загрузка (а также и выгрузка)DLL-библиотеки осуществляется программой по мере необходимости. Воспользуйтесь созданной в предыдущем задании динамической библиотекойDLL.DLL. Создайте новый проект для подготовки вызывающей программы с именем, например,CPP2.IDE.Не включайтев него библиотеку импорта.Не включайтев него прототипы вызываемых функций. Алгоритм программыCPP2.CPPдолжен содержать следующие элементы:
вывод в окно сообщения информации о запуске программы;
загрузка динамической библиотеки DLL.DLLвызовом функции WindowsLoadLibrary()с сохранением полученного дескриптора;
получение адресов вызываемых из DLL-библиотеки функций с помощью функции WindowsGetProcAddress(). В качестве первого параметра этой функции следует указывать полученный ранее дескриптор загруженной библиотеки, а в качестве второго параметра – найденные в предыдущем задании “декорированные” имена вызываемых функций;
последовательный вызов обеих функций из DLL-библиотеки посредством полученных на предыдущем этапе адресов;
выгрузка библиотеки вызовом функции FreeLibrary().
Откомпилируйте программу CPP.EXE. Запустив программу на выполнение, убедитесь, что внешне она работает так же, как и предыдущая, хотя, возможно, вам удастся заметить задержку при ее выполнении на этапе поиска и загрузкиDLL-библиотеки.
c. Динамическая загрузка с исходными именами вызываемых функций. Поскольку в этом заданииDLL-библиотеку следует создавать не так, как в предыдущих заданиях, откройте новый проект для создания приложения типаDynamicLibrary(.dll). Пусть этот проект носит имя DLL3.IDE. Включите в него имеющийся уже у вас исходный файл DLL3.CPPи, кроме того, файл определения модуля с именемDLL3.DEF. Этот файл будет состоять из трех строк (при наличии вDLL-библиотеке двух функций):
EXPORTS
имя_функции1_в_программе = “декорированное”_имя_функции
имя_функции2_в_программе = “декорированное”_имя_функции
Заново скомпилируйте DLL-библиотеку.
Создайте новый проект для подготовки вызывающей программы (CPP3.IDE). Скопируйте файлCPP2.CPPпод именемCPP3.CPPи исправьте в нем имя загружаемойDLL-библиотеки на новое. Исправьте также “декорированные” имена вызываемых функций на те, которые использовались в исходном файлеDLL-библиотеки. Получите загрузочный модуль основной программы и убедитесь в правильности его работы.