Функции для вывода графики

Заголовки некоторых функций для вывода графических изображений:

COLORREF SetPixel(HDC, int, int, COLORREF);

COLORREF SetTextColor(HDC, COLORREF);

COLORREF SetBkColor(HDC, COLORREF);

BOOL TextOutA(HDC, int, int, LPCSTR, int);

BOOL MoveToEx(HDC, int, int, LPPOINT);

BOOL LineTo(HDC, int, int);

BOOL Rectangle(HDC, int, int, int, int);

BOOL Ellipse(HDC, int, int, int, int);

BOOL Polygon(HDC, CONST POINT *, int);

Более подробно особенности приложений с графическим интерфейсом пользователя для Windows рассмотрены в [5].

 

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

В разработанном приложении необходимо реализовать некоторые функции простого текстового редактора - рисование графических примитивов в окне с помощью мыши. Дополнительные функции (оцениваются дополнительными баллами): перерисовка, использование полосы прокрутки и др. Особое внимание обратить на структуру графического приложения, состоящего из двух основных функций – функции WinMain и функции обратного вызова (функции окна), а также на то, что основные функции приложения реализуются через механизм обработки сообщений в функции окна.

 

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

Условие задачи:

Разработать приложение для рисования в окне с помощью мыши (функции простого тестового редактора). Рисуются отрезки, начальная точка – точка положения курсора мыши в момент нажатия клавиши, рисование происходит при перемещении мыши с нажатой клавишей, конечная точка- положение курсора в момент отпускания клавиши. Используется правая клавиша мыши. Отрезки рисуются сплошным черным «пером».

Для решения задачи в среде Microsoft Visual Studio 2013 было создано стандартное оконное приложение (проект типа Проект Win32 или Win32 Project в нерусифицированной версии) с установленным свойством «Пустой проект» (Empty project). В проект добавлен файл с расширением .cpp, исходный код которого приведен ниже.

Листинг программы с комментариями:

#include <windows.h>

 

LRESULT CALLBACK WinFun(HWND, UINT, WPARAM, LPARAM);

char WinName[]="Мое окно"; // Имя класса окна

int WINAPI WinMain(HINSTANCE hIns, HINSTANCE hPrevIns, LPSTR arg, int WinMode)

{

HWND hwnd; // Дескриптор окна

MSG msg; // Содержит инф. о сообщении, посылаемом Windows

WNDCLASSEX wcl; // Определяет класс окна

// Определение класса окна

wcl.hInstance=hIns; // Дескриптор данного экземпляра

wcl.lpszClassName=WinName; //Имя класса

wcl.lpfnWndProc=WinFun; //Функция окна

wcl.style=0; //стиль по умолчанию

wcl.cbSize=sizeof(WNDCLASSEX); //Размер структуры

wcl.hIcon=LoadIcon(NULL, IDI_APPLICATION); //Большая пиктограмма

wcl.hIconSm=LoadIcon(NULL, IDI_WINLOGO); //Малая пиктограмма

wcl.hCursor=LoadCursor(NULL, IDC_ARROW); //Форма курсора

wcl.lpszMenuName=NULL; //Меню не используется

wcl.cbClsExtra=0; // Дополнительная информация отсутствует

wcl.cbWndExtra=0;

// Фон окна задается белым

wcl.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);

// Регистрация класса окна

if (!RegisterClassEx(&wcl)) return 0;

// Создание окна

hwnd=CreateWindow(

WinName, // Имя класса окна

"Мое простое окно", // Заголовок

WS_OVERLAPPEDWINDOW, // Стандартное окно

CW_USEDEFAULT, // Координата X- определяется Windows

CW_USEDEFAULT, // Координата Y- определяется Windows

CW_USEDEFAULT, // ширина- определяется Windows

CW_USEDEFAULT, // высота- определяется Windows

HWND_DESKTOP, // Родительского окна нет

NULL, // Меню нет

hIns, // дескриптор данного экземпляра приложения

NULL); // дополнительных аргументов нет

// Отображение окна

ShowWindow(hwnd, WinMode);

UpdateWindow(hwnd);

// Цикл сообщений

while(GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg); // Разрешает использование клавиатуры

DispatchMessage(&msg);

}

return msg.wParam;

}

 

// Эта функция вызывается Windows, которая передает ей сообщение

// из очереди сообщений

struct Line

{

int x1, x2, y1, y2;

};

 

struct LineList // Список линий

{

Line L;

LineList *pNext;

};

 

LineList *pFirst=0, *p;

 

void add(LineList *&pF, LineList *p)

{ // Добавляем элемент в начало списка

p->pNext=pF;

pF=p;

}

 

int x1, x2, y1, y2;

HPEN pB, pW;

 

LRESULT CALLBACK WinFun(HWND hwnd, UINT message,

WPARAM wParam, LPARAM lParam)

{

HDC hdc;

PAINTSTRUCT ps;

 

switch(message)

{

case WM_CREATE:

pB=(HPEN)GetStockObject(BLACK_PEN);

 

pW=(HPEN)GetStockObject(WHITE_PEN);

 

break;

case WM_RBUTTONDOWN:

x2=x1=LOWORD(lParam);

y2=y1=HIWORD(lParam);

break;

case WM_MOUSEMOVE:

if (wParam & MK_RBUTTON) // Определяем нажата ли правая кнопка мыши

{

hdc=GetDC(hwnd);

SelectObject(hdc, pW);

MoveToEx(hdc, x1, y1, (LPPOINT)NULL);

LineTo(hdc, x2, y2);

x2=LOWORD(lParam);

y2=HIWORD(lParam);

SelectObject(hdc, pB);

MoveToEx(hdc, x1, y1, (LPPOINT)NULL);

LineTo(hdc, x2, y2);

ReleaseDC(hwnd, hdc);

}

break;

case WM_RBUTTONUP: // Отпускаем правую кнопку мыши

p=new LineList;

p->L.x1=x1; p->L.x2=x2;

p->L.y1=y1; p->L.y2=y2;

add(pFirst, p);

break;

case WM_PAINT: // Перерисовка

hdc=BeginPaint(hwnd, &ps);

p=pFirst;

while(p)// Прсматриваем спикок и рисуем линии

{

MoveToEx(hdc, p->L.x1, p->L.y1, (LPPOINT)NULL);

LineTo(hdc, p->L.x2, p->L.y2);

p=p->pNext;

}

EndPaint(hwnd, &ps);

break;

 

 

case WM_DESTROY: // Завершение программы

PostQuitMessage(0);

break;

 

 

default:

// Позволяет Windows обрабатывать любые сообщения,

// не указанные в предыдущем случае

return DefWindowProc(hwnd, message, wParam, lParam);

}

return 0;

}

Следует отметить, что для запуска данной программы необходимо в окне свойств проекта отключить использование кодировки Unicode. Т.е. установить опцию «Набор символов» в состояние «Не задано», что показано на рисунке 9.

Рисунок 9 – Отключение набора символов Unicode

Возможные результаты работы программы представлены на рисунке 10.

Рисунок 10 – Пример с результатами работы программы