Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Lec3Pg6
- basewin.h
- #pragma once
- template <class DERIVED_TYPE>
- class BaseWindow
- {
- public:
- static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- DERIVED_TYPE *pThis = NULL;
- if (uMsg == WM_NCCREATE)
- {
- CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam;
- pThis = (DERIVED_TYPE*)pCreate->lpCreateParams;
- SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);
- pThis->m_hwnd = hwnd;
- }
- else
- {
- pThis = (DERIVED_TYPE*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
- }
- if (pThis)
- {
- return pThis->HandleMessage(uMsg, wParam, lParam);
- }
- else
- {
- return DefWindowProc(hwnd, uMsg, wParam, lParam);
- }
- }
- BaseWindow() : m_hwnd(NULL) { }
- BOOL Create(
- PCWSTR lpWindowName,
- DWORD dwStyle,
- DWORD dwExStyle = 0,
- int x = CW_USEDEFAULT,
- int y = CW_USEDEFAULT,
- int nWidth = CW_USEDEFAULT,
- int nHeight = CW_USEDEFAULT,
- HWND hWndParent = 0,
- HMENU hMenu = 0
- )
- {
- WNDCLASS wc = { 0 };
- wc.lpfnWndProc = DERIVED_TYPE::WindowProc;
- wc.hInstance = GetModuleHandle(NULL);
- wc.lpszClassName = ClassName();
- RegisterClass(&wc);
- m_hwnd = CreateWindowEx(
- dwExStyle, ClassName(), lpWindowName, dwStyle, x, y,
- nWidth, nHeight, hWndParent, hMenu, GetModuleHandle(NULL), this
- );
- return (m_hwnd ? TRUE : FALSE);
- }
- HWND Window() const { return m_hwnd; }
- protected:
- virtual PCWSTR ClassName() const = 0;
- HWND m_hwnd;
- };
- Source.cpp
- #include <windows.h>
- #include <d2d1.h>
- #pragma comment(lib, "d2d1")
- #include "basewin.h"
- template <class T> void SafeRelease(T **ppT)
- {
- if (*ppT)
- {
- (*ppT)->Release();
- *ppT = NULL;
- }
- }
- class MainWindow : public BaseWindow<MainWindow>
- {
- ID2D1Factory *pFactory;
- ID2D1HwndRenderTarget *pRenderTarget;
- ID2D1SolidColorBrush *pBrush;
- D2D1_ELLIPSE ellipse;
- void CalculateLayout();
- HRESULT CreateGraphicsResources();
- void DiscardGraphicsResources();
- void OnPaint();
- void Resize();
- public:
- MainWindow() : pFactory(NULL), pRenderTarget(NULL), pBrush(NULL)
- {
- }
- PCWSTR ClassName() const { return L"Circle Window Class"; }
- LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
- };
- // Пересчет изображения при изменении размера окна.
- void MainWindow::CalculateLayout()
- {
- if (pRenderTarget != NULL)
- {
- D2D1_SIZE_F size = pRenderTarget->GetSize();
- const float x = size.width / 2;
- const float y = size.height / 2;
- const float radius = min(x, y);
- ellipse = D2D1::Ellipse(D2D1::Point2F(x, y), radius, radius);
- }
- }
- HRESULT MainWindow::CreateGraphicsResources()
- {
- HRESULT hr = S_OK;
- if (pRenderTarget == NULL)
- {
- RECT rc;
- GetClientRect(m_hwnd, &rc);
- D2D1_SIZE_U size = D2D1::SizeU(rc.right, rc.bottom);
- hr = pFactory->CreateHwndRenderTarget(
- D2D1::RenderTargetProperties(),
- D2D1::HwndRenderTargetProperties(m_hwnd, size),
- &pRenderTarget);
- if (SUCCEEDED(hr))
- {
- const D2D1_COLOR_F color = D2D1::ColorF(1.0f, 1.0f, 0);
- hr = pRenderTarget->CreateSolidColorBrush(color, &pBrush);
- if (SUCCEEDED(hr))
- {
- CalculateLayout();
- }
- }
- }
- return hr;
- }
- void MainWindow::DiscardGraphicsResources()
- {
- SafeRelease(&pRenderTarget);
- SafeRelease(&pBrush);
- }
- void MainWindow::OnPaint()
- {
- HRESULT hr = CreateGraphicsResources();
- if (SUCCEEDED(hr))
- {
- PAINTSTRUCT ps;
- BeginPaint(m_hwnd, &ps);
- pRenderTarget->BeginDraw();
- pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::SkyBlue));
- pRenderTarget->FillEllipse(ellipse, pBrush);
- hr = pRenderTarget->EndDraw();
- if (FAILED(hr) || hr == D2DERR_RECREATE_TARGET)
- {
- DiscardGraphicsResources();
- }
- EndPaint(m_hwnd, &ps);
- }
- }
- void MainWindow::Resize()
- {
- if (pRenderTarget != NULL)
- {
- RECT rc;
- GetClientRect(m_hwnd, &rc);
- D2D1_SIZE_U size = D2D1::SizeU(rc.right, rc.bottom);
- pRenderTarget->Resize(size);
- CalculateLayout();
- InvalidateRect(m_hwnd, NULL, FALSE);
- }
- }
- int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR, int nCmdShow)
- {
- MainWindow win;
- if (!win.Create(L"Circle", WS_OVERLAPPEDWINDOW))
- {
- return 0;
- }
- ShowWindow(win.Window(), nCmdShow);
- // Цикл обработки сообщений.
- MSG msg = {};
- while (GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return 0;
- }
- LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch (uMsg)
- {
- case WM_CREATE:
- if (FAILED(D2D1CreateFactory(
- D2D1_FACTORY_TYPE_SINGLE_THREADED, &pFactory)))
- {
- return -1; // Неудача CreateWindowEx.
- }
- return 0;
- case WM_DESTROY:
- DiscardGraphicsResources();
- SafeRelease(&pFactory);
- PostQuitMessage(0);
- return 0;
- case WM_PAINT:
- OnPaint();
- return 0;
- case WM_SIZE:
- Resize();
- return 0;
- }
- return DefWindowProc(m_hwnd, uMsg, wParam, lParam);
- }
- Lec3Pg25
- basewin.h
- #pragma once
- template <class DERIVED_TYPE>
- class BaseWindow
- {
- public:
- static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- DERIVED_TYPE *pThis = NULL;
- if (uMsg == WM_NCCREATE)
- {
- CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam;
- pThis = (DERIVED_TYPE*)pCreate->lpCreateParams;
- SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);
- pThis->m_hwnd = hwnd;
- }
- else
- {
- pThis = (DERIVED_TYPE*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
- }
- if (pThis)
- {
- return pThis->HandleMessage(uMsg, wParam, lParam);
- }
- else
- {
- return DefWindowProc(hwnd, uMsg, wParam, lParam);
- }
- }
- BaseWindow() : m_hwnd(NULL) { }
- BOOL Create(
- PCWSTR lpWindowName,
- DWORD dwStyle,
- DWORD dwExStyle = 0,
- int x = CW_USEDEFAULT,
- int y = CW_USEDEFAULT,
- int nWidth = CW_USEDEFAULT,
- int nHeight = CW_USEDEFAULT,
- HWND hWndParent = 0,
- HMENU hMenu = 0
- )
- {
- WNDCLASS wc = { 0 };
- wc.lpfnWndProc = DERIVED_TYPE::WindowProc;
- wc.hInstance = GetModuleHandle(NULL);
- wc.lpszClassName = ClassName();
- RegisterClass(&wc);
- m_hwnd = CreateWindowEx(
- dwExStyle, ClassName(), lpWindowName, dwStyle, x, y,
- nWidth, nHeight, hWndParent, hMenu, GetModuleHandle(NULL), this
- );
- return (m_hwnd ? TRUE : FALSE);
- }
- HWND Window() const { return m_hwnd; }
- protected:
- virtual PCWSTR ClassName() const = 0;
- HWND m_hwnd;
- };
- Source.cpp
- #include <windows.h>
- #include <d2d1.h>
- #pragma comment(lib, "d2d1")
- #include "basewin.h"
- template <class T> void SafeRelease(T **ppT)
- {
- if (*ppT)
- {
- (*ppT)->Release();
- *ppT = NULL;
- }
- }
- class MainWindow : public BaseWindow<MainWindow>
- {
- ID2D1Factory *pFactory;
- ID2D1HwndRenderTarget *pRenderTarget;
- ID2D1SolidColorBrush *pBrush;
- D2D1_ELLIPSE ellipse;
- ID2D1SolidColorBrush *pStroke;
- void CalculateLayout();
- HRESULT CreateGraphicsResources();
- void DiscardGraphicsResources();
- void OnPaint();
- void Resize();
- void DrawClockHand(float fHandLength, float fAngle, float fStrokeWidth);
- void RenderScene();
- public:
- MainWindow() : pFactory(NULL), pRenderTarget(NULL), pBrush(NULL)
- {
- }
- PCWSTR ClassName() const { return L"Analog Clock Window Class"; }
- LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
- };
- // Пересчет изображения при изменении размера окна.
- void MainWindow::CalculateLayout()
- {
- if (pRenderTarget != NULL)
- {
- D2D1_SIZE_F size = pRenderTarget->GetSize();
- const float x = size.width / 2;
- const float y = size.height / 2;
- const float radius = min(x, y);
- ellipse = D2D1::Ellipse(D2D1::Point2F(x, y), radius, radius);
- }
- }
- HRESULT MainWindow::CreateGraphicsResources()
- {
- HRESULT hr = S_OK;
- if (pRenderTarget == NULL)
- {
- RECT rc;
- GetClientRect(m_hwnd, &rc);
- D2D1_SIZE_U size = D2D1::SizeU(rc.right, rc.bottom);
- hr = pFactory->CreateHwndRenderTarget(
- D2D1::RenderTargetProperties(),
- D2D1::HwndRenderTargetProperties(m_hwnd, size),
- &pRenderTarget);
- if (SUCCEEDED(hr))
- {
- const D2D1_COLOR_F color = D2D1::ColorF(1.0f, 1.0f, 0);
- hr = pRenderTarget->CreateSolidColorBrush(color, &pBrush);
- if (SUCCEEDED(hr))
- {
- const D2D1_COLOR_F handcolor = D2D1::ColorF(0, 0, 0);
- hr = pRenderTarget->CreateSolidColorBrush(handcolor, &pStroke);
- if (SUCCEEDED(hr))
- {
- CalculateLayout();
- }
- }
- }
- }
- return hr;
- }
- void MainWindow::DiscardGraphicsResources()
- {
- SafeRelease(&pRenderTarget);
- SafeRelease(&pBrush);
- }
- void MainWindow::OnPaint()
- {
- HRESULT hr = CreateGraphicsResources();
- if (SUCCEEDED(hr))
- {
- PAINTSTRUCT ps;
- BeginPaint(m_hwnd, &ps);
- pRenderTarget->BeginDraw();
- RenderScene();
- hr = pRenderTarget->EndDraw();
- if (FAILED(hr) || hr == D2DERR_RECREATE_TARGET)
- {
- DiscardGraphicsResources();
- }
- EndPaint(m_hwnd, &ps);
- }
- }
- void MainWindow::Resize()
- {
- if (pRenderTarget != NULL)
- {
- RECT rc;
- GetClientRect(m_hwnd, &rc);
- D2D1_SIZE_U size = D2D1::SizeU(rc.right, rc.bottom);
- pRenderTarget->Resize(size);
- CalculateLayout();
- InvalidateRect(m_hwnd, NULL, FALSE);
- }
- }
- void MainWindow::DrawClockHand(float fHandLength, float fAngle, float fStrokeWidth)
- {
- pRenderTarget->SetTransform(
- D2D1::Matrix3x2F::Rotation(fAngle, ellipse.point)
- );
- // endPoint определяет один конец стрелки.
- D2D_POINT_2F endPoint = D2D1::Point2F(
- ellipse.point.x,
- ellipse.point.y - (ellipse.radiusY * fHandLength)
- );
- // Нарисовать прямую из центра эллипса к endPoint.
- pRenderTarget->DrawLine(
- ellipse.point, endPoint, pStroke, fStrokeWidth);
- }
- void MainWindow::RenderScene()
- {
- pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::SkyBlue));
- pRenderTarget->FillEllipse(ellipse, pBrush);
- pRenderTarget->DrawEllipse(ellipse, pStroke);
- // Стрелки
- SYSTEMTIME time;
- GetLocalTime(&time);
- // 60 минут = 30 градусов, 1 минута = 0.5 градуса
- const float fHourAngle = (360.0f / 12) * (time.wHour) + (time.wMinute * 0.5f);
- const float fMinuteAngle = (360.0f / 60) * (time.wMinute);
- DrawClockHand(0.6f, fHourAngle, 6);
- DrawClockHand(0.85f, fMinuteAngle, 4);
- // Восстановить идентичность трансформации.
- pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
- }
- int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR, int nCmdShow)
- {
- MainWindow win;
- if (!win.Create(L"Analog Clock", WS_OVERLAPPEDWINDOW))
- {
- return 0;
- }
- ShowWindow(win.Window(), nCmdShow);
- // Цикл обработки сообщений.
- MSG msg = {};
- while (GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return 0;
- }
- LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch (uMsg)
- {
- case WM_CREATE:
- if (FAILED(D2D1CreateFactory(
- D2D1_FACTORY_TYPE_SINGLE_THREADED, &pFactory)))
- {
- return -1; // Неудача CreateWindowEx.
- }
- return 0;
- case WM_DESTROY:
- DiscardGraphicsResources();
- SafeRelease(&pFactory);
- PostQuitMessage(0);
- return 0;
- case WM_PAINT:
- OnPaint();
- return 0;
- case WM_SIZE:
- Resize();
- return 0;
- }
- return DefWindowProc(m_hwnd, uMsg, wParam, lParam);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement