Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
65
Добавлен:
10.12.2013
Размер:
324.61 Кб
Скачать

9

ТЕХНОЛОГИИ ПРОГРАММИРОВАНИЯ

ПРОГРАММИРОВАНИЕ В СРЕДЕ VISUAL C++ 6

Лабораторная работа №2

Тема: Мастера Классов ClassWizard.

Цель: Получить практические навыки создания простых Win32 API-приложений в среде Microsoft Visual C++ с использованием мастеров классов..

Основное содержание работы.

Создать с использованием мастера Class Wizard простое приложение Win32 API, в котором рисуются графические фигуры и выводится текст с помощью функций API.

Краткие теоретические сведения

  • Мастер ClassWizard

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

Мастер ClassWizard позволяет добавлять в программу новые классы или изменять существующие. Использовать ClassWizard можно после того, как при помощи AppWizard создан прототип приложения. Доступ к ClassWizard осуществляется через меню View.

Панель ClassWizard Bar выглядит так.

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

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

Список всех членов-функций для данного класса или список всех глобальных функций, выберите одну из них

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

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

Можно выбрать класс, затем функцию класса, либо имя глобальной

функции, щелкните на кнопку “действие по умолчанию” и перейти в

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

реализации выбранной функции. Вы можете изменить что-то в декларации функции или класса.

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

Переход к реализации функции(definition)

или к декларации(описанию) данной ффуфункции(Declarartion)

Добавить в выбранный класс новую функцию или

удалить выбранную с помощью WizardBar функцию класса

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

.

Добавить новый класс

Позволяет переходить от текста реализации одной функции класса к другой в алфавитном порядке.

При удалении какой-либо функции класса с помощью средств Visual C++, сам код функции не удаляется, а только заключается в комментарии; окончательное решение на удаление остается за вами.

Е

Введите здесь тип значения возвращаемого функцией

Введите имя функции +параметры , если они есть

сли вы хотите добавить новую функцию-член класса, то можете воспользоваться средствами либо вкладки ClassView, либо средствами ClassWizard Bar. В любом случае вы увидите следующее окно:

Тип доступа к функции

Если необходимо, выберите тип функции- статическая или виртуальная

Сгенерированная функция всегда появится в декларации класса. В конце того файла, где находится реализация функций данного класса, появится “заготовка” для данной функции- просто пустая функция. Практически аналогично добавление новой переменной в класс. Для этого надо в Workspace Viwer выбрать вкладку Class View и щелкнуть на имени класса правой кнопкой мыши. В появившемся всплывающем меню выбрать пункт Add Member Variable…

Для облегчения внесения в проект данных о новом классе можно воспользоваться средствами, которые предоставляет ClassWizard. Вызвав одну из возможностей с именем New Class, мы получим окно New Class.

В этом окне в поле Class type укажите тип мастера генерации класса. Для приложений типа Win32 Application – это Generic Class.

В группе Class information в поле Name укажите имя нового класса, а в поле File name- имя файла с реализацией данного класса.

В группе Base class в поле Derived From укажите имя базового класса (если новый класс наследуется , а в поле As тип наследования.

При создании класса будет сгенерирован прототип класса, состоящий из определения класса и пустого конструктора и деструктора.

Затем в класс можно добавить члены-данные и члены-функции, как было показано выше.

  • Графический интерфейс устройства (gdi)

Графический интерфейс устройства (Graphics Device Interface-GDI) – это подсистема Windows, отвечающая за работу с графическими устройствами. На системном уровне GDI достаточно сложен и включает в себя более 200 функций. Для выполнения приложением практически любой графической операции необходимы вызовы функций GDI.

Функции GDI- это обычные API функции, однако VC++ предлагает и встроенную поддержку GDI в виде библиотеки классов MFC.

GDI – это графическая библиотека, предназначенная, прежде всего, для решения задач нижнего уровня. GDI находится в полном неведении о проблемах графики интерфейса пользователя, таких как ширина заголовка окна или цвет затененного края кнопки. На вопросы такого сорта отвечает ОС Windows, которая, в свою очередь, используя GDI, размещает графические элементы на экране компьютера. Связующим звеном между программным кодом и областью рисования (drawing area) является контекст устройства.

  • Контекст устройства (dc)

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

Для того, чтобы что-то нарисовать(вывести) необходимо получить контекст устройства (DC). Во всех случаях, кроме обработки сообщения WM_PAINT, для этой цели используется функция GetDC().

HDC GetDC(HWND hWnd);

где hWnd - handle окна

Для получения контекста устройства для обработчика сообщения WM_PAINT используется функция BeginPaint()

HDC BeginPaint(

HWND hwnd, // handle окна

LPPAINTSTRUCT lpPaint // структура, содержащая информацию для рисования в кли-

// ентской области окна

);

За исключением самого первого сообщения WM_PAINT, посылаемого окну при вызове UpdateWindow(), эти сообщения будут посылаться в следующих случаях:

- при изменении размеров окна;

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

- при использовании функции ScrollWindow();

- при принудительной генерации сообщения WM_PAINT вызовом функций InvalidateRect() или InvalidateRgn().

  • Вывод текста

Для вывода текста в области окна можно использовать функции TextOut() и DrawText().

BOOL TextOut(

HDC hdc, // handle to DC

int nXStart, // x-coordinate of starting position

int nYStart, // y-coordinate of starting position

LPCTSTR lpString, // character string

int cbString // number of characters

);

int DrawText(

HDC hDC, // handle to DC

LPCTSTR lpString, // выводимый текст

int nCount, // длина выводимой строки, если передать -1,то длина вычисляется автоматически

LPRECT lpRect, // область, внутри которой будет выведена строка

UINT uFormat // флаги форматирования

);

Пример

RECT Rect;

PAINTSTRUCT ps;

HDC hdc=BeginPaint(hwnd,&ps);

GetClientRect(hwnd,&Rect);

DrawText(hdc,”Простое Win32 Application”, -1, &Rect, DT_SINGLELINE|DT_CENTER| DT_VCENTER);

Для того чтобы установить шрифт надо:

1)Создать структуру типа LOGFONT.

