Венгерская нотация

advertisement
Лекция 3
(2 курс, осень)
Венгерская нотация
Наверняка, Вы слышали о так называемой Венгерской нотации. Давайте
рассмотрим детальней этот вопрос. При программировании под Windows, мы
сталкиваемся с новыми типами данных, с большими "исходниками". И вот тутто и возникает следующий вопрос: "Как по имени переменной, определить ее
смысловую нагрузку?". Чтобы решить эту проблему программисты Microsoft для
идентификации переменных руководствуются неглассным соглашением,
известным как венгерскамя нотация. Она названа так потому, что ее в Microsoft
популяризировал венгерский программист Чарльз Шимоньи (Charles Simonyi).
В венгерской нотации переменным даются описательные имена, такие как
CustomProgress и FirstButton, начинающиеся с заглавных букв. Если имя
состоит из нескольких слов, каждое слово начинается с заглавной буквы. Затем
перед описательным именем добавляются буквы, чтобы указать тип
переменной. Например, nCustomProgress для типа int и bFlag для переменных
типа bool (понятно - или true, или false). Если придерживаться этих правил, то
программисту будет труднее забыть о типе переменной (но, естественно, не
невозможно) или допустить ошибку связанную с несоответсвием типов при
передаче аргументов в функцию. Будем откровенны, несмотря на то что этот
стиль приобрел широкую популярность, есть определенная группа товарищей,
которые его не поддерживают. Хотя все эти споры подобны дискусии о
расстановке фигурных скобок (открывающую фигурную скобу ставить сразу за
командой, или с новой строки и т.д.).
Тем не менее, реальность такова, что большинство функций WinAPI, и классы,
определенные в MFC, используют венгерскую нотацию, поэтому мы тоже
должны быть знакомы с ней. Важно помнить что венгерская нотация это не
требование (в С++ мало требований...), а всего лишь рекомендация (...зато
много рекомендаций) для написания легкочитаемых пограмм. В венгерской
нотации предлагаются следующие префиксы соответсвенно типам переменных:
Пример префиксов из венгерской нотации
Префикс
Тип переменной
b
Логический тип (bool или BOOL)
i
Целое число (индекс в... )
n
Целое число (количество чего-либо)
u
Целое число без знака
d
Число с двойной точностью
sz
Строковая переменная ограниченная нулем
p
Указатель
lp
Длинный указатель
a
Массив
lpfn
Длинный указатель на функцию
h
Дескриптор
C
Класс
m_
Переменная - член класса (т.е. поле)
Естественно, Вы можете сами дополнить приведенную таблицу префиксами,
которые помогут Вам разобраться в смысловой нагрузке переменных.
Новые типы данных
Итак, вы начали изучать программирование под Windows. Фактически вы
снова в начале пути. А помните с чего всё начиналось на первых уроках?
Конечно же, с переменных и типов данных. Так вот вам снова предстоит
повторить часть вашего обучения! Для создания программ под Windows были
определены новые типы данных. Может возникнуть вопрос, а зачем? Что
старые были чем-то плохи? Нет, просто появилась потребность в переменных
новых типов. Давайте приступим к знакомству с ними:
Новые типы данных:
BOOL
Булевский тип данных. Может принимать одно из двух
значений TRUE или FALSE. Занимает 1 байт.
BYTE
1-байтное целое без знака.
COLORREF
Тип данных, используемый для работы с цветом. Занимает 4
байта.
DWORD
4-х байтное целое или адрес.
LONG
4-х байтное целое со знаком. Это просто переопределение
типа long под Windows.
LPARAM
Переменные этого типа передаются в качестве
дополнительного параметра в функцию-обработчик какого
либо сообщения. В них обычно содержатся информация
специфическая для данного события. Занимает 4 байта.
WPARAM
Всё, что было написано для LPARAM, верно и для WPARAM.
LPCSTR
4-х байтный указатель на константную строку символов.
Указатели с приставкой LP обычно называют длинными
указателями.
LPSTR
4-х байтный указатель строку символов.
UINT
4-х байтное целое без знака.
WORD
2-х байтное целое без знака.
HANDLE
4-х байтное целое, используемое в качестве дескриптора.
Дескриптор (handle по-английски) - это величина, которая
используется в качестве идентификатора какого-то ресурса.
HWND
Дескриптор окна. Проще говоря, идентификатор окна, который
отличает одно окно от другого.
HINSTANCE
Дескриптор экземпляра приложения.Необходим, для того
чтобы отличить один экземпляр приложения от другого ( как
известно Windows позволяет запустить одновременно
несколько экземпляров одного и того же приложения ).
Структура, в которой можно содержать координаты
прямоугольника. В ней есть следующие поля:
LONG left - переменная, в которой должна находиться
координата для левого верхнего угла прямоугольника по оси
X;
RECT
LONG top - переменная, в которой должна находиться
координата для левого верхнего угла прямоугольника по оси
Y;
LONG right - переменная, в которой должна находиться
координата для правого нижнего угла прямоугольника по оси
X;
LONG bottom - переменная, в которой должна находиться
координата для правого нижнего угла прямоугольника по оси
Y.
Структура, в которой определяются координаты точки по оси X
и Y. В ней есть следующие поля:
POINT
LONG x - переменная, в которой должна находиться
координата точки по X;
LONG y - переменная, в которой должна находиться
координата точки по Y.
LPCRECT
4-х байтный указатель на константную структуру типа RECT.
LPRECT
4-х байтный указатель на структуру типа RECT.
Система сообщений Windows:
Вот и наступил исторический момент прощания c легендарным чёрным окном.
Мавр сделал своё дело, мавр может уходить... Жаль, так уходит история, хотя с
другой стороны пора развиваться дальше!!!
Старая и новая концепция программирования:
Все программы, которые были написаны вами до этого момента, имели
структуру программ под DOS (хотя и назывались они консольными
приложениями под Windows). Они использовали традиционный, процедурный
подход к программированию. Что это значит? Программа выполнялась
последовательно от начала (от первой строки функции main) до конца в
предопределенном порядке. Наиболее часто выполняемые блоки программ
выделялись
в
подпрограммы.
Налицо
последовательное
выполнение
программы. Продолжим дальше. Во многих операционных системах
взаимодействие между системой и программой инициализирует программа.
Например, в DOS программа запрашивает разрешение на ввод и вывод данных.
Говоря другими словами, не- Windows-программы (программы, написанные без
использования
архитектуры
Windows-приложения)
сами
вызывают
операционную систему. Операционная система не вызывает прикладную
программу. В Windows-приложениях все совершенно наоборот: именно система
вызывает программу. Этот процесс осуществляется следующим образом:
программа ждет, пока не получит сообщение от Windows.
Сообщение - это сигнал от системы о том, что произошло какое-то событие.
Любое событие, происходящее в системе, будь то создание окна или
перемещение мыши, сопровождается соответствующим сообщением, которое
посылается либо конкретному окну, либо некоторым, либо всем окнам. Иногда
одно событие влечет за собой еще несколько событий и сообщений. Например,
событие создание окна влечет за собой событие перерисовки окна, акивизации
окна, а так же событие создания окна для дочерних окон (кнопок, полей ввода)
и так далее. Сообщение передается программе через специальную функцию,
вызываемую Windows. После того как сообщение получено, программа ищет
функцию-обработчик данного сообщения, если он определен в коде
программы, то выполняется его тело, иначе вызывается стандартный Windowsобработчик (стандартная функция обработки события для этого сообщения).
После завершения обработки сообщения программа ожидает следующего.
Windows может посылать программе сообщения различных типов. Например,
каждый раз при щелчке мышью в окне активной программы посылается
соответствующее сообщение. Другой тип сообщений посылается, когда
необходимо обновить содержимое активного окна. Сообщения посылаются
также при нажатии клавиши, если программа ожидает ввода с клавиатуры.
Необходимо запомнить одно: по отношению к программе сообщения
появляются случайным образом. Вот почему Windows-программы похожи на
программы обработки прерываний: невозможно предсказать, какое сообщение
может появиться в следующий момент. Естественно всё это вносит коррективы
в традиционный, процедурный подход к программированию. Типичная
Windows-программа выполняется нелинейно. Невозможно предсказать, какой
фрагмент кода будет выполняться через минуту. Это связано с тем, что
сообщения приходят в программу абсолютно произвольно. Сообщение
характеризуется номером и двумя числовыми параметрами. Номер сообщения
должен быть уникальным, по крайней мере, в пределах одного приложения.
Чаще всего пользуются мнемоническим обозначением сообщения ( например,
WM_CREATE вместо 0x1 ). Список сообщений находится в файле winuser.h.
Например, типичная строка из этого файла:
#define WM_PAINT 0x000F
Параметры сообщения носят название wParam и lParam. Значения и смысл
этих параметров зависят от конкретного сообщения.
Примеры сообщений:
События мыши:
С мышью связан целый ряд событий и это вполне естественно, так как мышь
является незаменимым механизмом для работы в Windows.
WM_LBUTTONDOWN
Сообщение приходит, когда пользователь нажимает
левую кнопку мышки
Прототип обработчика этого сообщения:
afx_msg void OnLButtonDown( UINT nFlags, CPoint point );
Параметр nflags - показывает, какие кнопки были нажаты,
когда произошло событие.
Префикс afx_msg показывает, что данная функция является обработчиком
какого-то события.
Этот параметр может быть комбинацией следующих значений:
MK_CONTROL
- была нажата кнопка CTRL.
MK_LBUTTON
- была нажата левая кнопка мышки.
MK_MBUTTON
- была нажата средняя кнопка мышки.
MK_RBUTTON
- была нажата правая кнопка мышки.
MK_SHIFT
- была нажата кнопка SHIFT.
Параметр point - содержит координату x и y позиции точки,
где находился указатель мыши в тот момент, когда произошло событие.
Эти координаты считаются относительно левого
верхнего угла окна.
WM_RBUTTONDOWN
Сообщение приходит, когда пользователь нажимает
правую кнопку мышки
Прототип обработчика этого сообщения:
afx_msg void OnRButtonDown( UINT nFlags, CPoint point );
Всё, что было сказано о предыдущем сообщении, верно и для этого.
Сообщение приходит, когда пользователь совершает
двойной щелчок левой кнопки мышки.
WM_LBUTTONDBLCLK
Прототип обработчика этого сообщения:
afx_msg void OnLButtonDblClk( UINT nFlags, CPoint point );
Всё, что было сказано о предыдущем сообщении, верно и для этого.
Сообщение приходит, когда пользователь совершает
двойной щелчок правой кнопки мышки.
WM_RBUTTONDBLCLK
Прототип обработчика этого сообщения:
afx_msg void OnRButtonDblClk( UINT nFlags, CPoint point );
Всё, что было сказано о предыдущем сообщении, верно и для этого.
WM_MOUSEMOVE
Сообщение приходит, когда пользователь передвигает
мышку.
Прототип обработчика этого сообщения:
afx_msg void OnMouseMove( UINT nFlags, CPoint point );
Всё, что было сказано о предыдущем сообщении, верно и для этого.
Событие диалога :
WM_INITDIALOG
Сообщение приходит приложению (в частности, классу,
производному от класса CDialog) перед тем, как диалог
показывается на экран.
Прототип обработчика этого сообщения:
virtual BOOL OnInitDialog( );
Этот обработчик вызывается перед показом на экран диалога.
В нем можно проводить подготовительные мероприятия
(например, инициализацию переменных диалога, настройку необходимых
параметров, вызов функций, которые должны выполняться сразу
после отображения окна диалога на экране и т. п.).
Иерархия классов MFC и Class Wizard
После
долгих
страданий
на
ниве
объектно-ориентированного
программирования, борьбы с классами, обьектами, конструкторами и иже с
ними вы, наконец, добрались до вершины творчества современного
программиста - приложению под Windows. Знакомство с первым образцом
программы такого типа уже произошло. Скорее всего, она повергла вас в
уныние. Столько строк кода ради какого-то окошка. А если таких окошек
понадобится несколько??? Одним словом ужас и кошмар. Да судьба ваша
страшна... Однако не стоит отчаиваться - все не так плохо!!! Можно избежать
той рутины с помощью одного прекрасного средства!!! Нет, не подумайте
ничего плохого!!!
Его название - MFC
MFC - расшифровывается как Microsoft Foundation Classes.
MFC - это библиотека классов, которая призвана упростить жизнь
программисту. Классы, входящие в неё, охватывают большую часть
функциональных возможностей Windows, а также представляют разработчику
значительное количество не только очень мощных дополнительных
возможностей, но и целые механизмы, которые не нарушая идеологии
операционной системы, существенно её расширяют и упрощают. При создании
библиотеки MFC преследовались следующие цели :

Сокращение усилий по программированию приложений под Windows.

Минимальный размер вспомогательного кода.

Скорость выполнения программ, написанных с помощью MFC, должна
быть сопоставима с программами, написанными на языке С с
использованием WIN32 Api.
В реализации библиотеки эти проблемы были решены с блеском.
Подробней об Иерархии классов MFC
Удачный день! Ещё не написали ни одной строчки кода, а уже получили целую
готовую библиотеку классов, проверенную и оттестированную. Давайте
приступим к разбору сего приятного подарка. Внизу изображена сама Иерархия
классов MFC!!!
На первый взгляд выглядит устрашающе, но только на первый!!! Начнем
анализ изображения. Наверху иерархии находится абстрактный базовый класс
CObject. В зависимости от отношения к этому классу все остальные классы
библиотеки MFC можно условно разбить на две группы: классы, производные
от CObject, и классы, не зависящие от него. Большинство классов относятся к
первой группе ( т. е. являются производными от CObject ). Функции и элементы
данных CObject представляют наиболее общие свойства производных от него
классов MFC. Основное назначение этого класса заключается в предоставлении
всем производным классам следующих возможностей:

Хранение информации о классе обьекта во время выполнения.

Поддержка сериализации и диагностики обьекта.
С понятием сериализации вы столкнетесь
наследуются следующие категории классов:
в
дальнейшем.
От
CObject
1. Классы, отвечающие за архитектуру приложения, работу с сообщениями,
окнами, документами. Базовым классом для данной категории является
CCmdTarget.
2. Набор
классов,
реализующий
механизм
обработки
исключений
средствами MFC. Базовый класс для этой группы - CException.
3. Классы, предназначенные для работы с файлами любого типа. Пример
базового класса - CFile.
4. Классы, направленные на работу с контекстом устройства. Базовый класс
- CDC. Классы, представляющие графические обьекты ( кисть, шрифт и т.
д. ). Базовый класс - CGdiObject.
5. Категория вспомогательных классов, например, CImageList.
6. Классы, предназначенные для работы с базами данных.
7. Классы, реализующие типы данных. Например, массивы, списки, хэши.
Примеры классов: CArray, CList, CMap.
8. Другие категории классов, производные от CObject.
Голова может пойти кругом от набора возможностей, рассмотренных выше
классов. Обратимся ко второй группе классов ( !CObject ). В ней находятся
классы, не наследующие CObject. На первых порах вы узнаете о следующих
классах: CString - класс для работы со строками, CPoint - класс для хранения
координат точки, CRect - класс для работы с прямоугольниками. С остальными
классами вы познакомитесь в процессе обучения.
Class Wizard
Class Wizard - это специальная утилита, входящая в состав среды Visual C++.
С её помощью можно создавать обработчики сообщений, новые классы,
добавлять переменные и делать многое другое. Class Wizard активизируется по
нажатию CTRL+W на клавиатуре или через главное меню View->ClassWizard.
Внешний вид:
С помощью первой вкладки Message Maps вы можете создавать обработчики
сообщений, новые классы.
1. В выпадающем списке Project стоит имя активного проекта.
2. В выпадающем списке Class Name содержатся все классы, которые есть в
программе.
3. В списке Object IDs находится название выбранного в списке Class Name
класса и ID элеменов управления, связанных с ним.
4. В списке Messages находятся сообщения доступные для активного класса
и элементов, связанных с ним.
5. В списке Member functions находятся названия сообщений, для которых
уже созданы обработчики в текущем классе.
Например, вы хотите создать обработчик сообщения WM_LBUTTONDBLCLK для
класса диалога.
1. Выбрать название класса диалога в выпадающем списке Class name.
2. Выбрать название класса диалога в списке Object IDs.
3. Найти название сообщения в списке Messages и выбрать его.
4.
Примечание:
5.
сообщения, выделенные жирным шрифтом, уже имеют соответствующие
обработчики в текущем проекте.
6. Нажать на кнопку Add Function.После этого добавится функция
обработчик этого сообщения.Она появится в списке под названием
Member
functions.
7. Для редактирования тела обработчика нужно нажать кнопку Edit Code.
В следующих уроках вы продолжите знакомство с Class Wizard.
Необходимые понятия и определения
Этот раздел познакомит вас с основной терминалогией Windows, которую вы
будете встречать в текстах наших уроков и в любой технической литературе.
Окно (Window) - прямоугольная область экрана для организации обмена
данными между пользователем и приложением. Окно совместно использует
экран с другими окнами, в том числе и с окнами других приложений.
Одновременно пользователь может осуществлять ввод только в одно окно
приложения, к которому это окно относится.
На следующем рисунке изображены основные и дополнительные элементы
окна
Диалоговое окно или блок диалога (Dialog Box) - временное окно, создаваемое
для запроса ввода пользователя. Блоки диалога обычно содержат некоторое
количество элементов управления, позволяющих ввести текст, выбрать режим
и т. д. (элементы управления будут рассматриваться позднее). Диалоги могут
быть модальными и немодальными. Модальные диалоги служат для ввода
пользователем некоторых данных или ответа на вопрос, необходимого для
продолжения работы. Остальные элементы (окна) приложения при этом
недоступны. Немодальные диалоги служат для постоянного отображения на
экране, например, для быстрого изменения какого-либо параметра и
немедленной реакции приложения на него.
Ресурсы приложения - данные, которые обычно хранятся в отдельном(-ых)
файле(-ах) и включаются в выполняемый файл лишь на этапе компоновки.
Перечислим
приложений:
ресурсы,
которые
являются
стандартными
для
Windows-

