- •§ 1.2. Основы программирования в ос Windows
- •1.2.1. Принципы взаимодействия ос Windows с прикладными программами
- •1.2.2. Типы данных в Windows
- •1.2.3. Графический и консольный интерфейс
- •1.2.4. Создание элементарного графического окна
- •Int nCmdShow)
- •Общие черты.
- •§ 1.3. Принципы разработки динамических библиотек
- •1.3.1. Основные положения
- •1.3.2. Главная функция DllMain()
- •If(bAll WentWell)
- •1.3.3. Экспортирование функций из dll
- •Int sharedInts[10] ;
1.2.1. Принципы взаимодействия ос Windows с прикладными программами
Благодаря интерфейсу вызова функций в Windows доступ к системным ресурсам осуществляется через целый рад системных функций. Совокупность таких функций называется прикладным программным интерфейсом, или API (Application Programming In-terfase). Для взаимодействия с Windows приложение запрашивает функции API, с помощью которых реализуются все необходимые системные действия, такие как выделение памяти, вывод на экран, создание окон и т.п.
Поскольку API состоит из большого числа функций, может сложиться впечатление, что при компиляции каждой программы, написанной для Windows, к ней подключается код довольно значительного объема. В действительности это не так. Функции API содержатся в библиотеках динамической загрузки (Dynamic Link Libraries, или DLL), которые загружаются в память только в тот момент, когда к ним происходит обращение, т.е. при выполнении программы. Рассмотрим, как осуществляется механизм динамической загрузки.
Динамическая загрузка обеспечивает ряд существенных преимуществ.
Во-первых, поскольку практически все программы используют API-функции, то благодаря DLL-библиотекам существенно экономится дисковое пространство, которое в противном случае занималось бы большим количеством повторяющегося кода, содержащегося в каждом из исполняемых файлов.
Во-вторых, изменения и улучшения в Windows-приложениях сводятся к обновлению только содержимого DLL-библиотек. Уже существующие тексты программ не требуют перекомпиляции.
В настоящее время наибольшее распространение получила версия API, которая получила название Win32. Данная версия API пришла на смену версии Win16, используемой в Windows 3.1. Фактически 32-разрядная Win32, используемая в операционных системах 9x, является надмножеством для Win16 (т.е. фактически включает в себя этот интерфейс), так как большинство функций имеет то же название и применяется аналогичным образом. Однако, будучи в принципе похожими, оба интерфейса все же отличаются друг от друга. Win32 поддерживает 32-разрядную линейную адресацию, тогда как Win16 работает только с 16-разрядной сегментированной моделью памяти. Это привело к тому, что некоторые функции были модифицированы таким образом, чтобы принимать 32-разрядные аргументы и возвращать 32-разрядные значения. Часть из них пришлось изменить с учетом 32-разрядной архитектуры. Была реализована поддержка потоковой многозадачности, новых элементов интерфейса и прочих нововведений Windows.
Так как Win32 поддерживает полностью 32-разрядную адресацию, то логично, что целые типы данных (intergers) также объявлены 32-разрядными. Это означает, что переменные типа int и unsigned будут иметь длину 32 бита, а не 16, как в Windows 3.1. Если же необходимо использовать переменную или константу длиной 16 бит, они должны быть объявлены как short (далее будет показано, что для этих типов определены независимые typedef-имена.). Следовательно, при переносе программного кода из 16-разрядной среды необходимо убедиться в правильности использования целочисленных элементов, которые автоматически будут расширены до 32 битов, что может привести к появлению побочных эффектов.
Другим следствием 32-разрядной адресации является то, что указатели больше не нужно объявлять как near и far. Любой указатель может получить доступ к любому участку памяти. В Windows 9x константы near и far объявлены (с помощью директивы #define) пустыми.
Существенные изменения коснулись также функций API, которые работают с символьными строками. Внутренние механизмы Windows 9x (не полностью), NT и Windows 2000 используют символы в формате UNICODE (16-битное значение символов). Но многие прикладные программы продолжают использовать ANSI (то есть стандарт, в ко-тором каждый символ кодируется при помощи 8 бит). Чтобы решить эту проблему, каждая функция, работающая со строками, реализована в двух вариантах. В первом варианте в качестве аргумента воспринимается строка в формате ANSI (внутри функции эта строка автоматически преобразуется в UNICODE). Второй вариант функции напрямую работает со строками в формате UNICODE.
Одним из подмножеств API является GDI (Graphics Device Interfase – интерфейс графического устройства). GDI – это та часть Windows, которая обеспечивает поддержку аппаратно-независимой графики. Благодаря функциям GDI Windows-приложение может выполняться на различных ПЭВМ.
Еще одной особенность Windows является многозадачность, причем поддерживается два типа многозадачности: основанная на процессах и основанная на потоках. Далее идеология многозадачности будет рассмотрена более подробно.
Во многих операционных системах взаимодействие между системой и программой инициализирует программа. Например, в DOS программа запрашивает разрешение на ввод и вывод данных. Говоря другими словами, не- Windows-программы сами вызывают операционную систему. Обратного процесса не происходит. В Windows все совершенно наоборот: именно система вызывает программу. Это осуществляется следующим образом: программа ожидает получения сообщения от Windows. Когда это происходит, то выполняется некоторое действие. После его завершения программа ожидает следующего сообщения.
Windows может посылать программе сообщения множества различных типов. Например, каждый раз при щелчке мышью в окне активной программы посылается соответствующее сообщение. Другой тип сообщений посылается, когда необходимо обновить содержимое активного окна. Сообщения посылаются также при нажатии клавиши, если программа ожидает ввода с клавиатуры. Необходимо запомнить одно: по отношению к программе сообщения появляются случайным образом. Вот почему Windows-программы похожи на программы обработки прерываний: невозможно предсказать, ка-кое сообщение появиться в следующий момент.
Функция окна. Все Windows-программы должны содержать специальную функцию, которая не используется в самой программе, но вызывается самой операционной системой. Эту функцию обычно называют функцией окна, или процедурой окна. Она вызывается Windows, когда системе необходимо передать сообщение в программу. Именно через нее осуществляется взаимодействие между программой и системой. Функция окна передает сообщение в своих аргументах. Согласно терминологии Windows, функции, вызываемые системой, называются функциями обратного вызова. Таким образом, функция окна является функцией обратного вызова. Помимо принятия сообщения от Windows, функция окна должна вызывать выполнение действия, указанного в сообщении. Конечно, программа не обязана отвечать на все сообщения, посылаемые Windows. Поскольку их могут быть сотни, то большинство сообщений обычно обрабатывается самой системой, а программе достаточно поручить Windows выполнить действия, предусмотренные по умолчанию.
Цикл сообщений. Как объяснялось выше, Windows взаимодействует с программой, посылая ей сообщения. Все приложения Windows должны организовать так называемый цикл сообщений. В этом цикле каждое необработанное сообщение должно быть извлечено из очереди сообщений данного приложения и передано назад в Windows, которая затем вызывает функцию окна программы с данным сообщением в качестве аргумента.
Класс окна. Как будет показано далее, каждое окно в Windows-приложении характеризуется определенными атрибутами, называемыми классом окна. (Здесь понятие “класс” не идентично используемому в С++. Оно, скорее, означает стиль или тип.) В традиционной программе класс окна должен быть определен и зарегистрирован прежде, чем будет создано окно. При регистрации необходимо сообщить Windows, какой вид должно иметь окно и какую функцию оно выполняет. В то же время регистрация класса окна еще не означает создание самого окна. Для этого требуется выполнить дополнительные действия.
Структура Windows-программ отличается от структуры программ других типов. Это вызвано двумя обстоятельствами: во-первых, способом взаимодействия между программой и Windows, описанным выше; во-вторых, правилами, которым следует подчиняться для создания стандартного интерфейса Windows-приложения (т.е. чтобы сделать программу “похожей “ на Windows-приложение).
Цель Windows – дать человеку, который хотя бы немного знаком с системой, возможность сесть за компьютер и запустить любое приложение без предварительной подготовки. Для этого Windows предоставляет дружественный интерфейс пользователя, который необходимо поддерживать всем программистам, создающим программное обеспечение в данной операционной системе.
