Файл: 16. Основы программирования пользовательского интерфейса.pdf

Добавлен: 20.10.2018

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

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

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

16. Основы программирования пользовательского интерфейса  

на базе Win32 API 

Стремление  сделать  прикладные  программы  как  можно  более  удобными 

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

приложения  реализует  именно  интерфейс  с  пользователем.  В  течение  90-х 

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

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

управляющих элементов (УЭ), меню и диалоговых окон. Системы  Windows 

традиционно  поддерживают  6  базовых  УЭ  и  около  15  дополнительных.  К 

основным  УЭ  относятся:  кнопки  разных  типов,  одно-  и  многострочные 

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

статический текст, полосы прокрутки. 

Каждый  УЭ  с  точки  зрения  системы  является  дочерним  окном, 

прикрепленным  к  какому-либо  родителю.  В  качестве  родительского  окна 

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

типа, но сами УЭ родителями быть не могут. Каждый базовый УЭ является 

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

общие  свойства  данного  типа  УЭ,  в  том  числе  –  предопределенная 

стандартная  оконная  функция,  реализующая  стандартное  поведение  УЭ. 

Таким  образом,    ОС  отвечает  за  стандартное  поведение  своих  УЭ  и  их 

прорисовку на экране. 

Базовые  УЭ  можно  создавать  с  помощью  системного  вызова 

CreateWindow,  который  в  случае  успеха  возвращает  дескриптор  созданного 

УЭ. Пример создания управляющих элементов: 

MyButton1 := CreateWindow („BUTTON‟, „Просто Кнопка!‟, 

bs_PushButton or ws_Child or ws_Visible, 50, 50, 100, 50, 

ParentWin, id_But1, …); 

MyEdit1 := CreateWindow(„EDIT‟, 0, es_MultiLine or ws_Child or 

ws_Visible, 200, 50, 100, 200, ParentWin, 0, …); 


background image

Вызовы  CreateWindow,  которые  создают  УЭ,  можно  располагать  в 

приложении в двух местах: в главной функции вслед за созданием главного 

окна и в оконной функции в обработчике какого-либо события. 

Важным  аспектом  взаимодействия  приложения  со  своими  УЭ  является 

отдача  этим  элементам  определенных  команд,  таких  как  “добавить  новый 

элемент в список”, “удалить выбранный элемент из списка”, “вернуть номер 

выбранного  в  списке  элемента”,  “вернуть  введенный  в  редакторе  текст”, 

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

фиксацией”  и  т.д.  Для  отдачи  команд  приложение  посылает  управляющим 

элементам  соответствующее  сообщение.  Фактически,  основная  работа 

приложения  с  УЭ  строится  на  использовании  механизма  посылки 

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

–  либо  SendMessage,  либо  PostMessage.  Различие  в  работе  этих  функций 

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

 

SendMessage  посылает  сообщение  сразу  в  оконную  функцию 

приложения и ждет обработки этого сообщения оконной функцией. 

 

PostMessage  посылает  сообщение  в  очередь  сообщений  данного 

приложения и не ждет пока это сообщение будет обработано. 

Чаще  используется  вызов  SendMessage.  Оба  этих  вызова  имеют  4 

формальных параметра: 

 

дескриптор УЭ, которому посылается сообщение (кому?); 

 

константа,  определяющая  действие,  которое  должен  выполнить  УЭ; 

для каждого типа УЭ определен свой набор констант; 

 

дополнительная информация о выполняемом действии (два параметра). 

Рассмотрим примеры кодирования наиболее типичных действий: 

 

добавление элемента-строки в список: 

SendMessage (MyList, lb_addString, 0, longint(строка)); 

при этом новая строка добавляется либо в конец не отсортированного 

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

 

запрос номера текущего выбранного элемента в списке: 


background image

Nomer := SendMessage (MyList, lb_GetCurSel, 0, 0); 

 

удаление выбранного элемента из списка (элемента с номером Nomer): 

SendMessage (MyList, lb_DeleteString, Nomer, 0); 

 

получение из списка текста выбранной строки с номером Nomer: 

SendMessage (MyList, lb_GetText, Nomer, строка); 

 

установка 

состояния 

включено/выключено 

у 

независимого 

переключателя: 

