4.2.2 ВОЗМОЖНОСТИ ГРАФИЧЕСКОЙ БИБЛИОТЕКИ API

В этом разделе разбирается  пример программы в 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. Заполнение областей

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