Акселераторы (accelerators) - структуры данных, содержащие списки
горячих клавиш и команд, ассоциированных с ними

Битовые массивы (bitmaps) - массивы точек для отображения на экране
(картинки)

Курсоры (cursors) - битовые массивы,
растровых изображений указателя мыши

Шаблоны диалогов (dialogs) - структуры, описывающие окно диалога,
включая элементы управления, оконные стили, положение на экране
(координаты) и другие параметры. Используются для вывода диалоговых
окон на экран
используемые
в
качестве

Значки (icons) - битовые массивы, которые используются для
визуального представления различных объектов в системе - приложений,
документов и т. д.

Шаблоны меню (menus) - описывают
задаваемыми пользователем командами

Строковые таблицы (string tables) - списки статических символьных
массивов

Шаблоны панелей инструментов (toolbars) - описывают элементы
управления, состоящие из набора битовых массивов в качестве кнопок,
каждая из которых связана с определенной командой

Описания версий (version) - статические структуры специального вида,
содержащие информацию о программе, включая имя приложения, номер
версии, информацию об авторских правах и т. п. Используются
операционной системой для вывода информации о программе
пункты
меню,
связанные
с
Примечание:
Доступ к ресурсам осуществляется по числовым или строковым
идентификаторам, описанным в файле Resource.h (см. следующий раздел).
В следующем разделе будет представлен процесс создания наиболее простого
Windows-приложения - приложения, основанного на базе модального
диалогового окна (т. е. диалоговое окно будет выступать в качестве главного
окна приложения).
Создание диалоговых приложений
Для создание Windows-приложения на базе MFC необходимо выполнить
следующие шаги:

