Воскресенье
17-11-19, 07:47
"КОМП" от и до!
Приветствую Вас Гость | RSS
Главная Статьи Регистрация Вход
Меню сайта

Категории каталога
PHP [10]
Создание сайтов на PHP
Visual Studio.Net [5]
Среда разработки Visual Studio.Net

Наш опрос
Статьи по каким темам вам наиболее интересны?
Всего ответов: 250

Реклама

Главная » Статьи » Программирование » Visual Studio.Net

Урок 3. Традиционное Windows-приложение. Часть 2.
Урок 3. Традиционное Windows-приложение. Часть 2.
 
 
Оконная процедура
Теперь рассмотрим, как устроена оконная процедура wndProc. Ее имя уже дважды появлялось в тексте программы. Сначала был объявлен ее прототип, затем оно было присвоено одному из полей структуры типа WNDCLASSEX. Поле имеет тип указателя на функцию с особым прототипом оконной функции. Здесь полезно вспомнить, что имя функции трактуется компилятором C++ как ее адрес.
Оконная процедура должна «просеивать» все посылаемые ей сообщения и обрабатывать те из них, которые были выбраны программистом для обеспечения желаемой функциональности. Типичной структурой оконной процедуры является switch-блок, каждая ветвь которого содержит обработку одного сообщения. В первом приближении наша оконная процедура реагирует только на три сообщения:
WM_COMMAND — о выборе пользователем одной из команд меню;
WM_PAINT — о необходимости перерисовать клиентскую область окна;
WM_DESTROY — о необходимости закрыть окно.
Сообщение WM_DESTROY (уничтожить окно) посылается системой уже после того, как окно исчезло с экрана. Мы реагируем на него вызовом функции PostQuitMessage, которая указывает системе, что поток приложения требует своего завершения, путем посылки сообщения WM_QUIT. Его параметром является код завершения, который мы указываем при вызове PostQuitMessage.
Примечание
Рассмотренная структура приложения Win32 позволяет сделать вывод, что в подавляющем числе случаев развитие приложения сосредоточено внутри оконной процедуры, а не в функции WinMain. Развитие приложения заключается в том, что в число обрабатываемых сообщений (messages) включаются новые. Для этого программист должен вставлять новые case-ветви в оператор switch (msg).
Если оконная процедура не обрабатывает какое-либо сообщение, то управление передается в ветвь default. Вы видите, что в этой ветви мы вызываем функцию DefWindowProc, которая носит название оконной процедуры по умолчанию. Эта функция гарантирует, что все сообщения будут обработаны, то есть, удалены из очереди. Возвращаемое значение зависит от посланного сообщения.
Вы, конечно, обратили внимание на обилие новых типов данных, которые используются в приложениях Win32. Многие из них имеют префикс Н, который является сокращением слова Handle — дескриптор, описатель. Описатели разных типов (HWND, HPEN, HBITMAP и т. д.) являются посредниками, которые помогают найти нужную структуру данных в виртуальном мире Windows. Объекты Windows или ее ресурсы, такие как окна, файлы, потоки, перья, кисти, области, представлены в системе структурами языка С, и адреса этих структур могут изменяться. В случае нехватки реальной памяти Windows выгружает из памяти ненужные в данный момент времени объекты и загружает на их место объекты, требуемые приложением. В системной области оперативной памяти Windows поддерживает таблицу, в которой хранятся физические адреса объектов. Для поиска объекта и управления им сначала следует получить у системы его описатель (место в таблице, индекс). Важно иметь в виду, что физический адрес объекта — понятие для Windows, а не для программиста. Описатель типа HANDLE можно уподобить номеру мобильного телефона, с помощью которого вы отыскиваете объект, перемещающийся в виртуальном мире Windows.
 
 
Меню и диалог
При выборе пользователем какой-либо команды меню система посылает в оконную процедуру сообщение WM_COMMAND, в коротком (wParam) параметре которого будет спрятан идентификатор команды. В обработке сообщения WM_COMMAND содержится распаковка короткого параметра и разветвление в зависимости от идентификатора команды. В ответ на команду About вызывается диалог, шаблон которого вы можете найти в ресурсах приложения.
Запуск диалога в модальном режиме обеспечивает API-функция DialogBox, последним параметром которой является адрес функции About. Он явно приводится к типу DLGPROC (диалоговые процедуры). Этот тип определен как указатель на функцию обратного вызова (реакцию на сообщение) с определенным прототипом. Функция About будет вызываться системой для обработки сообщений, посылаемых уже не главному окну приложения, а окну диалога. Отметим, что описатели CALLBACK, WINAPi и FAR PASCAL идентичны. Они появились на разных этапах развития Windows и одновременно используются системой для обеспечения совместимости со старыми версиями.
Параметры функции About имеют следующий смысл:
HWND hDlg — Windows-описатель окна диалога;
UINT message — код сообщения;
WPARAM wParam, LPARAM IParam — два параметра, сопровождающих сообщение.
Диалоговая процедура имеет характерную, давно устоявшуюся структуру. Первая ветвь switch-блока (WM_INITDIALOG) вызывается при открытии диалога, а вторая (WM_COMMAND) — при нажатии кнопок, расположенных в нем. Вместе с сообщением WM_COMMAND приходят два параметра, в которых запакована сопровождающая информация. В нашем случае это идентификатор (ШОК) кнопки ОК, так как другой традиционной кнопки Cancel (IDCANCEL) просто нет в шаблоне диалога. В Win32 идентификатор элемента управления спрятан в младших 16 битах wParam, и его приходится распаковывать. Функция EndDialog закрывает окно диалога.
 
 
Развитие начальной заготовки
Мы хотим показать способы развития начальной заготовки приложения Win32. В наши планы входит создание пера Windows и управление его стилями. Кроме того, мы хотим показать, как можно изменять цвет пера с помощью стандартного диалога Windows. Существует множество стандартных диалогов для управления разными объектами системы, например открытие файла, выбор шрифта, поиск и замена текста. Мы будем управлять стандартным диалогом по выбору цвета. Обычным приемом при работе с каким-либо из стандартных диалогов является использование подходящей вспомогательной структуры. Поля структуры помогают инициализировать элементы диалога при его открытии, а также извлечь результат после его завершения.
В нашем случае диалог вызывается ЛР1-функцией chooseColor, которая требует задать в качестве параметра адрес структуры типа CHOOSECOLOR. Ее надо предварительно создать и использовать для хранения текущего цвета, а также цвета, выбранного пользователем в рамках диалога. Цвет должен храниться в поле rgbResult этой структуры. Вы помните, что оконная процедура многократно, при обработке каждого сообщения, получает и вновь отдает управление системе. Ее локальные (автоматические) переменные будут каждый раз создаваться и погибать. Следовательно, они не в состоянии запомнить текущий выбранный цвет. Выход — использовать либо глобальные, либо статические переменные. Используя второй способ, вставьте в начало тела функции WndProc следующие переменные:
//===== Структура для работы со стандартным диалогом
CHOOSECOLOR cc;
//===== Переменная для хранения текущего цвета
static COLORREF color = RGB(255,0,0);
//===== Массив цветов, выбираемых пользователем
static COLORREF CustColors[16];
Структура CHOOSECOLOR определена в библиотеке, которая сейчас недоступна, поэтому вставьте в конец файла stdafx.h директиву #include <CommDlg.h>. Заодно добавьте туда еще две строки:
#include <string>
using namespace std;
так как ниже мы будем пользоваться объектами типа string из библиотеки STL. Затем в блок switch (wmld) функции WndProc введите ветвь обработки команды меню ID_EDIT_COLOR (саму команду создадим позже):
// Если выбрана команда с идентификатором ID_EDIT_COLOR
case ID_EDIT_COLOR:
// Подготовка структуры для обмена с диалогом
ZeroMemory(Sec, sizeof(CHOOSECOLOR));
//====== Ее размер
cc.lStructSize = sizeof(CHOOSECOLOR);
//====== Адрес массива с любимыми цветами
cc.lpCustColors = (LPDWORD)CustColors;
if (ChooseColor (ice)) // Вызов диалога
{
// Если нажата кнопка OK,
// то запоминаем выбранный цвет
color = cc.rgbResult;
// Объявляем недействительной
// клиентскую область окна
InvalidateRect(hWnd, NULL, TRUE);
}
break;
Функция ChooseColor запускает диалог в модальном режиме. Это означает, что пользователь не может управлять приложением, пока не завершит диалог. Тактика работы с диалогом такого типа стандартна:
Подготовка данных, инициализирующих поля диалога.
Запуск диалога, ожидание его завершения и проверка результата.
В случае выхода по кнопке ОК, выбор данных из полей вспомогательной структуры.
Использование результатов диалога, например перерисовка окна с учетом нового цвета.
Функция InvalidateRect сообщает системе, что часть окна стала недействительной, то есть требует перерисовки. В ответ на это система посылает приложению сообщение WM_PAINT. Наша оконная процедура уже реагирует на это сообщение, но пока еще не рисует. Теперь создадим команду меню, при выборе которой диалог должен появится на экране. Для этого:
Перейдите в окно Resource View.
Раскройте узел дерева ресурсов под именем Menu.
Выполните двойной щелчок на идентификаторе всей планки меню IDC_API.
В окне редактора меню переведите фокус ввода в окно на планке меню с надписью Type here (Внимание, там два таких окна!).
Введите имя меню Edit и переведите курсор вниз в пустое поле для команды.
Введите имя команды меню Color.
Откройте окно Properties и убедитесь, что команда получила идентификатор ID_EDIT_COLOR.
Перетащите мышью меню Edit на одну позицию влево.
Запустите приложение (Ctrl+F5) и опробуйте команду меню Edit > Color. Диалог имеет две страницы. Для того чтобы убедиться в правильном функционировании статического массива любимых цветов (custColors), раскройте вторую страницу, выберите несколько цветов в ее правой части, нажимая кнопку Add to Custom Colors. Обратите внимание на то, что выбранные цвета попадают в ячейки левой части диалога. Закройте и вновь откройте диалог. Новые цвета должны остаться на месте, так как они сохранились в массиве CustColors.
 
 
 
 
Категория: Visual Studio.Net | Добавил: kompot (08-01-31)
Просмотров: 931 | Комментарии: 3 | Рейтинг: 0.0/0 |
Всего комментариев: 1
1  
Piordmido если по данной теме то пишите прямо тут. Если чтото другое то через гостевую книгу или личные сообщения.

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа

Поиск

Друзья сайта

Статистика


Copyright MyCorp © 2017