typedef struct tagLOGFONT {

LONG lfHeight; //высота шрифта

LONG lfWidth; //ширина

LONG lfEscapement;// угол, под которым выводится шрифт

LONG lfOrientation; //0

LONG lfWeight; //толщина(0-900)

BYTE lfItalic; //1-курсив

BYTE lfUnderline;// 1-подчеркнуть

BYTE lfStrikeOut; //1-перечеркнуть

BYTE lfCharSet; //символьный набор,0-ANSI char

BYTE lfOutPrecision; //OUT_STROKE_PRECIS

BYTE lfClipPrecision; //CLIP_STROKE_PRECIS

BYTE lfQuality; //DEFAULT_QUALITY

BYTE lfPitchAndFamily;

TCHAR lfFaceName[LF_FACESIZE]; //имя шрифта

} LOGFONT;

В структуре LOGFONT можно просто обнулить все поля, кроме первого и последнего, и тем самым предоставить Windows выбрать значения для всех остальных полей по умолчанию.

Например,

LOGFONT logfont;

logfont.lfHeight =50;

logfont.lfWidth =10;

//….

strcpy(logfont.lfFaceName, "Arial");

//…

2) Создать шрифт вызовом функции CreateFontIndirect() или CreateFont():

HFONT CreateFontIndirect(CONST LOGFONT *lplf);

Например,

HFONT newfont=CreateFontIndirect(&logfont);

3)Установить шрифт в контексте устройства вызовом функции SelectObject():

HGDIOBJ SelectObject(

HDC hdc, // handle to DC

HGDIOBJ hgdiobj // handle to GDI-объекта(в данном случае фонта)

);

Например,

SelectObject(hdc,(HGDIOBJ) newfont);

Если нужно установить цвет букв, отличный от по умолчанию, то вызываем функцию SetTextColor():

COLORREF SetTextColor(

HDC hdc, // handle to DC

COLORREF crColor // цвет символов

);

Например,

SetTextColor(hdc, RGB(255, 0,0));

  • Рисование графических примитивов

Рисование графических примитивов производится с помощью перьев. В Windows есть три предопределенных пера–черное(BLACK_PEN), белое(WHITE_PEN) и прозрачное (NULL_PEN). Handle каждого из них может быть получен с помощью функции GetStockObject(). Создать новое перо можно функцией CreatePen(). После создания пера, необходимо сделать его текущим в контексте устройства. Это делается функцией SelectObject(). После того как мы отработаем с пером, необходимо удалить его, вызвав функцию DeleteObject(). Стили пера определяются константами PS_XXXX.

Для рисования линий и геометрических фигур используются различные функции API:

Линия- LineTo()

Прямоугольник- Rectangle()

Прямоугольник с закругленными краями- RoundRect()

Эллипс- Ellipse()

Дуга- Arc()

Сектор- Pie()

Например,

BOOL Ellipse(

HDC hdc, // handle to DC

int nLeftRect, // x-coord of upper-left corner of rectangle

int nTopRect, // y-coord of upper-left corner of rectangle

int nRightRect, // x-coord of lower-right corner of rectangle

int nBottomRect // y-coord of lower-right corner of rectangle

);

