Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
83
Добавлен:
10.12.2013
Размер:
1.15 Mб
Скачать
  • Среда Win32

Основное принципиальное отличие DOS и Windows - это поддерживаемые методологии программирования. DOS поддерживает и ориентирована на программы и языки структурного программирования, а Windows - на программы и языки, построенные по объектным или объектно-ориентированным технологиям и языкам.

Другое важное свойство Windows- эта система поддерживает обьектное программирование и языки, но объектно-ориентированное программирование поддерживается не полностью. В первую очередь это связанно с тем, что Windows планировалась как система пригодная для использования и процедурными(C, Pascal) и объектно-ориентированными (C++, Smalltalk, Pascal-Delphi) языками. В процедурных языках, перечисленных выше, применение тех свойств, которыми обладает любая обьектная система, а именно: сокрытие данных в объектах и классах, сообщения как метод взаимодействия между обьектами, классы, объекты, методы классов без наследования - относительно легко применимы и могут быть добавлены без серьезных изменений языка и средств разработки.

Однако основные черты объектно-ориентированного программирования: наследование и динамическое связывание методов класса в процедурных языках практически невозможно реализовать, не изменив сам язык.

Поэтому в среде Windows чрезвычайно развито такое свойство объектного программирования как сокрытие данных и механизм сообщений , а наследование практически отсутствует (исключение- окна Windows, у них есть это свойство, но остальное множество объектов этой среды этим свойством не обладают)

Отсюда следует другое важное свойство: система Windows должна поддерживать использование объектов и объектных технологий в любом процедурном языке, но не в ущерб объектно-ориентированным языкам и технологиям.

  • Классы Win32

В системе Win32 существуют много самых разнообразных классов( то есть множества объектов ,имеющих общую структуру и поведение), наследование от этих классов не поддерживается, кроме абстрактного класса окна ,который поддерживается для однократного наследования глубиной 1. В системе есть примерно 10 классов унаследованных от абстрактного класса окна, которые мы можем использовать в своей программе.

Изменение состояния объектов и получение информации об объектах в любом классе, кроме классов производных от оконных, возможно с использованием множества функций предоставляемых операционной системой, и только с их помощью. Внутренняя структура и данные любого объекта Windows и любого класса Windows защищена от вмешательства со стороны прикладной программы средствами Windows и аппаратно. Для любого объекта, производного от оконного класса, можно изменить состояния объекта и получить информацию об объекте либо путем вызова функции Windows, либо путем отправки этому объекту сообщения, при этом любой вызов функции Windows может быть продублирован отправкой соответствующего сообщения.

  • Объекты Win32

Каждый объект в системе идентифицируется своим уникальным номером-дескриптором (handle), который уникален для объектов каждого класса операционной системы и каждого класса, производного от оконного класса, но для объектов разных классов возможна, хотя и мало вероятна ситуация, когда этот номер совпадет.

При вызове соответствующей функции Win32 для соответствующего класса, этот номер будет одним из параметров функции, по которому ОС выделит этот объект среди множества объектов этого класса и попробует выполнить запрошенное действие, а если объекта с таким номером нет, то вызов функции будет проигнорирован. Как было сказано выше, handle объектов разных классов могут совпасть, тогда возможны очень неприятные и трудноуловимые ошибки, поэтому следует следить за тем, какой handle вы отправляете в качестве параметра.

Все объекты классов создаются только средствами ОС. Для создания объектов соответствующего класса предусмотрена своя уникальная функции, которая попытается создать объект заданного класса и в случае успеха возвратит handle созданного объекта не равный нулю.

  • Интерфейс прикладного программирования (API)

API(Application Programming Interface)-это набор функций, предоставляющих программисту возможность создавать программы(приложения) для Windows NT, Windows 95/98, Windows 2000 и т.д., т.е. для 32-разрядных платформ. Естественно, что эти платформы разнятся между собой, но набор функций, составляющих API, для них один и тот же. Все функции этого набора 32-битовые.

Таким образом, Windows API есть не что иное, как просто набор функций, формирующих интерфейс между приложением и компьютером в целом.

  • Программа для Windows

Минимальная программа для Windows состоит из двух функций: функции WinMain и функции окна. На некотором псевдоязыке программу для Windows можно записать следующим образом:

WinMain(список аргументов)

{

Создание класса окна

Создание экземпляра класса окна

Пока не произошло необходимое для выхода событие

Выбрать из очереди сообщений очередное сообщение

Передать сообщение оконной функции

Возврат из программы}

}

WindowsFunction(список аргументов)

{

Обработать полученное сообщение

Возврат

}

  • Функция WinMain

Функция WinMain() является обязательным компонентом любого приложения и отвечает за следующее:

1)регистрацию класса окна приложения;

2)начальную инициализацию приложения;

3)создание и инициализацию цикла обработки сообщений;

4)завершения выполнения программы, обычно в результате получения сообщения WM_QUIT.

Рассмотрим простейшее приложение Win32

int WINAPI WinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR lpCmdLine,

int nCmdShow)

{

return 0;

}

