Файл: 15. Основы разработки событийно-управляемых программ в среде Windows.pdf

Добавлен: 20.10.2018

Просмотров: 1075

Скачиваний: 5

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

Для  описания  оконного  класса  используется  специальная  структура 

данных  со  стандартным  именем  WndClass.  Эта  структура  имеет  10  полей, 

которые  ВСЕ  необходимо  заполнить,  но,  к  счастью,  многие  из  них 

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

данного типа, имеющую любое осмысленное имя, например  – MyWndClass. 

Каждое  поле  этой  структуры  имеет  свое  жестко  заданное  имя,  которое 

мнемонически определяет смысл данного поля. Порядок установки полей не 

имеет  значения.  С  практической  точки  зрения  наиболее  интересными 

являются следующие поля: 

 

поле  с  именем  lpfnWndProc,  определяющее  адрес  оконной  функции, 

связываемой с данным оконным классом: 

MyWndClass.lpfnWndProc := @ имя_оконной_функции; 

 

поле-указатель  lpszClassName  на  текстовую  строку  с  именем 

создаваемого оконного класса: 

MyWndClass.lpszClassName := ‟MyClass‟; 

имя  класса  может  быть  практически  любым,  за  исключением 

нескольких стандартных зарезервированных имен; 

 

поле-указатель  lpszMenuName  на  текстовую  строку  с  именем  меню, 

используемом в главном окне программы: 

MyWndClass.lpszMenuName := „MyMenu‟;  

если  меню  не  используется,  полю  присваивается  пустое  значение  nil 

или NULL; 

 

поле hCursor, определяющее тип используемого в приложении курсора; 

подключение  курсора  может  выполняться  с  помощью  API-функции 

LoadCursor: 

MyWndClass.hCursor := LoadCursor (0, idc_Arrow); 

здесь второй параметр вызова – это константа, определяющая один из 

стандартных курсоров, а именно – обычную стрелку; кроме нее, можно 

использовать,  например,  такие  курсоры,  как  перекрестие  (idc_Cross) 

или песочные часы (idc_Wait); 


background image

 

поле  hbrBackground  определяет  шаблон  заполнения  фона  окна  с 

помощью  инструмента  рисования  –  кисти  (Brush)  и  может 

устанавливаться многими способами: 

       MyWndClass.hbrBackground := CreateSolidBrush(RGB(0,100,255)); 

       MyWndClass.hbrBackground := HBrush(Color_Window

); 

здесь  RGB  –  системная  функция,  определяющая  цвет  кисти  для 

заполнения фона как комбинацию трех базовых составляющих цвета – 

красного  (Red),  зеленого  (Green)  и  синего  (Blue);  интенсивность 

каждой  составляющей  задается  целым  числом  от  0  до  255;  например, 

RGB(0, 0, 0) задает черную кисть, а RGB(255, 255, 255) – белую; 

 

поле  hIcon  определяет  пиктограмму  окна  при  его  сворачивании  и 

устанавливается с помощью вызова LoadIcon: 

       MyWndClass.hIcon := LoadIcon (0, idi_Application); 

здесь  константа  idi_Application  определяет  стандартную  пиктограмму 

приложения. 

Кроме перечисленных выше, необходимо установить следующие поля, 

которые приводятся без комментариев в силу их редкого изменения: 

MyWndClass.Style := cs_VRedraw OR cs_HRedraw OR cs_DblClks;  

MyWndClass.cbClsExtra := 0; 

MyWndClass.cbWndExtra := 0; 

MyWndClass.hInstance := hInstance;

 

2.  После  задания  всех  10  полей  структуры  WndClass  ее  надо 

зарегистрировать в системе с помощью API-вызова RegisterClass с проверкой 

результата регистрации: 

    if   RegisterClass(MyWndClass) = 0   then   Exit;  // неудачная регистрация 

необходимость  проверки  связана  с  тем,  что  иногда  она  может  привести  к 

отрицательному результату, и в этом случае дальнейшая работа приложения 

невозможна. 

3.  После  успешной  регистрации  оконного  класса  можно  создавать  окна 

данного  класса.  Как  минимум,  должно  быть  создано  одно  главное  окно. 


background image

Создание одного окна выполняется с помощью одного вызова API–функции 

CreateWindow. Этот вызов принимает 11 параметров (более поздняя версия – 

уже  13).  Эти  параметры  конкретизируют  создаваемое  на  основе  данного 

класса окно. Важно понимать, что создание окна – это не отображение окна 

на  экране,  а  создание  соответствующей  информационной  структуры  с 

основными  параметрами  окна.  Если  создание  окна  проходит  успешно,  то 

вызов  CreateWindow  возвращает  специальный  описатель  окна,  так 

называемый  дескриптор.  Для  работы  с  дескриптором  надо  ввести 

переменную системного типа HWnd. Многие последующие функции работы 