SendMessage (MyCheck1, bm_SetCheck, 1/0, 0); 

 

запрос состояния переключателя: 

Sost := SendMessage (MyCheck1, bm_GetCheck, 0, 0); 

Более  подробное  описание  констант-действий  можно  получить  во 

встроенной помощи. 

Теперь  рассмотрим  некоторые  возможности  по  управлению  системой 

меню  с  помощью  API-функций.  Всего  Win32  API  предоставляет  около  40 

подобных  функций.  Естественно,  начинать  надо  с  функций,  позволяющих 

создать в приложении систему меню программным способом. 

Программное  создание  меню  выполняется  по  принципу  “снизу  - 

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

после  этого  подключаются  к  соответствующим  пунктам  более  высокого 

уровня.  В  самую  последнюю  очередь  создается  полоса  основного  меню 

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

затем вся созданная система меню подключается к приложению. 

В качестве примера рассмотрим создание двухуровневого меню. 

Шаг  1.  Создание  двух  пустых  подменю  нижнего  уровня  (функция 

CreatePopUpMenu): 

SubMenu1 := CreatePopUpMenu; 

// 

SubMenu1 

и  SubMenu2  – 

дескрипторы  

SubMenu2  :=  CreatePopUpMenu;                //  подменю,  переменные  типа  

HMenu 


background image

Шаг  2.  Заполнение  созданных  подменю  элементами.  Каждый  элемент 

добавляется  с  помощью  своего  API-вызова    AppendMenu,  принимающего  4 

параметра: 

 

дескриптор меню, в которое добавляется новый элемент; 

 

стиль  добавляемого  элемента,  определяемый  как  комбинация  (с 

помощью  операции  логического  сложения)  следующих  основных 

флагов: 

o  mf_string – элемент является текстовой строкой; 

o  mf_enabled – элемент является активным; 

o  mf_disabled – элемент не активный; 

o  mf_grayed  –  элемент  показан  серым  цветом,  что  говорит  о  его 

неактивности в данный момент; 

o  mf_PopUp – используется при добавлении элемента-подменю; 

 

уникальный идентификатор элемента (например, idm_About); 

 

текст элемента (например, „About‟, „Open‟). 

Например: 

AppendMenu (SubMenu1, mf_string OR mf_enabled, 100, „Открыть‟); 

AppendMenu  (SubMenu2,  mf_string  OR  mf_grayed,  idm_About,  „О 

программе‟); 

Шаг 3. Создание основного меню с помощью вызова CreateMenu: 

MainMenu := CreateMenu; 

//    MainMenu  –  дескриптор  основного 

меню 

Шаг  4.  Присоединение  к  основному  меню  созданных  подменю  с  помощью 

вызова  AppendMenu,  который  имеет  те  же  самые  параметры,  но  со 

следующими отличиями: 

 

во втором параметре надо использовать флаг mf_PopUp; 

 

третий  параметр  –  это  дескриптор  присоединяемого  подменю 

(например, SubMenu1). 

Например: 


background image

AppendMenu  (MainMenu,  mf_PopUp  OR  mf_enabled,  SubMenu1, 

„Файл‟); 

Шаг 5. Присоединение созданного меню к главному окну приложения с 

помощью вызова  SetMenu, принимающего два параметра: 

 

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

 

дескриптор присоединяемого меню. 

В  этом  случае  в  описании  оконного  класса  в  поле  lpszMenuName 

ничего задавать не надо. 

Шаг  6.  Прорисовка  полосы  меню  выполняется  после  отображения  главного 

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

- дескриптор окна. 

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

структурой,  что  очень  распространено  в  современных  приложениях, 

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

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

следующие функции: 

1.  Изменение состояния элемента - EnableMenuItem с параметрами: 

 

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

элемент; 

 

либо идентификатор элемента, либо его порядковый номер (отсчет – 

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

 

комбинация флагов из следующего набора: 

o  mf_ByCommand – элемент задается идентификатором 

(установлен по умолчанию); 

o  mf_ByPosition – элемент задается порядковым номером; 

o  mf_enabled – элемент активен; 

o  mf_disabled – элемент не активен; 

o  mf_grayed – элемент показан серым цветом. 

2.  Изменение текста элемента – ModifyMenu с параметрами: