Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ООП_Лабораторный практикум

.pdf
Скачиваний:
79
Добавлен:
11.05.2015
Размер:
1.5 Mб
Скачать

Обязательное требование: заголовок функции должен быть точно такой же, как в базовом классе (и имя, и список параметров должны быть одинаковые). Тогда при создании объекта или базового, или одного из производных классов компилятор определяет, какую из функций требуется вызвать, основываясь на типе (ID класса) объекта.

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

Такой процесс в C++ получил название «позднее связывание».

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

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

Упражнение 3. Программа должна содержать:

-базовый класс X, включающий два элемента x1, x2 типа int;

-конструктор с параметрами для создания объектов в динамической области памяти,

-деструктор;

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

Производный класс Y, включающий один элементу типа int;

-конструктор с параметрами и списком инициализаторов, передающий данные конструктору базового класса;

-переопределенные методы просмотра текущего состояния объектов и их переустановки в новое состояние.

Варианты:

1.Создать в производном классе метод Run, определяющий:

2.Сумму компонент классов.

3.Произведение компонент классов.

4.Сумму квадратов компонент классов.

5.Значение xl + х2-y.

6.Значение (xl + х2)/у.

7.Значение (x1+ х2)*у.

8.Значение xl*y + x2.

Программа должна продемонстрировать работу конструкторов базового и производного классов, начальное значение задается конструкторами, а переустановка их в новое состояние производится методами классов через косвенную адресацию.

Контрольные вопросы

1)Опишите процесс создание и удаления таймера.

2)Зачем необходимо генерировать сообщение WM_PAINT?

3)Опишите процесс создания и подключения второй диалоговой панели.

4)Опишите параметры процедуры SetTimer(…).

5)Опишите варианты обработки сообщения WM_TIMER.

6)Что такое «наследование» и иерархия классов?

61

7)Какие элементы базового класса видны из производного? Как управлять степенью их защиты?

8)Какое наследование называют множественным?

9)Поясните механизм виртуальных функций.

10)Что такое чисто виртуальная функция?

Лабораторная работа №7.

Работа программы в фоновом режиме. Шаблоны классов.

Цельработы: изучитьприемысозданияииспользованияшаблоновклассов.

Часть 1. Основы программирования в среде Microsoft Visual C++ 6.0. Работа программы в фоновом режиме.

1.Создание нового проекта

Для изучения элементов управления Microsoft Visual C++ 6.0 создадим лабораторную программу, выполняющую следующие действия: Программа Task иллюстрирует работу программы в фоновом режиме, она будет выполнять несколько задач, такие как приращение счетчика через 50, 500, 1000 миллисекунд на единицу. В программе будет использоваться приложение c интерфейсом одного документа SDI( Single Document Interfeis), на базе класса формы (диалогового окна) CFormView. Примером программы SDI служит "Блокнот".

Окно вашей программы будет выглядеть так (рис 7.1):

Рис 7.1. Главное окно лабораторной программы №7.

1.Создание нового проекта

При создании проекта используйте следующие параметры: Project Name - Tasks.

Single Document.

None - т.к. баз данных не нужна.

Уберите все флажки за исключением 3D Controls.

На шаге 5 в верхнем окне списка классов выберите CTasksView, в раскрывшемся списке Base Class выберите класс CFormView.

2.Проектирование диалоговой панели

Расставьте элементы управления как показано на рис. 7.1 и согласно таблице 7.1.

62

 

 

Таблица 7.1. Оконные элементы программы.

Объект

Свойство

Установка

 

Dialog Box

ID

IDD_TASK_FORM

 

 

Font

System, Size 10, страница Styles

 

Static Text

ID

IDC_STATIC

 

 

Caption

Task 1(50 ms).

 

Edit Box

ID

IDC_TASK1_EDIT

 

 

Multi-line

отмечен, страница Styles

 

 

Align text

по центру, страница Styles

 

Check Box

ID

IDC_ENABLE_TASK1_CHECK

 

 

Caption

Enable Task 1

 

Static Text

ID

IDC_STATIC

 

 

Caption

Task 2(500 ms).

 

Edit Box

ID

IDC_TASK2_EDIT

 

 

Multi-line

отмечен, страница Styles

 

 

Align text

по центру, страница Styles

 

Check Box

ID

IDC_ENABLE_TASK2_CHECK

 

 

Caption

Enable Task 2

 

Edit Box

ID

IDC_TEST_EDIT

 

С помощью Class Wizard добавьте следующие переменные:

Object ID

Variable Name

Type

IDC_ENABLE_TASK1_CHECK

m_EnableTask1Check

BOOL

IDC_ENABLE_TASK2_CHECK

m_EnableTask2Check

BOOL

IDC_TASK1_EDIT

m_Task1Edit

long

IDC_TASK2_EDIT

m_Task2Edit

long

3. Инициализация флажков

При запуске программы, флажки должны быть отмечены, т.к. они включают счетчик. Для этого добавим код, в функцию OnInitalUpdate, которая будет выполняться при инициализации приложения.

Свяжите код с событием OnInitalUpdate класса CFormView c помощью ClassWizard. void CTaskView::OnInitialUpdate()

{

CFormView::OnInitialUpdate(); //Без комментариев m_EnableTask1Check=TRUE; m_EnableTask2Check=TRUE; UpdateData(FALSE);

}

4.Связывание элементов управления с событиями

Теперь необходимо добавить код обработки фонового режима, для этого нам необходимо связать код с событием OnIdle, которое происходит, когда окно программы не активно.

Для этого откройте Class Wizard выберите класс CFormApp, найдите сообщение OnIdle и добавьте функцию, в которую поместите следующий код:

BOOL CTaskApp::OnIdle(LONG lCount)

{

// TODO: Add your specialized code here and/or call the base class

63

/*Вызвать функцию базового класса СWinApp::OnIdle(), чтобы завершить его служебные задачи*/

CWinApp::OnIdle(lCount); //Звуковой сигнал

MessageBeep((WORD)-2);

/*Вернуть TRUE, чтобы опять запустить себя, если есть фоновый режим*/ returnTRUE;

}

Запустите программу, когда ваша система простаивает она выдает непрерывный звуковой сигнал, даже когда вы печатаете в окне редактирования, тоже подается звуковой сигнал, т.к. есть паузы между набором символов.

Модифицируем программу так, чтобы она меняла значение в окне редактирования на 1 через каждые 50 и 500 миллисекунд.

Измените код в функции OnIdle следующим образом. BOOL CTaskApp::OnIdle(LONG lCount)

{

////-Мой код начинается здесь-////

/*Вызвать функцию базового класса СWinApp::OnIdle(), чтобы завершить его служебные задачи*/

CWinApp::OnIdle(lCount);

//Получить указатель на шаблон документа

POSITION pos = GetFirstDocTemplatePosition(); CDocTemplate* pDocTemplate=GetNextDocTemplate(pos); //Получить указательна документ pos=pDocTemplate->GetFirstDocPosition();

CDocument* pDoc=pDocTemplate->GetNextDoc(pos); //Получить указатель на представление pos=pDoc->GetFirstViewPosition();

CTaskView* pView=(CTaskView*) pDoc->GetNextView(pos); //Переменные для хранения времени

static DWORD PrevTimeTask1=0; static DWORD PrevTimeTask2=0; //Получить Текущее время

DWORD CurrentTime=GetTickCount(); //Получить данные от элементов уравления pView->UpdateData(TRUE);

//Если время превысило 50 мс, то прибавить 1 if(CurrentTime>PrevTimeTask1+50 && pView->m_EnableTask1Check)

{

pView->m_Task1Edit=pView->m_Task1Edit+1; pView->UpdateData(FALSE); PrevTimeTask1=CurrentTime;

}

//Если время превысило 500 мс и cчетчик включен, то прибавить 1 if(CurrentTime>PrevTimeTask2+500 &&pView->m_EnableTask2Check)

{

pView->m_Task2Edit=pView->m_Task2Edit+1; pView->UpdateData(FALSE); PrevTimeTask2=CurrentTime;

}

return TRUE;

////-Мой код заканчивается здесь-////

}

64

Упражнение 1. Придумайте задачу и реализуйте программу работающую в фоновом режиме.

Часть 2. Шаблоны классов.

Механизм шаблонов C++ - это средство построения обобщенных определений функций и классов, которые не зависят от используемых типов данных. Этот механизм позволяет сократить трудоемкость создания программ, т.к. повышает лаконичность текста, т.е. использование шаблонов избавляет от необходимостидублироватькодыклассовифункцийдляразныхтиповданных.

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

Шаблоны класса в отличие от шаблона функции позволяют параметризовать, т.е. использовать в качестве параметров не только типы элементов данных, ноиконстантыразныхтипов.

Синтаксисопределенияшаблонакласса следующий:

template <список параметров шаблона> обычное описание структуры класса;

При этом список параметров шаблона не может быть пустым. Элементы в списке разделяются запятыми. Внутри пространства класса параметры шаблона должны быть хотя бы один раз упомянуты.

Всписокпараметровмогутвходитьдвавидапараметров:

1)типизированные параметры, начинающиесясослов

class Идентификатор,

компилятор при создании экземпляра класса заменит его на конкретный тип данных;

2)нетипированные параметры шаблона:

Стандартный тип числовых данных Идентификатор

Таким образом, типированные параметры - это фиктивные имена типов данных, входящих в класс. Нетипированные параметры - это поименованные типы числовых констант. При этом им при декларировании можноприсваиватьумалчиваемыезначения.

Каждый параметр является локальным врамках пространства класса.

В описании класса хотя бы один раз необходимо упомянуть ID типированных и нетипированных параметров, конкретные значения для которых будут переданы в момент создания объекта этого класса через список аргументов, который указывается через запятые в треугольных скобках сразу после ID класса:

ID_ класса <список аргументов> ID_объектов',

ID_объектов — идентификаторы объектов, которые создает данный класс (записанные через запятые, например а,b,с). При этом в списке аргументов каждому типированному параметру шаблона должен соответствовать известный конкретный тип данных, а каждому нетипированному параметру - константное выражение соответствуючего типа. Таким образом, между списком параметров шаблона и списком аргументов должно быть абсолютное соответствие по количеству, порядку их следования и типам. Если нетипированные параметры имеют умалчиваемые значения, ихрасполагаютвспискепоследними.

Пример с шаблоном класса, конструктор которого порождает объекты с двумя параметризованнымиполями:

template <class Tl> class X {

protected: Tl a, b; public:

X(T1 i, T1 j) { // Конструктор a = i; b=j;

cout« "\n Object created, size = " « sizeof(Tl) « endl;

}

65

void Print(void) {

cout« " a = " « a « " b = " « b « endl;

}

};

void main(void) {

X <int> x1(2, 3); // Целочисленныеобъекты x1.Print(); // Наэкране: Object created, size = 2 getch(); // a = 2 b = 3

X <double> x2(0.5, 1.2); // Вещественныеобъекты X2.Print(); // Наэкране: Object created, size = 4 getch();// a = 0.5b=1.2

Методышаблонаклассаможноопределятьвнеегопространства. Вэтомслучаеформатих определениябудетследующим:

template < списокпараметровшаблона> типрезультата ID класса <переченьчерез‘,’ ID изспискапараметровшаблона> :: ID метода (списокпараметровметода) { кодметода }

Ввышеприведенномпримеревынесемзапределыпространстваклассакодконструктора:

template <class Tl> class X {

protected: Tl a, b; public: X(T1, T1);

void Print(void) {

cout« " a = " « a « " b = " « b « endl;

}

}; // Определениеконструкторавнесоставакласса

template <class Tl> X <Т1> :: Х(Т1 i, T1 j) { а= i; b = j;

cout « " Object created, size = " « sizeof(T1) « endl;

}

void main(void) {

// Кодпредыдущегопримера

}

Упражнение 2. Даны: числоN ипоследовательностьа1, а2, …, aN. Создатьшаблонкласса, порождающегодинамическиеодномерныемассивысэлементамиразличных типов (вещественные, целочисленные, символьные ит.д.). Тип данных и результат являются параметрами по отношению к классу. Программадолжнасодержать: конструктор, деструктор, методпросмотразначенийсозданногомассива, атакжеметоддлярешениязадачформирования новогомассивапосоответствующемуиндивидуальномузаданию.

Варианты:

а) a1,(a1 +a2 ),K,(a1 +a2 +K+aN )

б) (a1 *a1 ),(a1 *a2 ),K,(a1 *aN )

в) a1 , a1 +a2 ,K, a1 +a2 +K+aN

г) a1 *1,a2 *2, a3 *3,K,aN * N

66

д) a1,+a2 ,a3 ,K,(1)N *aN

е) (a1 +1),(a2 +2),(a3 +3),K,(aN + N )

ж) a1 *1,a2 *2, a3 *3,K,aN * N

з) a1 *a2 ,a2 *a3 ,K,aN 1 *aN

Контрольные вопросы.

1)Опишите способы добавления новых файлов в проект.

2)Опишите способ создания документа SDI.

3)Дайте определение фонового режима работы программы.

4)Опишите процесс создания программы, работающей в фоновом режиме.

5)Опишите способ получения указателя на документ и на представление.

6)ВчемвC++ заключаетсямеханизмшаблоновклассовифункций?

7)Каковобщийформатшаблонакласса?

8)Перечислитевидыпараметровшаблонакласса.

9)Каксоздатьконкретныйэкземпляркласса, используяшаблонкласса?

10)Какопределитьметодвнепространствашаблонакласса?

Лабораторная работа №8.

Основы программирования с помощью Win API. Обработка исключительных ситуаций (C++).

Часть 1. Основы программирования с помощью Win API.

В связи с тем, что сегодня уровень сложности программного обеспечения очень высок, разработка приложений Windows с использованием только какого-либо языка программирования (например, языка C) значительно затрудняется. Программист должен затратить массу времени на решение стандартных задач по созданию пользовательского интерфейса. Реализация технологии связывания и встраивания объектов - OLE - потребует от программиста еще более сложной работы.

Чтобы облегчить работу программиста, практически все современные компиляторы с языка C++ содержат специальные библиотеки классов. Такие библиотеки включают в себя практически весь программный интерфейс Windows и позволяют пользоваться при программировании средствами более высокого уровня, чем обычные вызовы функций. За счет этого значительно упрощается разработка приложений, имеющих сложный интерфейс пользователя, облегчается поддержка технологии OLE и взаимодействие с базами данных.

Современные интегрированные средства разработки приложений Windows позволяют автоматизировать процесс создания приложения. Для этого используются генераторы приложений (AppWizard). Программист отвечает на вопросы генератора приложений и определяет свойства приложения - поддерживает ли оно многооконный режим, технологию OLE, трехмерные органы управления, справочную систему. Генератор приложений, создаст приложение, отвечающее требованиям, и предоставит исходные тексты. Пользуясь им как шаблоном, программист сможет быстро разрабатывать свои приложения.

Подобные средства автоматизированного создания приложений включены в компилятор Microsoft Visual C++ и называются MFC AppWizard. Заполнив несколько диалоговых панелей, можно указать характеристики приложения и получить его тексты, снабженные обширными комментариями. MFC AppWizard позволяет создавать однооконные и многооконные приложения, а также приложения, не имеющие главного окна, -вместо него используется диалоговая панель. Можно также включить поддержку технологии OLE, баз данных, справочной системы, построить библиотеку DLL.

67

Конечно, MFC AppWizard не всесилен. Прикладную часть приложения программисту придется разрабатывать самостоятельно. Исходный текст приложения, созданный MFC AppWizard, станет только основой, к которой нужно подключить остальное. Но работающий шаблон приложения - это уже половина всей работы. Исходные тексты приложений, автоматически полученные от MFC AppWizard, могут составлять сотни строк текста. Набор его вручную был бы очень утомителен.

Нужно отметить, что MFC AppWizard создает тексты приложений только с использованием библиотеки классов MFC (Microsoft Foundation Class library). Поэтому только изучив MFC, можно пользоваться средствами автоматизированной разработки и создавать свои приложения в кратчайшие сроки.

1.Объектно-ориентированное программирование и Visual C++.

Идеи объектно-ориентированного программирования (ООП) уже оказали и продолжают оказывать решающее влияние на состояние и развитие всех областей современного программирования, языки и системы программирования, операционные системы, базы данных и базы знаний. Одним из результатов этого процесса стал Visual C++.

Среда разработки программ Visual C++ может использоваться для создания консольных приложений., но в основном предназначена для создания Windows-приложений, т.е. программ, созданных теми или иными инструментальными средствами, вместе со всем необходимым для их работы: файлами ресурсов, библиотеками и т.д.

В Visual C++ в основном разрабатываются MFC AppWizard-приложения, использующие библиотеку базовых классов MFC (Microsoft Foundation Class Library) фирмы Microsoft и

инструменты AppWizard, ClassWizard, а также редактор ресурсов и текстовый редактор. AppWizard-приложения представляют собой совокупность объектов, которыми является само приложение и все его компоненты: документы, окна, виды документов и т.д. Объектприложение, обычно носящий имя theApp (the Application, где определенный артикль подчеркивает, что речь идет о конкретном приложении), взаимодействует с другими объектами. Это взаимодействие, как и положено в объектно-ориентированном мире, выражается в сообщениях, посылаемых друг другу объектами. Отсюда ясно, что объяснить, как строятся приложения в Visual C++ и как они работают, не привлекая понятий из области ООП, невозможно.

Основные принципы и понятия ООП: объект, класс и наследование - появились в 1967 году в языке Симула-67. Эти идеи были развиты и четко сформулированы в языке и среде Smalltalk. В версии Smalltalk-80 была высказана еще одна центральная идея: жизнь объектов состоит в том, что они посылают друг другу сообщения.

Классы с наследованием и переопределением методов вошли в большинство объектноориентированных языков программирования - в том числе и в C++ (объектно-ориентированное расширение языка C). Идея обмена сообщениями легла в основу операционной системы Windows, где объекты-окна посылают и получают сообщения.

Класс является обобщением понятия типа данных и задает свойства и поведение объектов класса, называемых экземплярами класса. Каждый объект принадлежит некоторому классу. Отношение между объектом и его классом такое же, как между переменной и ее типом. С формальной точки зрения, класс - это объединение данных и обрабатывающих их функций. Данные класса называются также переменными класса, а процедуры - методами класса. В C++ переменная класса data member, метод - member function. Переменные определяют свойства объекта, Говорят также, что значения переменных определяют состояние объекта. Методы определяют поведение объекта.

Если определен класс А, можно определить новый класс В, наследующий свойства и поведение объектов класса А. Это значит, что в классе В определены переменные и методы класса А. Класс В, являясь наследником базового (родительского) по отношению к нему класса А, называется производным (порожденным) по отношению к классу А. В производном классе можно задавать новые свойства и новое поведение, определив новые переменные и новые методы, или даже переопределить существующий метод базового класса. Переопределение

68

