В этом разделе разбирается пример программы в Visual C++, в котором демонстрируются режимы рисования замкнутых фигур. В частности, определяется кисть, загружаемая из битовой матрицы, полученной с помощью файла .bmp. Интерфейс программы основан на иерархическом меню.
Программа выводит многоугольник, координаты вершин которого вводятся с помощью мыши. В данном приложении используется шаблон заполнения областей, созданный пользователем. Он загружается из файла bitmap1.bmp с помощью функции LoadBitmap(). Кисть в этом случае создается с помощью оператора
hbrush = CreatePatternBrush (LoadBitmap(hInst,”MYBP”));
а затем загружается обычным образом, с помощью вызова функции
SelectObject (hdc,hbrush);
Файл bitmap1.bmp обычно имеет размеры 64х64. В нашем же случае он состоит из 8х8 битов. Он создается аналогично иконке:
· на главной панели выбираем опцию Insert->Resourse;
· в открывшемся окне Insert Resourse выбираем опцию bitmap;
· устанавливаем необходимые размеры и рисуем шаблон (в нашем случае 8х8);
· сохраняем его как Script1.rc;
· в результате будет создан файл bitmap1.bmp, который нужно включить в файл ресурсов polygon.rc, добавив строку
MYBP BITMAP BITMAP1.BMP
Создадим папку с именем polygon. Эта папка в дальнейшем будет включать файлы:
· polygon.rc -файл ресурсов, состоящий из меню, иконки icon1.ico и файла bitmap1.bmp;
· polygon.cpp -текст программы;
· icon1.ico -двоичный файл, одержащий изображение иконки;
· bitmap1.bmp -двоичный файл, содержащий шаблон заполнения областей.
Приведем файл ресурсов и текст программы.
// файл polygon.rc
MYMENU MENU
{
POPUP "&Attribute"
{
POPUP "&Phone"
{
MENUITEM "Red",301
MENUITEM "Green",302
MENUITEM "White",303
MENUITEM "Black",304
}
POPUP "&MixedMode"
{
MENUITEM "&CopyPen",311
MENUITEM "&DisplayInverse",312
MENUITEM "&PenInverse",313
MENUITEM "White",314
MENUITEM "&Black",315
MENUITEM "XorPen",316
}
POPUP "&BackMode"
{
MENUITEM "&Transparent",321
MENUITEM "&Opaque",322
}
}
POPUP "&Pen"
{
POPUP "&Thickness"
{
MENUITEM "&Thin", 101
MENUITEM "&Regular", 102
MENUITEM "T&hick", 103
}
POPUP "&Color"
{
MENUITEM "&Red", 111
MENUITEM "&Green", 112
MENUITEM "&Black", 113
}
}
POPUP "&Brush"
{
POPUP "St&yle"
{
MENUITEM "&Solid", 201
MENUITEM "&Hatched", 202
MENUITEM "&Pattern", 203
}
POPUP "C&olor"
{
MENUITEM "&Red", 211
MENUITEM "&Green", 212
MENUITEM "&Blue", 213
}
}
}
IDI_ICON1 ICON ICON1.ICO
MYBP BITMAP BITMAP1.BMP
// файл Polygon.cpp
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <math.h>
LRESULT CALLBACK WindowFunc(HWND,UINT,WPARAM,LPARAM);
//BOOL CALLBACK DialogFunc (HWND,UINT,WPARAM,LPARAM);
char szwinname[] = "MyWindow";
int maxX,maxY;
POINT pnts[100];
HINSTANCE hInst;
int PenWidth =3;
COLORREF PenColor=RGB(255,0,255);
COLORREF BrushColor=RGB(0,192,255);
LOGBRUSH lb= {BS_SOLID,BrushColor,HS_DIAGCROSS};
/*HPEN holdpen;
HPEN hRedpen, hGreenpen, hBluepen,hYellowpen;*/
HBRUSH hbrush;
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 = CS_DBLCLKS;
wcl.hIcon = LoadIcon (hthisinst, "IDI_ICON1");
wcl.hCursor = LoadCursor(NULL,IDC_ARROW);
wcl.lpszMenuName = "MYMENU";
wcl.cbClsExtra = 0;
wcl.cbWndExtra = 0;
wcl.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
hInst = hthisinst;
if(!RegisterClass(&wcl))
return 0;
hwnd = CreateWindow(szwinname,
"Function",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
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);
}
}
return msg.wParam;
}
LRESULT CALLBACK WindowFunc(HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
HDC hdc;
static int count;
int i;
PAINTSTRUCT paintstruct;
HANDLE saveObject, saveObject2;
static COLORREF Phone;
static int MMode=R2_COPYPEN;
static int BMode, saveBM, saveROP,saveBC;
switch(message)
{
case WM_CREATE:
maxX= GetSystemMetrics(SM_CXSCREEN);
maxY= GetSystemMetrics(SM_CYSCREEN);
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case 101: // Pen
PenWidth = 1;
break;
case 102: // Pen
PenWidth = 3;
break;
case 103: // Pen
PenWidth = 5;
break;
case 111:
PenColor = RGB(255,0,0);
break;
case 112:
PenColor = RGB(0,255,0);
break;
case 113:
PenColor = RGB(0,0,0);
break;
case 201: // Brush
lb.lbStyle=BS_SOLID;
break;
case 202: // Brush
lb.lbStyle=BS_HATCHED;
break;
case 203: // Brush
lb.lbStyle=BS_PATTERN;
// lb.lbHatch=(HBITMAP)LoadBitmap(hInst,"MYBP");
break;
case 211:
lb.lbColor=RGB(255,0,0);
break;
case 212:
lb.lbColor=RGB(0,255,0);
break;
case 213: // Brush
lb.lbColor=RGB(0,0,255);
break;
case 301:
Phone=RGB(255,0,0);
break;
case 302:
Phone=RGB(0,255,0);
break;
case 303:
Phone=RGB(255,255,255);
break;
case 304:
Phone=RGB(0,0,0);
break;
case 311:
MMode=R2_COPYPEN;
break;
case 312:
MMode=R2_NOT;
break;
case 313:
MMode=R2_NOTCOPYPEN;
break;
case 314:
MMode=R2_WHITE;
break;
case 315:
MMode=R2_BLACK;
break;
case 316:
MMode=R2_XORPEN;
break;
case 321:
BMode=TRANSPARENT;
break;
case 322:
BMode=OPAQUE;
break;
}
break;
case WM_LBUTTONDOWN:
pnts[count].x = LOWORD(lParam);
pnts[count].y = HIWORD(lParam);
hdc=GetDC(hwnd);
Ellipse(hdc,pnts[count].x-2,pnts[count].y-2,
pnts[count].x+2,pnts[count].y+2);
count++;
if (count>=100) count=99;
ReleaseDC(hwnd,hdc);
break;
case WM_LBUTTONDBLCLK:
case WM_CHAR:
InvalidateRect(hwnd,NULL,1);
break;
// COLORREF Phone;
// int MMode, BMode, saveBM, saveROP,saveBC;
case WM_PAINT:
hdc = BeginPaint(hwnd,&paintstruct);
RoundRect(hdc,maxX/4, maxY/4,3*maxX/4,3*maxY/4,20,20);
saveBC=SetBkColor(hdc, Phone);
saveBM = SetBkMode(hdc,BMode);
saveROP = SetROP2(hdc, MMode);
saveObject = SelectObject(hdc,
CreatePen(PS_SOLID,PenWidth,PenColor));
if (lb.lbStyle!=BS_PATTERN)
hbrush = CreateBrushIndirect(&lb);
else hbrush = CreatePatternBrush(LoadBitmap(hInst,"MYBP"));
saveObject2 = SelectObject(hdc,hbrush);
Polygon(hdc,pnts,count);
count=0;
DeleteObject(SelectObject(hdc,saveObject));
DeleteObject(SelectObject(hdc,saveObject2));
SetROP2(hdc,saveROP);
SetBkMode(hdc,saveBM);
SetBkColor(hdc, saveBC);
EndPaint(hwnd,&paintstruct);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,message,wParam,lParam);
}
return 0;
}
Результаты работы программы приведены на рис. 2.19.
Рис. 2.19. Заполнение областей
При работе с программой в меню выбирается режим смешения и вывода фона, пера и кисти. Рисунок выводится с помощью мыши. Левой кнопкой мыши указываются вершины многоугольника. Последняя вершина определяется двойным щелчком.