с окнами требуют задания дескриптора как одного из параметров. 

Что  касается  входных  параметров  вызова  CreateWindow,  то  из  11 

параметров наиболее важными являются первые 9: 

 

первый параметр определяет имя оконного класса, на основе которого 

создается  данное  окно;  это  имя  чаще  всего  совпадает  с  именем, 

заданным в качестве значения поля lpszClassName структуры оконного 

класса; 

 

второй  параметр  определяет  текст  в  заголовке  окна  (если  текст  не 

нужен, надо задать 0); 

 

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

используется  набор  специальных  стилевых  констант,  среди  которых 

чаще всего используются: 

константа ws_Overlapped определяет стиль главного окна; 

константа  ws_Child  определяет  стиль  дочернего  окна,  которое 

обязательно  имеет  родительское  окно,  одинаковый  с  ним  вид  и 

поведение; родителем может быть как главное окно, так и любое 

ранее  созданное  дочернее  окно;  тем  самым  окна  могут 

образовывать вложенную иерархию; 

константа  ws_PopUp  определяет  еще  одну  разновидность 

подчиненных окон, так называемые всплывающие окна, которые 

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


background image

другому  по  сравнению  с  дочерними  окнами;  перечисленные 

выше  стили  не  должны  использоваться  совместно  при  создании 

одного окна; 

константа ws_Visible определяет видимость создаваемого окна; 

константа Ws_Border определяет наличие рамки у окна; 

константа Ws_Caption определяет наличие у окна заголовка; 

константы  ws_MaximizeBox  и  ws_MinimizeBox  определяют, 

имеет окно кнопки максимизации или минимизации; 

при необходимости некоторые перечисленные выше стили можно 

объединять вместе, используя логическую операцию ИЛИ (например – 

OR): 

WsVisible OR ws_Caption OR ws_Border 

очевидно, что не все стили  можно комбинировать вместе, например  – 

стили  главного  окна,  дочернего  и  всплывающего  противоречат  друг 

другу; 

 

четвертый и пятый параметры определяют координаты левого верхнего 

угла окна относительно клиентской части его родителя, а для главного 

окна - относительно рабочего стола (клиентская часть окна образуется 

за вычетом заголовка и рамки); координаты задаются в пикселах; 

 

шестой  и  седьмой  параметры  определяют  ширину  и  высоту 

создаваемого окна в пикселах: 

 

восьмой  параметр  определяет  для  создаваемого  окна  его  родителя  и 

задается  соответствующим  дескриптором;  отсюда  видно,  что  порядок 

создания  окон  должен  быть  вполне  конкретным:  сначала  родитель, 

потом только подчиненное окно; первое по порядку создаваемое окно 

является главным, и для него восьмой параметр надо задать нулевым; 

 

девятый  параметр  в  основном  используется  для  присваивания  окнам 

уникальных  идентификаторов;  использование  этого  параметра  будет 

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

Пример программного кода, создающего два окна, может выглядеть так: 


background image

var  MyMainWin, MyChildWin : HWnd; 

MyMainWin := CreateWindow(„MyClass‟, „Это главное окно‟, 

ws_OverlappedWindow, 100, 100, 400, 300, 0, 0, hInstance, nil);  

MyChildWin := CreateWindow(„MyClass‟, „А это дочернее‟, ws_Child OR 

ws_Visible  OR  ws_Caption  OR  ws_Border,  50,  50,  200,  100, 

MyMainWin, 0, hInstance, nil); 

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

этом  достаточно  отобразить  лишь  главное  окно,  все  подчиненные  окна 

отобразятся  автоматически.  Для  отображения  главного  окна  в  целом  и  его 

клиентской части используются два системных вызова: 

ShowWindow (MyMainWin, cmdShow); 

UpdateWindow (MyMainWin); 

5. Последним шагом в главной программе является запуск цикла обработки 

сообщений.  В  простейшем  случае  этот  цикл  реализуется  двумя  API 

функциями: 

while GetMessage (MyMessage, 0, 0, 0) 

 

DispatchMessage (MyMessage); 

Здесь  параметр  MyMessage    -  это  переменная  системного  типа  Msg, 

используемая  для  хранения  извлекаемого  из  очереди  сообщения.  Вызов 

GetMessage  извлекает  из  очереди  очередное  сообщение,  а  вызов 

DispatchMessage передает это сообщение в оконную функцию на обработку. 

Цикл while закончит свою работу, когда вызов GetMessage вернет значение 0, 

а  это  произойдет  в  ответ  на  появление  в  очереди  сообщений  специального 

сообщения  wm_Quit, помещаемого в очередь  в ответ на закрытие  главного 

окна  приложения.  Практически  всегда  перед  вызовом  DispatchMessage 

выполняется  вызов  функции  TranslateMessage,  используемой  для  обработки 

клавиатурных сообщений.