Создать новый проект, за основу которого вам необходимо будет выбрать
пункт MFC AppWizard (exe)

Далее выбирается имя проекта (Project Name) и месторасположение
проекта (Location)

Нажимаем кнопку OK и переходим к следующему окну

Выбираем диалоговое приложение и жмем на кнопку Next

В появившемся окне можно отжать галочку ActiveX Controls - сейчас она
нам не нужна - и, по желанию, можно отключить окно диалога About,
которое обычно отображает информацию о приложении и его
разработчике. Можно также задать заголовок нашего приложения. Затем
снова жмем на кнопку Next

Теперь можно указать требуются ли нам автоматически создаваемые
комментарии. Также имеется возможность указать как будет создаваться
приложение: с помощью разделяемых библиотек или с помощью
статически скомпонованых библиотек. В первом случае выполняемый
файл (*.exe) будет сравнительно небольшим, но приложение будет
работать лишь в том случае, когда на компьютере пользователя
установлены необходимые библиотеки; во втором случае приложение
будет работать везде, но размер выполняемого файла увеличится в
несколько раз. И снова кнопка Next

В этом окне можно выбрать имена для класса приложения и оконного
класса. После того как вы примете соответствующее решение - жмите
кнопку Finish.

Вам отображается суммарная информация о проекте. Если ваше терпение
все еще не иссякло - нажмите кнопку OK и посмотрите на творение рук
ваших...
Примечание:
если на каком-то этапе создания проекта вы согласны с установками по
умолчанию на последующих этапах, то сразу нажимайте кнопку Finish;
если же вы в какой-то момент вы захотите вернуться на предыдущий этап
жмите кнопку Back;
для отмены создания проекта существует кнопка Cancel.
Далее вашему вниманию предоставляется краткий обзор автоматически
сгенерированного кода для вашего диалогового приложения.
Краткий обзор кода, который
автоматически генерируется для
диалогового приложения
Итак, как вы можете заметить, щелкнув по вкладке FileView (слева), Class
Wizard создал для вас 7 файлов:

Resource.h - файл описания ресурсов, который содержит определения
идентификаторов элементов управления (каждому идентификатору
присваивается целочисленная константа)

First.h (имя файла обычно совпадает с названием проекта, но это совсем
не обязательно) - заголовочный файл класса приложения

First.cpp - исходный файл класса приложения

FirstDlg.h - заголовочный файл класса окна

FirstDlg.cpp - исходный файл класса окна

StdAfx.h - заголовочный файл, включающий стандартные системные
заголовочные файлы и заголовочные файлы, специфические для данного
проекта