метода (или перегрузка (overloading) или перекрытие (overriding)) класса А в производном классе В - это определение в классе В метода с тем же именем, уже являющимся именем какого-то метода класса А. При этом обычно конкретизируется или специализируется реализация переопределенного метода класса А применительно к объектам класса В (они в силу наследования являются частными случаями объектов класса А).

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

Класс В, производный от класса А, в свою очередь может быть базовым по отношению к порожденному от него классу С, становящемуся, таким образом, наследником класса А в следующем поколении, и т.д. Все порожденные классы в любом поколении называются наследниками данного класса, а все, от которых он порожден, - его предками.

Визуальное и событийно-управляемое программирование Жизнь объектов состоит в обмене сообщениями. Когда один объект посылает сообщение

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

Рассматривать мир объектов приложения как замкнутый, внутренний вряд ли оправдано. Ситуация меняется, если мир объектов не замкнут и они способны получать сообщения из внешней среды. Эти сообщения могут появляться как результат событий, происходящих во внешнем мире: действий пользователя, операционной системы, других приложений.

Рассмотрим простую и естественную модель событийно-управляемого и визуального программирования, характерную для языка и среды Visual С++. В этой модели у приложения три составляющие: визуальная, системная и обработчик событий. Визуальная составляющая задает образ на экране, с которым будет работать пользователь. Она, как правило, разрабатывается визуальным инструментарием, позволяющим программисту создавать из элементов нужный образ на экране. Эти элементы являются объектами со своими свойствами и поведение.

Визуальная составляющая определяет интерфейс пользователя. Такие элементы интерфейса, как кнопки, окна редактирования, окна списков, называют элементами управления (controls). Эти и другие элементы интерфейса стандартизированы в стандарте пользовательского интерфейса CUA (Common User Access) в рамках общего стандарта SSA (system Application Architecture) фирмы IBM. Поэтому в разных средах разработки (Visual Basic, Visual C++, Delphi и др.) визуальный инструментарий содержит одни и те же элементы интерфейса. Такие же элементы интерфейса содержат разные приложения.

Элементы управления являются объектами, свойства и поведение которых определяется их переменными и методами. Они относятся к интерфейсным объектам.

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

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

69

объектов, добавлять или удалять объекты визуальной составляющей, даже полностью изменить ее облик.

Программирование на Visual С++ полностью соответствует концепциям визуального и событийно-управляемого программирования. Чтобы создать приложение на Visual С++, нужно сделать две вещи: разработать с помощью визуального инструментария интерфейс пользователя и написать реакции на действия пользователя, т.е. для каждого возможного события - обрабатывающий его метод.

Событийно-управляемое программирование (event-driven programming), называемое также программированием с управлением по событиям, имеет, разумеется, смысл и само по себе, а не только в рамках приведенной модели. Программы, разработанные по его принципам, существовали задолго до появления визуального программирования - например, всем известные текстовые редакторы. Обычно эти программы содержат цикл, в теле которого разбираются варианты реакций на действия пользователя.

Модель Visual С++ особенно интересна программисту. Во-первых, программист может очень быстро создать приложение со стандартными элементами управления, просто определив реакцию приложения на некоторые события. Во-вторых, здесь есть возможность создавать объекты, производные от стандартных, но с отличными свойствами, тем самым создавая уникальные по интерфейсу приложения. Но от программиста требуется глубокое знание системы, а также глубокое понимание особенностей объектно-ориентированного программирования.

2.Windows-приложения

Для создания прилржений под Windows без использования MFC пользователь должен знать особенности построения Windows-приложений, а также может пользоваться библиотекой

API Windows (Application Programming Interface). Мы будем говорить о 32-битовых Windows (95/98 или NT ), поэтому будем раcсматривать только Win32 API.

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

События, возникающие в процессе работы компьютера (инициированные пользователем или связанные с посылкой сообщений от одного приложения другому, от одного окна к другому окну того же приложения), приводят к помещению операционной системой сообщения, связанного с событием, в первичную системную очередь сообщений. Windows

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

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

70