Это приложение ничего заметного на глаз не делает и сразу же прекращает свою работу, возвращая управление OC с кодом возврата 0.

Первое заметное отличие этой программы от любой программы для DOS- это отсутствие функции main (). Это вызвано тем, что параметры программы, которые приложение получает от операционной системы Windows, иные, чем для DOS, поэтому потребовалась иная функция, с которой запускается и в которой завершается программа.

Обратите внимание на слово WINAPI перед телом функции WinMain. Это слово указывает компилятору на необходимость сгенерировать перед выполнением этой функции специальный пролог и эпилог необходимый для функции, в которой запускается и завершается программа. Если это слово будет отсутствовать, то программа будет сгенерированна неправильно. Не забывайте включать это слово перед каждой функцией WinMain, которую вы пишите.

Рассмотрим те параметр, которые получает приложение от OS в функции WinMain.

lpCmdLine- указатель на строку, содержащую командную строку программы, это параметры для программы, переданные пользователем, если таких параметров нет, то равна NULL. В целом схоже с аналогичной строкой параметров, которые программа получает от пользователя DOS.

nCmdShow- стиль окна приложения - код показывающей, каким пользователь хочет видеть окно, в которое ваша программа будет осуществлять вывод( свернутым или полноэкранным и т.д.).

hInstance- handle программного модуля приложения. Среди классов Win32 ваша программа также является объектом класса HINSTANCE, желательно запомнить его handle в какой-нибудь глобальной переменной, т.к. некоторые функции API могут потребовать его в качестве параметра. В основном он необходим при работе с ресурсами приложений, организации многозадачности и при создании оконных объектов.

Вы всегда можете получить его в своей программе с помощью функции

HINSTANCE GetModuleHandle(LPCTSTR lpModuleName) , которая возвращает handle программного модуля, заданного по имени его .exe или .dll файла или, если параметр LpModuleName равен NULL, то handle того программного модуля, из которого эта функция была вызвана.

hPrevInstance- параметр перешел в Win32 в целях совместимости с предыдущими версиями Win16; в Win32 не используется и всегда равен NULL

Имея в своем распоряжение handle своего программного модуля, приложение будет способно работать с файлами, выделять себе необходимую память, взаимодействовать с другими работающими программами, но будет неспособно организовать работу с пользователем. Для ее организации приложение должно создать свое окно, которое будет взаимодействовать с пользователем и получать от него команды.

С точки зрения пользователя окно программы – это прямоугольная область экрана, где программа что- либо рисует и которая выполняет все необходимые действия для работы.

С точки зрения программиста окно программы – это главное окно программы, которое первое появляется и последним исчезает при работе с программой. Другие окна, которые создаются главным окном, взаимодействуют с ним и им же уничтожаются.

Любое созданное нами окно Windows будет принадлежать к одному из уже определенных системой или нами классов окон, в том числе и главное окно, класс которого необходимо зарегистрировать перед выполнение каких либо действий с ним. При регистрации класса окна в нем задаются наиболее общие свойства тех оконных объектов, которые будут созданы на основе данного класса, и сведения о которые необходимы для системы. Это, например, форма, которую принимает курсор при нахождение внутри той части экрана, которое занимает это окно, как и когда OС должно посылать запросы окну на перерисовку и т.д.

  • Регистрация класса окна

Для регистрации класса окна рекомендуется использовать функцию RegisterClassEx. ATOM RegisterClassEx(

const WNDCLASSEX *lpwcx; //указатель на структуру, содержащую данные о

// регистрируемом классе окна

);

Структура WNDCLASSEX определена только для Win95/Win98/Win2000.

Для Widows NT следует использовать структуру WNDCLASS и функцию RegisterClass(const WNDCLASS *lpwc);

При успехе функция возвращает уникальный целочисленный идентификатор(ATOM), целое число, которое уникально для каждого зарегистрированного класса окна или 0- в случае неудачи.

Параметром функции будет указатель на структуру WNDCLASSEX, в которой содержатся все необходимые данные об классе окна.

Прототип этой структуры такой.

typedef struct _WNDCLASSEX {

UINT cbSize;//размер этой структуры в байтах

UINT style;//стиль класса

WNDPROC lpfnWndProc;//адрес функции окна для этого класса

int cbClsExtra;//число байт необходимых для хранения данных для класса

int cbWndExtra;//число байт необходимых для хранения данных при создание каждого оконного объекта этого класса

HANDLE hInstance;//handle програмного модуля который регистрирует класс

HICON hIcon;// handle большой иконки

HCURSOR hCursor;// handle курсора

HBRUSH hbrBackground;//цвет кисти фона

LPCTSTR lpszMenuName;//имя меню для этого класса окна

LPCTSTR lpszClassName;//имя класса окна

HICON hIconSm;//handle маленькой иконки

} WNDCLASSEX;

Опишем части структуры более подробно.

cbSize-указывает размер этой структуры в байтах, используйте sizeof(WNDCLASSEX) для правильного заполнения этого поля