StdAfx.cpp - исходный файл, содержащий только
подключения (содержит строку #include "stdafx.h")
стандартные
Рассмотрим код классов приложения и окна
Файл First.h
// First.h : main header file for the FIRST application
//
#if !defined(AFX_FIRST_H__DA4A2945_6FFD_11D5_BB2A_90C85119D547__INCLUDED_)
#define AFX_FIRST_H__DA4A2945_6FFD_11D5_BB2A_90C85119D547__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include "resource.h"
// main symbols
// Основные символические константы
//////////////////////////////////////////////////////////////////////
// CFirstApp:
// See First.cpp for the implementation of this class
// Реализация данного класса смотри First.cpp
class CFirstApp : public CWinApp
{
public:
CFirstApp();
// Overrides
// ClassWizard generated virtual function overrides
// Переопределение виртуальных функций, сгенерированных Class Wizard
//{{AFX_VIRTUAL(CFirstApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CFirstApp)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
// ВНИМАНИЕ - здесь Class Wizard вставляет и удаляет функции класса
// НЕ ИЗМЕНЯЙТЕ этих частей сгенерированного кода !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
// Макрос, определяющий очередь сообщений
};
//////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations
// immediately before the previous line.
#endif
Файл First.cpp
// First.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "First.h"
#include "FirstDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//////////////////////////////////////////////////////////////////////
// CFirstApp
// Начало очереди сообщений
BEGIN_MESSAGE_MAP(CFirstApp, CWinApp)
//{{AFX_MSG_MAP(CFirstApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
// Конец очереди сообщений
//////////////////////////////////////////////////////////////////////
// CFirstApp construction
CFirstApp::CFirstApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
// Добавьте код конструктора
// Инициализация наиболее важных переменных и функций
// должна выполнятся в InitInstance
}
//////////////////////////////////////////////////////////////////////
// The one and only CFirstApp object
// Один и только один экземпляр приложения
CFirstApp theApp;
//////////////////////////////////////////////////////////////////////
// CFirstApp initialization
BOOL CFirstApp::InitInstance()
{
// Функция отвечает за инициализацию экземпляра приложения
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
// Стандартная инициализация
// Если вы не пользуетесь какими-либо функциями и желаете сократить
// размер выполняемого файла, удалите ненужные процедуры инициализации
#ifdef _AFXDLL
Enable3dControls();
DLL
// Call this when using MFC in a shared
// Если используются разделяемые библиотеки
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
// Если используется статическая компоновка
#endif
CFirstDlg dlg;
m_pMainWnd = &dlg;
// Объект диалога
// Данный объект является главным окном
int nResponse = dlg.DoModal();
// Отображение диалога
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
// Если для закрытия окна пользователь нажал OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
//
dismissed with Cancel
// Если для закрытия окна пользователь нажал Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
//
application, rather than start the application's message pump.
return FALSE;
}
Файл FirstDlg.h
// FirstDlg.h : header file
//
#ifndef (AFX_FIRSTDLG_H__DA4A2947_6FFD_11D5_BB2A_90C85119D547__INCLUDED_)
#define AFX_FIRSTDLG_H__DA4A2947_6FFD_11D5_BB2A_90C85119D547__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
//////////////////////////////////////////////////////////////////////
// CFirstDlg dialog
class CFirstDlg : public CDialog
{
// Construction
public:
CFirstDlg(CWnd* pParent = NULL); // standard constructor
// Стандартный конструктор
// Dialog Data
//{{AFX_DATA(CFirstDlg)
enum { IDD = IDD_FIRST_DIALOG };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CFirstDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Поддерожка DDX/DDV
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CFirstDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
Файл FirstDlg.cpp
// FirstDlg.cpp : implementation file
//
#include "stdafx.h"
#include "First.h"
#include "FirstDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
// Класс диалога About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX);
//}}AFX_VIRTUAL
// Implementation
protected:
// DDX/DDV support
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//////////////////////////////////////////////////////////////////////
// CFirstDlg dialog
CFirstDlg::CFirstDlg(CWnd* pParent /*=NULL*/)
: CDialog(CFirstDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CFirstDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon doesn't require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
// Загрузка пиктограммы приложения
}
void CFirstDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CFirstDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
// Начало очереди сообщений диалогового класса
BEGIN_MESSAGE_MAP(CFirstDlg, CDialog)
//{{AFX_MSG_MAP(CFirstDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// Конец очереди сообщений
//////////////////////////////////////////////////////////////////////
// CFirstDlg message handlers
// Обработчики сообщений диалогового класса
BOOL CFirstDlg::OnInitDialog()
{
// Переопределяемая функция для инициализации
// элементов диалогового окна.
// Вызывается до появления окна на экране
CDialog::OnInitDialog();
// Стандартный обработчик
// Add "About..." menu item to system menu.
// Добавление пункта About... в системное меню
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog.
//
The framework does this automatically
when the application's main window is not a dialog
// Установка пиктограммы приложения
SetIcon(m_hIcon, TRUE);
// Set big icon
SetIcon(m_hIcon, FALSE);
// Set small icon
// TODO: Add extra initialization here
// Здесь пользователь может вставить собственный вариант инициализации
// диалогового окна, например, вызвать какую-нибудь функцию, установить
// начальные значение каких-то параметров и т. п.
return TRUE;
// return TRUE
unless you set the focus to a control
// Если возвращается истина, то фокус уснавливается на первый элемент
// управления, если нет - на элемент, указанный пользователем
}
void CFirstDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
// Обработчик выбора системного меню
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
// Создание объекта окна
dlgAbout.DoModal();
// Отображение окна
}
else
{
// Стандартный обработчик
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code
// below to draw the icon.
For MFC applications using the document/view
// model, this is automatically done for you by the framework.
void CFirstDlg::OnPaint()
{
// Функция отвечает за перерисовку пиктограммы приложения,
// если на диалоге присутствует кнопка минимизации
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
// Объект прямоугольник
// Заполнение прямоугольника координатами клиентской области окна
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user
// drags the minimized window.
// Вызывается системой для получения указателя, отображаемого при
// перетаскивании свернутого окна
HCURSOR CFirstDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
Примечание:
Старайтесь, по возможности, прислушиваться к советам Class Wizard'а.
Часто встречаемые классы.
CPoint, CSize, CRect, CString
В данном разделе вы познакомитесь с наиболее употребительными функциями
вышеприведенных классов.
Класс CPoint // Точка
CPoint();
// Конструктор по умолчанию
CPoint( int initX, int initY );
// Конструктор с координатами
CPoint( POINT initPt );
// Конструктор с параметром точка
CPoint( SIZE initSize );
// Конструктор с параметром размер
void Offset( int xOffset, int yOffset );
// Прибавление
void Offset( POINT point );
// координат
void Offset( SIZE size );
// к точке
BOOL operator ==( POINT point ) const;
// Сравнение двух точек
// (true - равны)
BOOL operator !=( POINT point ) const;
// Сравнение двух точек
// (true - неравны)
Данные-члены:
X, Y - координаты
Класс CSize // Размер
CSize( );
// Конструктор по умолчанию
CSize( int initCX, int initCY );
// Конструктор с размерами
CSize( SIZE initSize );
// Конструктор с параметром размер
CSize( POINT initPt );
// Конструктор с параметром точка
BOOL operator ==( SIZE size ) const; // Сравнение двух размеров
// (true - равны)
BOOL operator !=( SIZE size ) const; // Сравнение двух размеров
// (true - неравны)
void operator +=( SIZE size );
// Добавление размера
void operator -=( SIZE size );
// Вычитание размера
CSize operator +( SIZE size ) const;
// Сложение двух размеров
CPoint operator +( POINT point ) const; // Добавление размера к точке
// (перенос точки)
CSize operator -( SIZE size ) const;
// Вычитание двух размеров
CPoint operator -( POINT point ) const; // Вычитание размера из точки
// (перенос точки)
Данные-члены:
cx - ширина, cy - высота
Класс CRect // Прямоугольник
CRect( );
// Конструктор по умолчанию
CRect( int l, int t, int r, int b );
// Конструктор с параметрами
// лево, верх, право, низ
CRect( const RECT& srcRect );
// Конструктор с параметром ссылка
// на структуру RECT
CRect( LPCRECT lpSrcRect );
// Конструктор с параметром
// указатель на структуру RECT
CRect( POINT point, SIZE size );
// Конструктор с параметрами левая
// верхняя точка и размер (ширина и высота прямоугольника)
CRect( POINT topLeft, POINT bottomRight );
// Конструктор с параметрами
// левая верхняя точка и правая нижняя точка
int Width( ) const;
// Ширина прямоугольника
int Height( ) const;
// Высота прямоугольника
CSize Size( ) const;
// Функция, вычисляющая размера прямоугольника,
// желательно предварительно вызвать функцию NormalizeRect
CPoint& TopLeft( );
// Вычисление верхней левой точки прямоугольника
CPoint& BottomRight( ); // Вычисление нижней правой точки прямоугольника
CPoint CenterPoint( ) const;// Вычисление центральной точки прямоугольника
BOOL IsRectEmpty( ) const;
// Возвращает истину, если прямоугольник пуст
// (ширина и/или высота прямоугольника <= 0)
// желательно предварительно вызвать функцию NormalizeRect
BOOL IsRectNull( ) const;
// Возвращает истину, если все параметры = 0
BOOL PtInRect( POINT point ) const; // Возвращает истину, если точка
// лежит внутри прямоугольника
void SetRect( int x1, int y1, int x2, int y2 ); // Установка размера
// и координат
void SetRectEmpty( );
// Установка всех координат прямоугольника в 0
void CopyRect( LPCRECT lpSrcRect );
// Копирование переданного
// прямоугольника
void operator =( const RECT& srcRect );
// Присваивание прямоугольников
BOOL EqualRect( LPCRECT lpRect ) const;
// Возвращают истину, если
BOOL operator ==( const RECT& rect ) const;// прямоугольники совпадают
// желательно предварительно вызвать функцию
// NormalizeRect для обоих прямоугольников
void InflateRect( int x, int y );
// Увеличивают размер
void InflateRect( SIZE size );
// прямоугольника, двигая
void InflateRect( LPCRECT lpRect );
// границы относительно
void InflateRect( int l, int t, int r, int b );// центральной точки
void DeflateRect( int x, int y );
// Уменьшают размер
void DeflateRect( SIZE size );
// прямоугольника, двигая
void DeflateRect( LPCRECT lpRect );
// границы относительно
void DeflateRect( int l, int t, int r, int b );// центральной точки
void NormalizeRect( );
// Нормализует координаты прямоугольника,
// т. е. ширина и высота становятся положительными, если левая сторона
// имеет координату > правой, то они меняются местами, то же самое
// относится к верхней и нижней сторонам прямоугольника
void OffsetRect( int x, int y );
// Сдвигают прямоугольник
void OffsetRect( POINT point );
// в заданную
void OffsetRect( SIZE size );
// позицию
BOOL SubtractRect( LPCRECT lpRectSrc1, LPCRECT lpRectSrc2 );
// Возвращает истину, если операция прошла успешно;
// вычитает прямоугольник lpRectSrc2 из lpRectSrc1 (т. е. создает
// прямоугольник который состоит из всех точек из lpRectSrc1,
// не входящих в lpRectSrc2). Прямоугольнику присваивается lpRectSrc1,
// если результат вычитания не является прямоугольником.
// Желательно предварительно вызвать функцию
// NormalizeRect для обоих прямоугольников
BOOL IntersectRect( LPCRECT lpRect1, LPCRECT lpRect2 );
// Возвращает истину, если пересечение не пусто.
// Создает прямоугольник, равный пересечению прямоугольников
// lpRect1 и lpRect2.
// Желательно предварительно вызвать функцию
// NormalizeRect для обоих прямоугольников
BOOL UnionRect( LPCRECT lpRect1, LPCRECT lpRect2 );
// Возвращает истину, если объединение не пусто.
// Создает прямоугольник, равный объединению прямоугольников
// lpRect1 и lpRect2.
// Желательно предварительно вызвать функцию
// NormalizeRect для обоих прямоугольников
Данные-члены:
left - левая сторона
right - правая сторона
top - верхняя сторона
bottom - нижняя сторона
Класс CString // Строка
CString( );
// Конструкторы
CString( const CString& stringSrc );
CString( TCHAR ch, int nRepeat = 1 );
CString( LPCTSTR lpch, int nLength );
CString( const unsigned char* psz );
CString( LPCWSTR lpsz );
CString( LPCSTR lpsz );
int GetLength( ) const;
// Возвращает количество байт в строке
BOOL IsEmpty( ) const;
// Возвращает истину, если в строке 0 байт
void Empty( );
// Очистка строки
TCHAR GetAt( int nIndex ) const;
// Получение элемента строки
TCHAR operator []( int nIndex ) const;
// по заданному индексу
void SetAt( int nIndex, TCHAR ch );
// Замена элемента строки
// по заданному индексу
// Сравнение строк с учетом регистра
BOOL operator ==( const CString& s1, const CString& s2 );
BOOL operator ==( const CString& s1, LPCTSTR s2 );
BOOL operator ==( LPCTSTR s1, const CString& s2 );
BOOL operator !=( const CString& s1, const CString& s2 );
BOOL operator !=( const CString& s1, LPCTSTR s2 );
BOOL operator !=( LPCTSTR s1, const CString& s2 );
BOOL operator <( const CString& s1, const CString& s2 );
BOOL operator <( const CString& s1, LPCTSTR s2 );
BOOL operator <( LPCTSTR s1, const CString& s2 );
BOOL operator >( const CString& s1, const CString& s2 );
BOOL operator >( const CString& s1, LPCTSTR s2 );
BOOL operator >( LPCTSTR s1, const CString& s2 );
BOOL operator <=( const CString& s1, const CString& s2 );
BOOL operator <=( const CString& s1, LPCTSTR s2 );
BOOL operator <=( LPCTSTR s1, const CString& s2 );
BOOL operator >=( const CString& s1, const CString& s2 );
BOOL operator >=( const CString& s1, LPCTSTR s2 );
BOOL operator >=( LPCTSTR s1, const CString& s2 );
int Compare( LPCTSTR lpsz ) const; // Сравнение строк
// возвращает 0, если строки равны; > 0, если строка > lpsz;
// < 0, если строка < lpsz
int CompareNoCase( LPCTSTR lpsz ) const;
// То же самое, но без учета регистра
CString Mid( int nFirst ) const; // Возвращает символы, начиная
// с позиции nFirst
CString Mid( int nFirst, int nCount ) const;
// Возвращает nCount символов, начиная с позиции nFirst
CString Left( int nCount ) const;
// Возвращает nCount символов слева
CString Right( int nCount ) const;
// Возвращает nCount символов справа
void MakeUpper( );
// Переводит строку в верхний регистр
void MakeLower( );
// Переводит строку в нижний регистр
void MakeReverse( );
// Переворачивает строку
int Replace( TCHAR chOld, TCHAR chNew );// Замена символов chOld на chNew,
// возвращается количество проведенных замен или 0, если их не было.
int Replace( LPCTSTR lpszOld, LPCTSTR lpszNew );
// То же самое, только происходит замена подстроки lpszOld на lpszNew.
int Remove( TCHAR ch ); // Удаляет символ ch из строки, возвращает
// количество удаленных символов или 0, если удалений не было.
int Insert( int nIndex, TCHAR ch );
// Вставка символа в позицию nIndex, возвращает длину измененной строки
int Insert( int nIndex, LPCTSTR pstr );
// Вставка подстроки в позицию nIndex, возвращает длину измененной строки
int Delete( int nIndex, int nCount = 1 ); // Удаление nCount символов,
// начиная с позиции nIndex, возвращает количество удаленных символов
int Find( TCHAR ch ) const;
// Поиск символа
int Find( LPCTSTR lpszSub ) const;
// Поиск подстроки
int Find( TCHAR ch, int nStart ) const;
// Поиск символа с позиции nStart
int Find( LPCTSTR pstr, int nStart ) const;
// Поиск подстроки с позиции nStart
// функции возвращают индекс найденного элемента (индекс начинается с 0)
// или -1, если элементы найдены не были
void Format( LPCTSTR lpszFormat, ... );
// Форматированный вывод в строку
// Общий формат представляется в виде:
// %[flags] [width] [.precision] [{h | l | I64 | L}]type
// здесь type:
// c - Символ
// d, i - целое знаковое число
// o - беззнаковое восьмеричное число
// x - беззнаковое шестнадцатиричное число, используются "abcdef"
// X - беззнаковое шестнадцатиричное число, используются "ABCDEF"
// u - беззнаковое десятичное число
// e - знаковое вещественное число в научной нотации
// f - знаковое вещественное число
// g - в зависимости от ситуации представляется в виде форматов e и f
// n - указатель на целое
// p - указатель на void
// s - строка
// flags:
// - - выравнивание по левому краю (по умолчанию по правому)
// + - если выводимые числа знаковые, то у них будет появляться знак (+/-)
// width - ширина поля вывода
// precision:
// тип с - не дает эффекта
// типы d, i, o, u, x, X - минимальное количество выводимых цифр,
// если цифр меньше, то число дополняется нулями
// тип e - количество цифр, которое распечатается после десятичной точки,
// последняя цифра округляется
// тип f - количество цифр после десятичной точки, как минимум одна цифра
// появится до запятой, число округляется до заданного количества цифр
// тип g - максимальное количество печатаемых значащих цифр
// тип s - максимальное количество печатаемых символов
Причер использования:
CString s;
int hour = 1, min = 12;
s.Format("Hello, World !\r%d:%d", hour, min);
Окна сообщений
Учитывая тот факт, что материл, который мы с Вами разбираем на этом уроке
абсолютно новый для Вас, можно предположить что у Вас появился вопрос:
"Что такое окно с сообщением?". Вы сто процентов сталкивались с ним при
повседневной работе с Windows. Как один из вариантов можно привести
пример следующего окна:
Итак, теперь, зная о чем идет речь, давайте научимся самостоятельно
создавать такие окна. Для этого рассмотрим функцию, которая позвляет
вывести окно c сообщением:
int AfxMessageBox(LPCTSTR lpszText, UINT nType=MB_OK, UINT nIDHelp=0);
Данная функция выводит в окно сообщения строку lpszText и использует
идентификатор nIDHelp для перехода к соответсвующей теме справки при
нажатии клавиши <F1> (заметим, что на данный момент параметр nIDHelp не
предоставляет для нас практического интереса. Поэтому отложим исследование
этого момента до рассмотрения темы, посвященной созданию справочной
системы). Параметр nType задает тип окна сообщений и может принимать одно
из следующих значений:
Возможные типы окна сообщения
Значение параметра
nType
Описание
MB_OK
Окно содержит только кнопку OK
MB_OKCANCEL
Окно содержит две кнопки: OK и Cancel (Отмена)
MB_RETRYCANCEL
Окно содержит две кнопки: Retry и Cancel (Повтор
и Отмена)
MB_ABORTRETRYIGNORE
Окно содержит три кнопки: Abort, Retry и Ignore
(Стоп, Повтор и Пропустить)
MB_YESNO
Окно содержит две кнопки: Yes и No (Да и Нет)
MB_YESNOCANCEL
Окно содержит три кнопки: Yes, No и Cancel (Да,
Нет и Отмена)
Если Вы хотите также добавить иконку в информационное окно, Вы можете
комбинировать указанные значения параметра nType с нижеследующими:
MB_ICONEXCLAMATION
(иконка
-восклицательный
знак),
MB_ICONINFORMATION (или MB_ICONASTERISK; иконка - символ "i"),
MB_ICONQUESTION (иконка - знак вопроса), MB_ICONSTOP (или
MB_ICONHAND; иконка - "стоп").
Вы можете также назначить кнопку по умолчанию, если вы используете
информационное окно с несколькими кнопками. Визуально, мы всегда можем
определить кнопку по умолчанию по затемненному контуру вокруг кнопки. Для
назначения кнопки по умолчанию, используйет соответсвенно одну из
констант:
MB_DEFBUTTON1
(кнопка
по
умолчанию
первая),
MB_DEFBUTTON2 (вторая) или MB_DEFBUTTON3 (третья).
Ниже приводиться рисунок, иллюстрирующий использование констант:
MB_ABORTRETRYIGNORE (три кнопки в окне сообщений), MB_ICONSTOP
(иконка в виде запрещающего креста), MB_DEFBUTTON2 (кнопка "Повторить"
назначена кнопкой по умолчанию). Окно было получено в результате вызова
функции:
AfxMessageBox("Используемые
константы:
MB_ABORTRETRYIGNORE|MB_ICONHAND|MB_DEFBUTTON2",
MB_ABORTRETRYIGNORE|MB_ICONHAND|MB_DEFBUTTON2);
Функция возвращает одно из следующих значений:
Описание возвращаемого значения
Значение
Описание
IDOK
Была нажата кнопка OK
IDCANCEL
Была нажата кнопка Cancel (или клавиша <Esc>)
IDABORT
Была нажата кнопка Abort
IDIGNORE
Была нажата кнопка Ignore
Описание возвращаемого значения
Значение
Описание
IDYES
Была нажата кнопка Yes
IDNO
Была нажата кнопка No
IDRETRY
Была нажата кнопка Retry
0
Произошла ошибка при создании окна сообщений
Итак, солидный багаж знаний по окнам сообщений у Вас уже есть. Теперь
немного о том, как и когда необходимо использовать окна сообщений? На
вопрос "Когда?" ответ очевиден. Когда Вам необходимо предоставить
пользователю запрос или сообщить пользователю о какой-то приятной новости,
обычно, Вы будете использовать окна сообщений. Например, следующий
фрагмент кода демонстрирует использование окна сообщений:
if (AfxMessageBox("Удаляем все файлы?",
MB_YESNO|MB_DEFBUTTON2|MB_ICONQUESTION)
== IDYES){
//удаляем все файлы
}
Заметим, что для вывода окна сообщения Вы можете также воспользоваться
функцией
int
MessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption=NULL, UINT nType=MB_OK);
Данная функция принимает lpszText в качестве строки сообщения, lpszCaption
- заголовок окна сообщения, nType - стили окна сообщений (см.
AfxMessageBox).
Основное различие между указанными функциями состоит в том, что функцию
MessageBox возможно вызвать только при наличии главного окна. Еще одно
отличие состоит в том, что функция MessageBox может создавать окна
сообщений с произвольным заголовком, тогда как функция AfxMessageBox в
качестве заголовка использует название приложения.
Домашнее задание
1. Вывести
на
экран
свое
(краткое
!!!)
резюме
с
помощью
последовательности MessageBox'ов (числом не менее трех). Причем на
заголовке последнего должно отобразиться среднее число символов на
странице (общее количество символов в резюме / количество
MessageBox'ов).
2. Написать функцию, которая "угадывает" задуманное пользователем
число от 1 до 2000. Для запроса к пользователю использовать
MessageBox. После того, как число отгадано, необходимо вывести
количество запросов, потребовавшихся для этого, и предоставить
пользователю возможность сыграть еще раз, не выходя из программы.
(MessageBox'ы оформляются кнопками и значками соответственно
ситуации).
3. Представьте, что у вас на форме есть прямоугольник, границы которого
на 10 пикселей отстоят от границ рабочей области формы.
Информацию о размере рабочей области окна можно получить, воспользовавшись
функцией void GetClientRect( LPRECT lpRect ) const. Параметром этой функции
служит адрес объекта типа CRect. Функция заполняет поля этого объекта.
Необходимо создать следующие обработчики:
1. Обработчик нажатия левой кнопки мыши (OnLButtonDown),
который выводит сообщение о том, где находится текущая точка:
внутри прямоугольника, снаружи, на границе прямоугольника.
Если при нажатии левой кнопки мыши была нажата кнопка Control
(Ctrl), то приложение должно закрываться.
Для этого воспользуйтесь функцией void EndDialog( int nResult ), где nResult
- произвольный целочисленный параметр, которыйвозвращается в точку вызова
функции отображения диалога DoModal.
2. Обработчик нажатия правой кнопки мыши (OnRButtonDown),
который выводит в заголовок окна информацию о размере
клиентской (рабочей) области окна в виде: Ширина = x, Высота =
y, где x и y - соответствующие параметры вышего окна.
Для вывода информации в заголовок
SetWindowText( LPCTSTR lpszString );
окна
воспользуйтесь
функцией
void
3. Обработчик перемещения указателя мыши в пределах рабочей
области (OnMouseMove), котовый должен выводить в заголовок
окна текущие координаты мыши x и y.
Download