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

Технологии программирования. Программирование графических интерфейс

.pdf
Скачиваний:
3
Добавлен:
15.11.2022
Размер:
2.24 Mб
Скачать

14.Как называется ввод в Windows-программу?

15.Каковы три основные части функции WinMain?

16.Каждое основное окно приложения должно обязательно обрабатывать одно сообщение. Что это за сообщение?

17.Что такое WNDCLASS? Где используется?

18.КаковаразницамеждуShowWindow() иUpdateWindow()?

19.Какой тип стандартного Си ассоциируется с WORD?

20.Какой тип стандартного Си ассоциируется с HWND?

21.Какой тип стандартного Си ассоциируется с HIN-

STANCE?

22.Какой тип стандартного Си ассоциируется с UINT?

23.Какой тип стандартного Си ассоциируется с LONG?

24.Какойтипстандартного Си ассоциируется сLPLONG?

25.Что происходит, если вы не обрабатываете явно сообщениявнутриоконной функции?

26.Как вызывается оконная функция?

Упражнения

1.Включите в программу обработку двойного щелчка.

2.Уберите из окна кнопки справа.

3.Измените цвет фона окна.

4.Сделайте так, чтобы при запуске окно было свернутым.

5.Замените в диалоговом боксе кнопки OK и CANCEL на YES и NO и сделайте кнопку NO кнопкой по умолчанию.

6.Измените заголовок окна на «Простейшее Windowsприложение».

7.Сделайте так, чтобы при нажатии левой кнопки мыши выводился текст «Работу выполнил <Ф.И.О>», а при нажатии правой кнопки текст «Простейшее Windows-приложение».

8.Измените структуру программы так, чтобы она вклю-

чала функции MyRegisterClass() и InitInstanse(), которые вы-

зываются в функцииWinMain().

9.Измените иконку и курсор главного окна.

10.Измените стиль главного окна.

31

2.ПРОГРАММИРОВАНИЕ ГРАФИКИ

2.1.Графический интерфейс устройства (GDI)

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

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

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

2.2. Контекст устройства (DC)

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

32

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

Для того чтобы что-то нарисовать (вывести), необходимо получить контекст устройства (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().

33

2.3. Вывод текста

Для вывода текста в области окна можно использовать функции:

TextOut() и DrawText().

BOOL TextOut(

HDC hdc, // handle контекста устройства

int nXStart, // x – координатаначальной позициивывода int nYStart, // y – координата начальной позициивывода LPCTSTR lpString, // выводимая строка

int cbString // длина строки

);

int DrawText(

HDC hDC, // handle контекста устройства LPCTSTR lpString, // выводимый текст

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

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

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

);

Пример 2.1

RECT Rect; PAINTSTRUCT ps;

HDC hdc=BeginPaint(hwnd,&ps); GetClientRect(hwnd,&Rect);

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

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

34

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;

memset(&logfont,0,sizeof(LOGFONT)); logfont.lfHeight =50;

logfont.lfWidth =10; //….

strcpy(logfont.lfFaceName, "Arial");

//…

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

Например:

//получаем хэндл текущего шрифта, используемого для рисования

35

HFONT usedfont=(HFONT)::GetCurrentObject(hdc, OBJ_FONT); //получаем информацию об используемом шрифте

GetObject((HGDIOBJ) usedfont, sizeof(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 контекста устройства HGDIOBJ hgdiobj // handle to GDI-объекта (в данном слу-

чае шрифта)

);

Например, SelectObject(hdc,(HGDIOBJ) newfont).

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

COLORREF SetTextColor(

HDC hdc, // handle контекста устройства COLORREF crColor // цвет символов

);

Например, SetTextColor(hdc, RGB(255, 0,0)).

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

Рисование графических примитивов производится с помощью перьев. В Windows есть три предопределенных пера: черное

(BLACK_PEN), белое (WHITE_PEN) и прозрачное (NULL_PEN).

36

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

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

Линия – LineTo()

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

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

Эллипс – Ellipse() Дуга – Arc()

Сектор – Pie() Например:

BOOL Ellipse(

HDC hdc, // handle контекста устройства

int nLeftRect, // x – координата левого верхнего угла, описанного прямоугольника

int nTopRect, // y – координата левого верхнего угла, описанного прямоугольника

int nRightRect, // x – координата правого нижнего угла, описанного прямоугольника

int nBottomRect // y – координата правого нижнего угла, описанного прямоугольника

);

BOOL Rectangle(

HDC hdc, // handle контекста устройства

int nleftRect, // x – координата левого верхнего угла, прямоугольника

int nTopRect, // y – координата левого верхнего угла, прямоугольника

37

int nRightRect, // x – координата правого нижнего угла, прямоугольника

int nBottomRect // y – координата правого нижнего угла, прямоугольника

);

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

Сплошная кисть создается функцией CreateSolidBrush(). Штриховая кисть создается функцией CreateHatchBrush().

Стили штриховки определяются константами HS_XXXX. После создания кисти необходимо сделать ее текущей в кон-

текстеустройства. Этоделается функцией SelectObject(). Например:

1) создается кисть нужного цвета long color=RGB(125,125,225); HBRUSH hNew;

hNew=CreateSolidBrush(color);

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

SelectObject(hdc,hNew);

2.5. Мастер ClassWizard

Мастер ClassWizard позволяет добавлять в программу новые классы или изменять существующие. Панель ClassWizard Bar выглядит, как показано на рис. 2.1.

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

Можно выбрать класс, затем функцию класса либо имя глобальной функции, щелкните на кнопку «действие по умолчанию» и перейдите в редакторе к тому месту в программе, где находится начало реализации выбранной функции. Вы можете изменить что-то в декларации функции или класса.

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

38

Рис. 2.1

Рис. 2.2

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

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

39

Рис. 2.3

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

Рис. 2.4

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

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

neric Class.

40