BOOL Rectangle(

HDC hdc, // handle to DC

int nLeftRect, // x-coord of upper-left corner of rectangle

int nTopRect, // y-coord of upper-left corner of rectangle

int nRightRect, // x-coord of lower-right corner of rectangle

int nBottomRect // y-coord of lower-right corner of rectangle

);

После прорисовки замкнутой фигуры, она заливается цветом и атрибутами текущей кисти. Сплошная кисть создается функцией CreateSolidBrush(). Штриховая кисть создается функцией CreateHatchBrush(). Стили штриховки определяются константами HS_XXXX.

После создания кисти, необходимо сделать ее текущей в контексте устройства. Это делается функцией SelectObject().

Например,

1)Создается кисть нужного цвета

long color=RGB(125,125,225);

HBRUSH hNew;

hNew=CreateSolidBrush(color);

2)Устанавливается объект-кисть в контексте устройства

SelectObject(hdc,hNew);

Порядок выполнения работы

Создадим простейшее приложение Win32 с использованием средств Visual C++.

Пусть программа выполняет следующее - рисует одну из геометрических фигур - прямоугольник (при нажатие клавиши 1) или круг (при нажатие клавиши 2), если ни одна из этих клавиш не нажата, то выводится сообщение “Press 1 or 2”. Для этого создадим небольшой класс, инкапсулирующий в себе один из классов объектов GDI- класс контекста устройства(DC), получаемого при обработке сообщения WM_PAINT, а также небольшую иерархию классов для графических объектов типа прямоугольник и круг. Для этого выполним следующее:

1.Запустим VC++. Из меню File выберем пункт New.

Из списка возможных типов проектов, выберем тип проекта Win32 Application, введем имя проекта (например test) и выберем папку, в которой он будет создан.

2.В появившемся окне Win32 Application выберем вид приложения “A simple Win32 application.” AppWizard сгенерирует следующие файлы: StdAfx.h, StdAfx.cpp и файл с “имя_проекта”.cpp(пусть оно будет test.cpp).

Файлы StdAfx.h, StdAfx.cpp содержат служебную информацию о программе, поэтому их лучше не изменять.

Файл test.cpp будет содержать следующие строки

// test.cpp : Defines the entry point for the application.

//

#include "stdafx.h"

int APIENTRY WinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR lpCmdLine,

int nCmdShow)

{

// TODO: Place code here.

return 0;

}

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

Составим на ее основе программу, выполняющею указанную выше работу.

3.Создадим несколько классов- класс инкапсулирующий контекст отображения с именем DCclass, абстрактный базовый класс геометрических фигур с именем figures и два порожденных от него класса circle и rectangle.

Прежде всего создадим класс с именем DCclass. Для этого щелкнем на стрелочке вниз на панели Class Wizard Bar.

4. Из высветившегося списка выберем пункт New Class.

5. В появившемся диалоге New Class введем в поле Name имя класса DCclass, а так как у этого класса нет родительских классов, то в поле Base Classes ничего не вводим.

После нажатия на OK , будут сгенерированны следующие файлы: файл декларации классов DCclass.h и файл исходных кодов класса DCclass.cpp. Посмотрев на вкладку FileView , вы обнаружите эти файлы, они уже добавлены в проект.

6.Изменим аргументы конструктора DCclass::DCclass() на следующие

DCclass::DCclass(HWND hwnd) - это необходимо сделать вручную.

7.Добавим в класс функцию с именем gethdc() и типом возвращаемого значения HDC.

Это можно сделать вручную или с помощью Class Wizard Bar. Сделаем это с помощью Class Wizard Bar. Для этого переключимся на вкладку Classes и щелкнем на имени класса.

8. Из появившегося меню щелкните на Add Member Function. В появившемся диалоге введите в поле Function Type тип возвращаемого значения HDC, в поле- Function Declaration имя функции gethdc и так как аргументов у нее нет, то можно ничего больше не вводить. Если у функции есть аргументы, то их необходимо ввести вместе с именем функции, как обычно мы делаем при объявлении функции. Далее можно выбрать тип функции static или virtual и один из видов доступа к функции public, protected, private. Нажав на Ok вы прикажете Class Wizard сгенерировать декларацию функции с заданным именем и типом в декларации класса.

9.Добавим к этому классу несколько членов-данных. Для этого переключитесь на вкладку Classes и щелкните на имени класса, из появившегося меню щелкните на Add Member Variable. В появившемся диалоге введите в поле Variable Type тип переменной HDC, в поле Variable Name имя переменной hdc и выберите метод доступа protected. Нажав на Ok вы прикажете Class Wizard сгенерировать декларацию переменной с заданным именем и типом в декларации класса.

10.Добавим еще 2 переменные в декларацию класса.

PAINTSTRUCT ps;

HWND hwnd;

Соседние файлы в папке Лабы_длстудентов