cbClsExtra и cbWndExtra- размер областей памяти, которые выделит система для хранения дополнительных данных об окне после успешной регистрации класса окна и после успешного создания каждого оконного объекта этого класса. Мы не будем требовать у системы эту память, поэтому установим эти значения в ноль

hInstance-handle программного модуля, который регистрирует окно заданного класса, используйте значение переданное в параметрах функции WinMain.

hIcon и hIconSm-handle большой и маленькой иконки, которые будут появляться соответственно при нажатие Alt+Tab и в правом верхнем углу главного окна приложения.

Загрузить необходимую иконку можно с помощью функций LoadIcon или LoadImage.

Воспользуемся функцией LoadIcon для того чтобы загрузить одну из встроенных в OC иконок.

HICON LoadIcon( HINSTANCE hInstance, LPCTSTR lpIconName);

где

hInstance -идентификатор программного модуля, из ресурсов которого необходимо загрузить иконку, для загрузки иконки из ресурсов OС укажите этот параметр как NULL

lpIconName - имя иконки; для задания идентификатора одной из встроенных иконок в виде флажка Windows укажем этот параметр как IDI_APPLICATION

Функция LoadIcon загружает только иконки размером 32*32,для загрузки иконки меньшего размера, мы можем просто уменьшить размер загруженной иконки в 2 раза, например с помощью функции CopyImage, или загрузить иконку требуемого размера с помощью функции LoadImage

Воспользуемся функцией CopyImage.

HANDLE CopyImage(

HANDLE hImage,

UINT uType,

int cxDesired,

int cyDesired,

UINT fuFlags

);

где

hImage- handle уже загруженной иконки, загрузим ее с помощью функции LoadIcon

uType -тип рисунка для копирования, укажем IMAGE_ICON

cxDesired- новая ширина иконки, укажем 16

cyDesired- новая высота иконки, укажем 16

fuFlags - флаги

Присвоим полю hIconSm значение, полученное от функции CopyImage, преобразовав его к типу HICON.

hCursor –handle той формы курсора, которую он будет принимать, когда находится в оконном прямоугольнике, принадлежащем классу, заданному в lpszClassName.

Для ее загрузки воспользуемся функцией LoadCursor

HCURSOR LoadCursor(HINSTANCE hInstance, LPCTSTR lpCursorName );

где

hInstance- Идентификатор программного модуля, из ресурсов которого необходимо загрузить рисунок курсора, для загрузки иконки из ресурсов OС укажите этот параметр как NULL

lpCursorName - имя курсора; для задания идентификатора одного из встроенных курсоров в виде флажка Windows укажем этот параметр как IDC_ARROW

hbrBackground-Фоновая кисть для данного класса окна, то есть тот цвет, которым будет закрашена средствами OС та часть окна или все окно, перед тем как приложение сможет что-либо изобразить там.

Воспользуемся кистью с цветом окна по умолчанию, присвоив этому полю значение (HBRUSH)(COLOR_WINDOW+1).

Всего в системе есть около двадцати таких предопределенных цветов, доступных по своим константным номерам, полный их список можно просмотреть в помощи среды разработки. При использование какого-либо из них обязательно прибавьте к номеру 1 и преобразуйте к типу HBRUSH.

lpszMenuName-если окно, созданное на базе данного оконного класса имеет меню по умолчанию, то здесь указывается адрес строки содержащей это имя меню. Так как наше приложение не имеет меню, то укажем здесь NULL.

lpszClassName-имя класса окна; в системе не может быть два класса окна с одинаковыми именами, поэтому это имя должно быть уникальным, задается указателем на строку символов, содержащей это имя.

style-специфицирует стиль класса окна, то есть те необходимые свойства в поведение окон данного класса, которые нужно знать операционной системе.

Стили окна - это битовые флаги которые могут комбинироваться с помощью логической операции ИЛИ, всего их более 10, но для нас сейчас представляют интерес следующие стили:

CS_DBLCLKS- сообщение посылается при двойном щелчке мыши

CS_HREDRAW- если пользователь изменил высоту данного окна, то посылается сообщение об его перерисовки.

CS_VREDRAW- если пользователь изменил высоту данного окна, то посылается сообщение об его перерисовки.

Обычно достаточно установить поле style равным CS_HREDRAW| CS_VREDRAW | CS_DBLCLKS.

lpfnWndProc- адрес функции обратного вызова для приема сообщений предназначенных для данного класса окна.

Теперь, когда все поля структуры описаны, (не забудьте написать свою функцию обратного вызова для своего класса окна) зарегистрируйте свой класс окна с помощью функции RegisterClassEx. Функции вернет вам так называемый ATOM, или шестнадцатиразрядное целое число, по которому система будет различать ваш класс окна, вам его не нужно запоминать, но стоит проанализировать на предмет неравенства этого значения нулю. Если возвращенное число равно нулю, то зарегистрировать класс окна не удалось.

Мы можем зарегистрировать столько классов окна, сколько нам надо, однако нам необходимо обеспечить каждое из них своей уникальной функцией обратного вызова и своим уникальным именем.

Соседние файлы в папке Лабы_длстудентов