Технология виртуального окна




Приведенная ниже программа демонстрирует описанные выше графические функции. Эта программа использует технологию виртуального окна, которая рас­сматривалась в гл. 8. Она направляет весь вывод в контекст устройства памяти, содержимое которой затем копируется в реальное окно при обработке сообщения WM_PAINT. Этот прием позволяет автоматически обновлять содержимое окна при получении сообщения WM_PAINT.

 

Пример 9-1. Демонстрация основных графических функций:

 

// Демонстрация основных графических функций

#include <Windows.h>

#include <String.h>

#include <Stdio.h>

#include "Graph.h"

 

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

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

char str[255]; // Буфер строки вывода

int X=0, Y=0; // Текущие координаты строки

int maxX, maxY; // Размеры экрана

HDC memdc; // DC виртуального окна

HBITMAP hbit; // Растр - это виртуальное окно

HBRUSH hbrush, hOldbrush; // Дескрипторы кистей

HPEN hOldpen; // Дескриптор прежнего пера

HPEN hRedpen,hGreenpen,hBluepen,hYellowpen; // Перья

 

int WINAPI WinMain (HINSTANCE hThisInst,

HINSTANCE hPrevInst,

LPSTR lpszArgs,

int nWinMode)

{

HWND hwnd;

MSG msg;

WNDCLASS wcl;

HACCEL hAccel;

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

wcl.hInstance=hThisInst; // Дескриптор приложения

wcl.lpszClassName=szWinName; // Имя класса окна

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

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

wcl.hIcon=LoadIcon(NULL,IDI_APPLICATION); // Иконка

wcl.hCursor=LoadCursor(NULL,IDC_ARROW); // Курсор

wcl.lpszMenuName="MYMENU"; // Меню

wcl.cbClsExtra=0; // Без дополнительной

wcl.cbWndExtra=0; // информации

// Определить заполнение окна белым цветом

wcl.hbrBackground=

(HBRUSH)GetStockObject(WHITE_BRUSH);

if(!RegisterClass(&wcl)) // Зарегистр. класс окна

return 0;

// Создать окно

hwnd=CreateWindow(szWinName, // Имя класса

"Работа с графикой в виртуальном окне",

WS_OVERLAPPEDWINDOW,// Стиль окна

CW_USEDEFAULT, // Х-координата

CW_USEDEFAULT, // Y-координата

CW_USEDEFAULT, // Ширина окна

CW_USEDEFAULT, // Высота окна

HWND_DESKTOP, // Нет родит. окна

NULL, // Нет меню

hThisInst, // Дескрип. приложения

NULL); // Без дополит. аргументов

// Загрузить акселераторы

hAccel=LoadAccelerators(hThisInst,"MYMENU");

ShowWindow(hwnd,nWinMode); // Показать окно и

UpdateWindow(hwnd); // перерисовать содержимое

// Запустить цикл обработки сообщений

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

if(!TranslateAccelerator(hwnd,hAccel,&msg))

{

TranslateMessage(&msg); // Использ.Клавиатуры

DispatchMessage (&msg); // Возврат к Windows

}

return msg.wParam;

}

 

// Следующая функция вызывается операционной системой

// Windows и получает в качестве параметров сообщения

// из очереди сообщений данного приложения

 

LRESULT CALLBACK WindowFunc(HWND hwnd,

UINT message,

WPARAM wParam,

LPARAM lParam)

{

HDC hdc;

PAINTSTRUCT paintstruct;

switch(message)

{

case WM_CREATE: // Получаем размеры экрана

maxX=GetSystemMetrics(SM_CXSCREEN);

maxY=GetSystemMetrics(SM_CYSCREEN);

hdc=GetDC(hwnd); // Совмест. с окном растр

memdc=CreateCompatibleDC(hdc);

hbit=CreateCompatibleBitmap(hdc,maxX,maxY);

SelectObject(memdc,hbit);

hbrush=(HBRUSH)GetStockObject(WHITE_BRUSH);

SelectObject(memdc,hbrush);

PatBlt(memdc,0,0,maxX,maxY,PATCOPY);

// Создать новые перья

hRedpen =CreatePen(PS_SOLID,1,RGB(255,0,0));

hGreenpen=CreatePen(PS_SOLID,1,RGB(0,255,0));

hBluepen =CreatePen(PS_SOLID,1,RGB(0,0,255));

hYellowpen=

CreatePen(PS_SOLID,1,RGB(255,255,0));

hOldpen=(HPEN)SelectObject(memdc,hRedpen);

SelectObject(memdc,hOldpen); // Старое перо

ReleaseDC(hwnd,hdc);

break;

case WM_COMMAND:

switch(LOWORD(wParam))

{

case ID_LINES:

// Вывести 2 черных пикселя

SetPixel(memdc,40,14,RGB(0,0,0));

SetPixel(memdc,40,15,RGB(0,0,0));

// Вывести прямую линию

LineTo(memdc,100,50);

MoveToEx(memdc,100,50,NULL);

// Установить зеленое перо

hOldpen=

(HPEN)SelectObject(memdc,hGreenpen);

LineTo(memdc,200,100);

// Установить желтое перо

SelectObject(memdc,hYellowpen);

LineTo(memdc,0,200);

// Установить синее перо

SelectObject(memdc,hBluepen);

LineTo(memdc,200,200);

// Установить красное перо

SelectObject(memdc,hRedpen);

LineTo(memdc,0,0);

// Вернуться к прежнему перу

SelectObject (memdc, hOldpen);

// Провести дугу

Arc(memdc,0,0,300,300,0,50,200,50);

// Показать линии, отрезающие дугу

MoveToEx(memdc,150,150,NULL);

LineTo(memdc,0,50);

MoveToEx(memdc,150,150,NULL);

LineTo(memdc,200,50);

InvalidateRect(hwnd,NULL,1);

break;

case ID_RECTANGLES:

// Прямоугольники не заполняются

hOldbrush=(HBRUSH)SelectObject(memdc,

GetStockObject(HOLLOW_BRUSH));

// Рисуем прямоугольники

Rectangle(memdc,50,50,300,300);

RoundRect(memdc,125,125,220,240,15,13);

// Выбираем красное перо

SelectObject(memdc,hRedpen);

Rectangle(memdc,100,100,200,200);

SelectObject(memdc,hOldpen);

// Вернуться к прежнему перу

// Восстановить прежнюю кисть

SelectObject(memdc,hOldbrush);

InvalidateRect(hwnd,NULL,1);

break;

case ID_ELLIPSES:

// Создаем синюю кисть

hbrush=CreateSolidBrush(RGB(0,0,255));

hOldbrush=

(HBRUSH)SelectObject(memdc,hbrush);

// Рисуем эллипсы с синим заполнением

Ellipse(memdc,50,200,100,280);

Ellipse(memdc,75,25,280,100);

// Рисуем красным пером, зеленой кистью

SelectObject(memdc,hRedpen);

DeleteObject(hbrush); // Удалить кисть

// Создать зеленую кисть

hbrush=CreateSolidBrush(RGB(0,255,0));

SelectObject(memdc,hbrush);

Ellipse(memdc,100,100,200,200);

// Рисуем сектор

Pie(memdc,200,200,340,340,225,200,

200,250);

SelectObject(memdc,hOldpen);

// Вернуться к прежнему перу

SelectObject(memdc,hOldbrush);

// Восстановить прежнюю кисть и удалить

DeleteObject(hbrush); // зеленую кисть

InvalidateRect(hwnd,NULL,1);

break;

case ID_RESET:

// Восстановить текущую позицию в 0,0

MoveToEx(memdc,0,0,NULL);

// Стереть изображение при помощи

// перерисовки фона

PatBlt(memdc,0,0,maxX,maxY,PATCOPY);

InvalidateRect(hwnd,NULL,1);

break;

case ID_HELP:

MessageBox(hwnd,

"F2: линии\n"

"FЗ: прямоугольники\n"

"F4: эллипсы\n"

"F5: сброс",

"Работа с графикой",MB_OK);

break;

}

break;

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

// Получить DC */

hdc=BeginPaint(hwnd,&paintstruct);

// Теперь копируем растр из памяти на экран

BitBlt(hdc,0,0,maxX,maxY,memdc,0,0,SRCCOPY);

// Освободить DC

EndPaint(hwnd,&paintstruct);

break;

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

// Удалить созданные перья

DeleteObject(hRedpen);

DeleteObject(hGreenpen);

DeleteObject(hBluepen);

DeleteObject(hYellowpen);

DeleteDC(memdc); // Удалить виртуальное окно

PostQuitMessage(0);

break;

default:

// Все сообщения, не обрабатываемые в данной

// функции, направляются на обработку по

// умолчанию

return DefWindowProc(hwnd,message,

wParam,lParam);

}

return 0;

}

 

Для этой программы потребуется следующий файл ресурсов:

 

#include <Windows.h>

#include "Graph.h"

MYMENU MENU

{

MENUITEM "&Линии", ID_LINES

MENUITEM "&Прямоугольники",ID_RECTANGLES

MENUITEM "&Эллипсы",ID_ELLIPSES

MENUITEM "&Cбpоc",ID_RESET

MENUITEM "Помощь",ID_HELP

}

MYMENU ACCELERATORS

{

VK_F2, ID_LINES, VIRTKEY

VK_F3, ID_RECTANGLES, VIRTKEY

VK_F4, ID_ELLIPSES, VIRTKEY

VK_F5, ID_RESET, VIRTKEY

VK_F1, ID_HELP, VIRTKEY

}

 

Потребуется также файл определений Graph.h:

 

#define ID_LINES 100

#define ID_RECTANGLES 101

#define ID_ELLIPSES 102

#define ID_RESET 103

#define ID_HELP 104

 

Программа создает меню, позволяющее отображать линии (и вдобавок два пикселя), прямоугольники и эллипсы. Имеется также возможность очистить окно и восстановить текущую позицию. Пример вывода различных типов графики представ­лен на рис. 9.2.

 




Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2017-03-31 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: