- •Интерактивные графические системы
- •Лабораторная работа 1-2.
- •Создание программ построения графиков, используя графические примитивы api Windows. Создание меню, для отображения различных графических объектов
- •Содержание
- •Мировые и экранные координаты.
- •Графические библиотеки.
- •Программирование графики в Windows.
- •Контекст устройства
- •Получить контекст устройства
- •Контекст устройства в Windows программах.
- •Аналогичную схему создания и уничтожения пера можно представить в виде.
- •Графические примитивы api Windows.
- •Шрифты True Type в Windows программах.
- •Обработка сообщений меню Windows программы
- •Задание к выполнению лабораторной работы.
- •Часть 1. Написать Windows программу для своего варианта, которая рисует сразу два графика в одних координатных осях.
Графические библиотеки.
Графические средства в языке C++ и в его предшественнике C полностью отсутствуют. Все возможности для работы с графикой компиляторы C++ представляют в виде дополнительных библиотек графических функций.
Если программа работает под MS‑DOS, то в качестве инструмента для работы с графикой можно использовать графическую библиотеку под MS‑DOS компилятора BC++ 3.1 фирмы Borland.
Если программа работает под Windows, то компилятор использует функции графического интерфейса GDI (Graphic Device Interface – интерфейс графических устройств), которые предоставляет ему система Windows. Исторически сложилось, что существуют графические функции для двух платформ Win16 и Win32.
Для создания программ на платформе Win16 можно использовать компилятор BC++ 3.1, если его настроить соответствующим образом, или использовать компилятора BC++ 5.0.
Для создания программ на платформе Win32 можно использовать компилятор BC++ 5.0, или компиляторы Visual C++ 6.0, Visual C++ 2005.
В программах Win32 можно использовать также графические функции специализированных графических библиотек, таких как OpenGL.
Программирование графики в Windows.
Программирование графики в Windows имеет свои особенности. Во-первых, в составе Windows имеются графические функции, которые любая программа может использовать для создания изображений. Поэтому компиляторы, создающие программы под Windows, обычно не имеют собственных графических библиотек, а используют функции, которые им предоставляет система Windows.
Операционная система Windows имеет набор библиотечных функций для разработки приложений. Эти функции обеспечивают широкую поддержку программирования приложений Windows и в совокупности называются интерфейс API (Application Program Interface –интерфейс прикладного программирования). Графические функции из состава API Windows объединены в отдельную группу – подсистему GDI (Graphic Device Interface – интерфейс графических устройств). В литературе эти функции называют – графические функции API Windows или функции GDI Windows.
Во-вторых, работающая программа взаимодействует с операционной системой Windows с помощью механизма передачи сообщений. Все свои действия программа производит в ответ на последовательность сообщений. Все время пока программа работает, Windows посылает ей сообщения. Сообщение возникает, если что-то происходит в системе, например нажатие клавиши, движение мыши и т.д. Эти сообщения помещаются в очередь. Очередь может хранить несколько сообщений. Программа обращается к очереди и извлекает первое из сообщений. Затем программа или обрабатывает это сообщение или переходит к следующему сообщению. Рассмотрим некоторые из этих сообщений.
Сообщение WM_PAINT отправляется, если существует необходимость нарисовать или перерисовать окно программы.
Сообщение WM_COMMAND отправляется, если пользователь выбирает команду меню.
Сообщение WM_DESTROY отправляется перед тем, как окно уничтожается и программа прекращает работу.
В-третьих, программа работает в оконном режиме. При запуске программы создается окно, в котором выводятся результаты работы программы. Приведем код программы создающей рабочее окно. Пусть код находится в файле OnlyWin.cpp
#include <windows.h>
//прототип функции окна
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//главная функция приложения
int WINAPI WinMain(HINSTANCE hInstance, //идентификатор приложения
HINSTANCE hPrevInstance,
LPSTR lpCmdParam,
int nCmdShow)
{
WCHAR cname[] = L"Class"; // Имя класса окна
WCHAR title[] = L"Hello API Windows"; // Заголовок окна
MSG msg; // структура для работы с сообщениями
//регистрация класса окна приложения
WNDCLASS wc; // структура для регистрации класса окна приложения
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)WndProc; //адрес(имя) функции окна
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance; //идентификатор приложения
wc.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = cname;
if(!RegisterClass(&wc)) //регистрация класса окна приложения
return 0;
//создание окна приложения
HWND hWnd; // идентификатор окна приложения
hWnd = CreateWindow(cname,
title,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL, //идентификатор окна-родителя
NULL, //идентификатор меню дочернего окна
hInstance, //идентификатор приложения
NULL);
if(!hWnd)
return 0;
// Функция ShowWindow рисует окно
// функция UpdateWindows посылает сообщение WM_PAINT
// для обновления окна
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// Запускаем цикл обработки сообщений
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
//функция окна, обрабатывающая сообщения
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch(message)
{
//сообщение при закрытии окна
case WM_DESTROY:
PostQuitMessage(0); //выход из цикла сообщений
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Отметим общие черты любой программы работающей в системе Windows.
Каждая Windows программа, явно (API программирование) или неявно (библиотека классов MFC) содержит две основные функции приложения – главную функцию WinMain и функцию окна WndProc. Если приложение состоит из нескольких окон, то для каждого окна имеется своя функция окна.
Посмотрим, что содержится в главной функции. В работе главной функции WinMain можно выделить три основные этапа.
1) Регистрация класса окна.
2) Создание окна и вывод его на экран.
3) Запуск цикла обработки сообщений.
На первом этапе, регистрация класса окна осуществляется функцией:
ATOM RegisterClass(CONST WNDCLASS *lpWndClass);
Единственным параметром этой функции является указатель на структуру WNDCLASS. Приведем поля этой структуры.
typedef struct _WNDCLASS{
UINT style; //стиль окна
WNDPROC lpfnWndProc; //адрес (имя) оконной функции
int cbClsExtra; //дополнительные данные
int cbWndExtra; //дополнительные данные
HANDLE hInstance; //идентификатор приложения
HICON hIcon; //иконка окна
HCURSOR hCursor; //курсор окна
HBRUSH hbrBackground; //цвет заполнения окна
LPCTSTR lpszMenuName; //имя меню окна
LPCTSTR lpszClassName; //имя класса окна
} WNDCLASS;
На втором этапе работы главной функции, для создания окна вызывается API-функцией CreateWindow(). Эта функция имеет 11 параметров. Приведем значения этих параметров.
HWND CreateWindow(
LPCTSTR lpClassName, //имя класса окна
LPCTSTR lpWindowName, //заголовок окна
DWORD dwStyle, //стиль окна
int x, //координата угла окна
int y, //координата угла окна
int nWidth, //ширина окна
int nHeight, //высота окна
HWND hWndParent, //идентификатор окна-родителя
HMENU hMenu, //идентификатор меню
HANDLE hInstance, //идентификатор приложения
LPVOID lpParam //дополнительная информация
);
Для вывода окна на экран используется следующая функция:
BOOL ShowWindow(HWND hWnd, int nCmdShow);
На третьем этапе главная функция организует цикл обработки сообщений с помощью следующих трех функций.
BOOL GetMessage(LPMSG lpMsg, HWND hWnd, UINT minMsg, UINT maxMsg);
BOOL TranslateMessage(CONST MSG *lpMsg);
BOOL DispatchMessage(CONST MSG *lpMsg);
Во всех трех функциях присутствует указатель на структуру сообщений MSG. Приведем поля этой структуры.
typedef struct tagMSG{
HWND hwnd; //идентификатор окна, которому идет сообщение
UINT message; //код сообщения
WPARAM wParam; //дополнительная информация о сообщении
LPARAM lParam; //дополнительная информация о сообщении
DWORD time; //врем посылки сообщения
POINT pt; //положение курсора мыши
} MSG;
Сообщение, которое содержится в полях структуры MSG, попадает в цикл обработки сообщений, расшифровывается и передается функции окна WndProc, для дальнейшей обработки. Функция WndProc – это особенная функция, она вызывается самой системой, когда окну приходит сообщение. Функция окна WndProc имеет четыре параметра, совпадающие с первыми четырьмя полями структуры MSG. Ниже приводится прототип этой функции.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
Посмотрим, что содержится внутри функции окна. Обязательной частью функции окна является блок обработки сообщений message. Чаще всего этот блок оформляют в виде переключателя switch.
switch(message)
{
//сообщение при закрытии окна
case WM_DESTROY:
PostQuitMessage(0); //выход из цикла сообщений
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
В данной программе этот блок очень простой. По сути дела явно обрабатывается одно сообщение WM_DESTROY.
В функции окна WndProc обязательно по умолчанию должен присутствовать вызов функции DefWindowProc(). Функция DefWindowProc()может обрабатывать любое сообщение, приходящее к окну. Однако сообщение WM_DESTROY требует дополнительных действий от программиста. Когда приходит сообщение WM_DESTROY система закрывает окно. Но при этом программа остается в памяти, если не вызвать функцию PostQuitMessage().
Итак, написан код программы, единственным результатом работы которой является вывод окна приложения на экран монитора. Теперь надо компилировать программу и создать исполняемый файл. Для этой цели воспользуемся компилятором Visual C++ 2005.
Компиляция WIN32 –программ с помощью VISUAL C++ 2008
Проект, в программной среде VISUAL C++ 2008 создается точно также как и в среде VISUAL C++ 2005. Имеются некоторые отличия, но об этом скажем после. Сначала выполняем действия, описанные в пункте «Компиляция WIN32 –программ с помощью VISUAL C++ 2005». Причем в качестве файла, содержащего код программы, можно взять готовый файл, например GraphWin.cpp, или OnlyWin.cpp.
Когда проект приложения будет создан, выполняем компиляцию. Скорее всего, ошибок не будет, зато появится много предупреждений, о ненадежных системных функциях, которые используются в Вашей программе. Речь идет о функциях, связанных с различными кодировками текстовых строк.
Эту проблему можно решить одной установкой в настройке проекта. Идем по пути: Project GraphWin Properties Configuration Properties General. В окне Character Set устанавливаем запись Use Unicode Character Set. Проект готов, можно компилировать.
Компиляция WIN32 –программ с помощью VISUAL C++ 2005
Назовем проект нашего приложения OnlyWin. Файлы проекта будем помещать в папку D:\BC-WORK\OnlyWin. Запустим VISUAL C++ 2005 и в главном меню в пункте File пройдем по цепочке File – New – Project , где выбираем пункт Empty Project. В окошке Name пишем OnlyWin, а в окошке Location соответственно D:\BC-WORK.
Рис.3.
Окно New Projects компилятора Visual C++ 2005.
Нажимаем OK. В результате этих действий создается папка D:\BC-WORK\OnlyWin. В этой папке находятся служебные файлы создаваемого проекта. Среди этих файлов отметим файл OnlyWin.vcproj, который позволяет загрузить проект в интегрированную среду компилятора Visual C++ 2005.
В папку проекта надо также поместить файл OnlyWin.cpp, с кодом нашей программы, и включить его в создаваемый проект. Существует несколько способов включения файлов в проект. Рассмотрим два таких способа.
Первый способ. Предположим, что файл OnlyWin.cpp уже существует. Поместим тогда его в папку D:\BC-WORK\OnlyWin.
Загрузим проект в интегрированную среду компилятора Visual C++. В главном окне компилятора Visual C++ , слева имеется окно Solution Explorer – OnlyWin. Подводим мышку к надписи Source Files и щелкаем правой кнопкой. В появившемся маленьком меню выбираем пункт Add – Existing Item. Находим файл OnlyWin.cpp в папке D:\BC-WORK\OnlyWin. Включаем файл в проект. У пункта Source files появится плюс +.
Щелкаем по плюсу левой кнопкой, а затем двойным щелчком левой кнопкой открываем файл OnlyWin.cpp в главном окне.
Второй способ. Загрузим проект в интегрированную среду компилятора Visual C++. Подводим мышку к надписи Source Files и щелкаем правой кнопкой. В появившемся маленьком меню выбираем пункт Add – New Item.В появившемся окне Add New Item - OnlyWin выбираем пункт C++ File (.cpp). В окошке Name напишем OnlyWin.
Рис.4.
Окно Add New Item компилятора Visual C++ 2005, для добавления новых объектов в проект.
Нажимаем кнопку Add. В результате создается пустой фай OnlyWin.cpp, включенный в проект. В этот файл можно внести код программы двумя способами. Во-первых, можно скопировать готовый код из другого файла. Во-вторых, можно напечатать строчки кода, находясь в редакторе компилятора Visual C++ 2005.
Рис.5.
Главное окно компилятора Visual C++ 2005.
Теперь, чтобы компилировать код, в окошке Build главного меню выбираем пункт Compile. Если компиляция прошла успешно, то в окошке Build выбираем пункт Build OnlyWin и создаем исполняемый файл OnlyWin.exe. Файл OnlyWin.exe располагается в папке D:\BC-WORK\OnlyWin\Debug
Рис.6
Результат работы программы OnlyWin.exe.
Запустить программу можно или из папки D:\BC-WORK\OnlyWin\Debug, или в главном меню в окошке Debug выбрать пункт Start Without Debugging. На Рис.6 приведен результат работы программы.