Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Компьютерная графика WinAPI шаблон


Здравствуйте!

Как я говорил, изложение теории будет идти нога в ногу с практической реализацией. Поэтому для начала нам нужен шаблон, который позволит нам создавать различные наработки на его основе.

#include <windows.h>

const double PI = 3.141592653;

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

char szClassName[] = "CG Template";

////////////////////////////////////////////////////////////////////////////////////////////////////

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)

{

      HWND hWnd; 

      MSG lpMsg;

      WNDCLASS wc;

     

      // Заполняем структуру класса окна

      wc.style         = CS_HREDRAW | CS_VREDRAW;

      wc.lpfnWndProc   = WndProc;

      wc.cbClsExtra     = 0;

      wc.cbWndExtra    = 0;

      wc.hInstance     = hInstance;

      wc.hIcon          = NULL;

      wc.hCursor       = LoadCursor(NULL, IDC_ARROW);

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

      wc.lpszMenuName  = NULL;

      wc.lpszClassName = szClassName;

 

      // Регистрируем класс окна

      if (!RegisterClass(&wc))

      {

            MessageBox(NULL, "Cannot register class", "Error", MB_OK);

            return 0;

      }

     

      // Создаем основное окно приложения

      hWnd = CreateWindow(

            szClassName,                // Class name                  

            "CG Template",  // Text for window title bar                 

            WS_OVERLAPPEDWINDOW,    // Window style                                            

            50,   50,      // Use default position 

            600,  600,              // Width and height   

            (HWND) NULL,            // Overlapped windows have no parent   

            (HMENU) NULL,           // Use the window class menu             

            (HINSTANCE)hInstance,   // This instance owns this window             

            NULL    );                    // We don't use any data in our WM_CREATE      

     

      if (!hWnd)

      {

            MessageBox(NULL, "Cannot create main window", "Error", MB_OK);

            return 0;

      }

 

      // Показываем наше окно

      ShowWindow(hWnd, nCmdShow);

      UpdateWindow(hWnd);

 

      // Выполняем цикл обработки сообщений до закрытия приложения

      while (GetMessage(&lpMsg, NULL, 0, 0))  {

            TranslateMessage(&lpMsg);

            DispatchMessage(&lpMsg);

      }

 

      return (lpMsg.wParam);

}

 

////////////////////////////////////////////////////////////////////////////////////////////////////

LRESULT CALLBACK WndProc(HWND hWnd, UINT messg, WPARAM wParam, LPARAM lParam)

{

      PAINTSTRUCT ps;

      RECT Rect;

      HDC hdc, hCmpDC;

      HBITMAP hBmp;

 

      switch (messg)

      {

            case WM_PAINT:

                  GetClientRect(hWnd, &Rect);

                  hdc = BeginPaint(hWnd, &ps);

                  // Создание нового контекста для двойной буфферизации

                  hCmpDC = CreateCompatibleDC(hdc);

                  hBmp = CreateCompatibleBitmap(hdc, Rect.right - Rect.left,

                        Rect.bottom - Rect.top);

                  SelectObject(hCmpDC, hBmp);

                  // Закраска фоновым цветом

                  LOGBRUSH br;

                  br.lbstyle="BS_SOLID;"

                  br.lbColor = 0xEECCCC;

                  HBRUSH brush;

                  brush = CreateBrushIndirect(&br);

                  FillRect(hCmpDC, &Rect, brush);

                  DeleteObject(brush);

                  // Вывод на экран

                  SetStretchBltMode(hdc, COLORONCOLOR);

BitBlt(hdc, 0, 0, Rect.right - Rect.left, Rect.bottom - Rect.top,

                        hCmpDC, 0, 0, SRCCOPY);

                  DeleteDC(hCmpDC);

                  DeleteObject(hBmp);

                  hCmpDC = NULL;

                  EndPaint(hWnd, &ps);

                  break;

 

            case WM_DESTROY:

                  PostQuitMessage(0);

                  break;

 

            default:

                  return (DefWindowProc(hWnd, messg, wParam, lParam));

      }

 

      return (0);

}

Вот этот шаблон. Создайте в Visual Studio пустой проект (File → New → Project… → Visual C++ → General → Empty Project), создайте там .cpp файл и вставьте туда код выше. Он должен создать окно и залить клиентскую область синим цветом.

Не хочу вдаваться в устройство WinAPI, но коротко расскажу. Суть в том, что вывод графической информации с использованием WinAPI осуществляется с помощью контекста устройства (тип HDC, Handle of Device Context).

  • получаем контекст вывода нашей формы
  • создаем совместимый контекст на который и будет выводить изображение (используется для двойной буферизации)
  • создаем кисть для закраски фона нужным цветом
  • закрашиваем клиентскую область цветом фона
  • удаляем созданную кисть
  • копируем изображение на реальный контекст вывода ‘цвет в цвет’
  • освобождаем созданные объекты

Прим. Важно не забывать разрушать созданные кисти, карандаши, регионы и прочие графические объекты, т.к. это ведет к сбою работы программы.

Попробуйте запустить этот шаблон.

Не забывайте об обратной связи. Мне будет приятно не только услышать ваше мнение, но и прочитать о темах, которые вы хотите увидеть в настоящей рассылке. Моя электронная почта: cgraphics@mail.ru

Ведущий рассылки, Денис


В избранное