Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Lec5Pg7
- 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 <Dwrite.h>
- #pragma comment(lib, "DWrite")
- #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;
- void CalculateLayout() {}
- HRESULT CreateGraphicsResources();
- void DiscardGraphicsResources();
- void OnPaint();
- void Resize();
- HRESULT DrawHelloWorld(
- ID2D1HwndRenderTarget* pIRenderTarget
- );
- public:
- MainWindow() : pFactory(NULL), pRenderTarget(NULL)
- {
- }
- PCWSTR ClassName() const { return L"Hello Window Class"; }
- LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
- };
- 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);
- }
- return hr;
- }
- void MainWindow::DiscardGraphicsResources()
- {
- SafeRelease(&pRenderTarget);
- }
- void MainWindow::OnPaint()
- {
- HRESULT hr = CreateGraphicsResources();
- if (SUCCEEDED(hr))
- {
- PAINTSTRUCT ps;
- BeginPaint(m_hwnd, &ps);
- pRenderTarget->BeginDraw();
- pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::SkyBlue));
- hr = DrawHelloWorld(pRenderTarget);
- 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);
- }
- }
- HRESULT MainWindow::DrawHelloWorld(
- ID2D1HwndRenderTarget* pIRenderTarget
- )
- {
- HRESULT hr = S_OK;
- ID2D1SolidColorBrush* pIRedBrush = NULL;
- IDWriteTextFormat* pITextFormat = NULL;
- IDWriteFactory* pIDWriteFactory = NULL;
- if (SUCCEEDED(hr))
- {
- hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
- __uuidof(IDWriteFactory),
- reinterpret_cast<IUnknown**>(&pIDWriteFactory));
- }
- if (SUCCEEDED(hr))
- {
- hr = pIDWriteFactory->CreateTextFormat(
- L"Arial",
- NULL,
- DWRITE_FONT_WEIGHT_NORMAL,
- DWRITE_FONT_STYLE_NORMAL,
- DWRITE_FONT_STRETCH_NORMAL,
- 24.0f * 96.0f / 72.0f,
- L"en-US",
- &pITextFormat
- );
- }
- if (SUCCEEDED(hr))
- {
- hr = pIRenderTarget->CreateSolidColorBrush(
- D2D1::ColorF(D2D1::ColorF::Red),
- &pIRedBrush
- );
- }
- D2D1_RECT_F layoutRect = D2D1::RectF(0.f, 0.f, 250.f, 100.f);
- // Вывести текст в начало координат.
- if (SUCCEEDED(hr))
- {
- pIRenderTarget->DrawText(
- L"Hello World",
- wcslen(L"Hello World"),
- pITextFormat,
- layoutRect,
- pIRedBrush
- );
- }
- // Clean up.
- SafeRelease(&pIRedBrush);
- SafeRelease(&pITextFormat);
- SafeRelease(&pIDWriteFactory);
- return hr;
- }
- int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR, int nCmdShow)
- {
- MainWindow win;
- if (!win.Create(L"Hello", 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);
- }
- Lec5Pg10
- Source.cpp
- #include <dwrite.h>
- #include <string.h>
- #include <stdio.h>
- #include <new>
- // SafeRelease inline function.
- template <class T> inline void SafeRelease(T **ppT)
- {
- if (*ppT)
- {
- (*ppT)->Release();
- *ppT = NULL;
- }
- }
- void wmain()
- {
- IDWriteFactory* pDWriteFactory = NULL;
- HRESULT hr = DWriteCreateFactory(
- DWRITE_FACTORY_TYPE_SHARED,
- __uuidof(IDWriteFactory),
- reinterpret_cast<IUnknown**>(&pDWriteFactory)
- );
- IDWriteFontCollection* pFontCollection = NULL;
- // Get the system font collection.
- if (SUCCEEDED(hr))
- {
- hr = pDWriteFactory->GetSystemFontCollection(&pFontCollection);
- }
- UINT32 familyCount = 0;
- wchar_t localeName[LOCALE_NAME_MAX_LENGTH];
- // Get the default locale for this user.
- int defaultLocaleSuccess = GetUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH);
- wprintf(L"ln=%s\n", localeName);
- // Get the number of font families in the collection.
- if (SUCCEEDED(hr))
- {
- familyCount = pFontCollection->GetFontFamilyCount();
- }
- for (UINT32 i = 0; i < familyCount; ++i)
- {
- IDWriteFontFamily* pFontFamily = NULL;
- // Get the font family.
- if (SUCCEEDED(hr))
- {
- hr = pFontCollection->GetFontFamily(i, &pFontFamily);
- }
- IDWriteLocalizedStrings* pFamilyNames = NULL;
- // Get a list of localized strings for the family name.
- if (SUCCEEDED(hr))
- {
- hr = pFontFamily->GetFamilyNames(&pFamilyNames);
- }
- UINT32 index = 0;
- BOOL exists = false;
- if (SUCCEEDED(hr))
- {
- // If the default locale is returned, find that locale name, otherwise use "en-us".
- if (defaultLocaleSuccess)
- {
- hr = pFamilyNames->FindLocaleName(localeName, &index, &exists);
- }
- if (SUCCEEDED(hr) && !exists) // if the above find did not find a match, retry with US English
- {
- hr = pFamilyNames->FindLocaleName(L"en-us", &index, &exists);
- }
- }
- // If the specified locale doesn't exist, select the first on the list.
- if (!exists)
- index = 0;
- UINT32 length = 0;
- // Get the string length.
- if (SUCCEEDED(hr))
- {
- hr = pFamilyNames->GetStringLength(index, &length);
- }
- // Allocate a string big enough to hold the name.
- wchar_t* name = new (std::nothrow) wchar_t[length + 1];
- if (name == NULL)
- {
- hr = E_OUTOFMEMORY;
- }
- // Get the family name.
- if (SUCCEEDED(hr))
- {
- hr = pFamilyNames->GetString(index, name, length + 1);
- }
- if (SUCCEEDED(hr))
- {
- // Print out the family name.
- wprintf(L"%s\n", name);
- }
- SafeRelease(&pFontFamily);
- SafeRelease(&pFamilyNames);
- delete[] name;
- }
- SafeRelease(&pFontCollection);
- SafeRelease(&pDWriteFactory);
- char c;
- scanf_s("%c", &c, 1);
- }
- Lec5Pg14
- 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();
- //wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- 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;
- };
- Direct2D.cpp
- #include "Direct2D.h"
- #pragma comment(lib, "d2d1")
- #pragma comment(lib, "DWrite")
- float DPIScale::scaleX = 1.0f;
- float DPIScale::scaleY = 1.0f;
- Direct2D::Direct2D() : pFactory(NULL), pRenderTarget(NULL), pBlackBrush_(NULL)
- {
- wszText_ = L"Hello World using DirectWrite!";
- cTextLength_ = (UINT32)wcslen(wszText_);
- }
- Direct2D::~Direct2D()
- {
- }
- bool Direct2D::CreateDeviceIndependentResources()
- {
- HRESULT hr = D2D1CreateFactory(
- D2D1_FACTORY_TYPE_SINGLE_THREADED,
- &pFactory);
- if (SUCCEEDED(hr))
- {
- DPIScale::Initialize(pFactory);
- hr = DWriteCreateFactory(
- DWRITE_FACTORY_TYPE_SHARED,
- __uuidof(IDWriteFactory),
- reinterpret_cast<IUnknown**>(&pDWriteFactory_)
- );
- }
- if (SUCCEEDED(hr))
- {
- hr = pDWriteFactory_->CreateTextFormat(
- L"Gabriola", // Font family name.
- NULL, // Font collection (NULL sets it to use the system font collection).
- DWRITE_FONT_WEIGHT_REGULAR,
- DWRITE_FONT_STYLE_NORMAL,
- DWRITE_FONT_STRETCH_NORMAL,
- 72.0f,
- L"en-us",
- &pTextFormat_
- );
- }
- if (SUCCEEDED(hr))
- {
- hr = pTextFormat_->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);
- }
- if (SUCCEEDED(hr))
- {
- hr = pTextFormat_->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);
- }
- return SUCCEEDED(hr);
- }
- HRESULT Direct2D::CreateGraphicsResources(HWND m_hwnd)
- {
- 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(D2D1::ColorF::Black);
- hr = pRenderTarget->CreateSolidColorBrush(color, &pBlackBrush_);
- if (SUCCEEDED(hr))
- {
- CalculateLayout();
- }
- }
- }
- return hr;
- }
- void Direct2D::DiscardGraphicsResources()
- {
- SafeRelease(&pRenderTarget);
- SafeRelease(&pBlackBrush_);
- }
- // Пересчет изображения при изменении размера окна.
- void Direct2D::CalculateLayout()
- {
- }
- void Direct2D::OnPaintScene(HWND m_hwnd)
- {
- HRESULT hr = CreateGraphicsResources(m_hwnd);
- if (SUCCEEDED(hr))
- {
- RECT rc;
- GetClientRect(m_hwnd, &rc);
- const float dipX = DPIScale::PixelsToDipsX(rc.right);
- const float dipY = DPIScale::PixelsToDipsY(rc.bottom);
- D2D1_RECT_F layoutRect = D2D1::RectF(0.0f, 0.0f, dipX, dipY);
- pRenderTarget->BeginDraw();
- pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
- pRenderTarget->DrawText(
- wszText_, // The string to render.
- cTextLength_, // The string's length.
- pTextFormat_, // The text format.
- layoutRect, // The region of the window where the text will be rendered.
- pBlackBrush_ // The brush used to draw the text.
- );
- hr = pRenderTarget->EndDraw();
- if (FAILED(hr) || hr == D2DERR_RECREATE_TARGET)
- {
- DiscardGraphicsResources();
- }
- }
- }
- Direct2D.h
- #pragma once
- #include <d2d1.h>
- #include <dwrite.h>
- class DPIScale
- {
- static float scaleX;
- static float scaleY;
- public:
- static void Initialize(ID2D1Factory *pFactory)
- {
- FLOAT dpiX, dpiY;
- pFactory->GetDesktopDpi(&dpiX, &dpiY);
- scaleX = dpiX / 96.0f;
- scaleY = dpiY / 96.0f;
- }
- template <typename T>
- static float PixelsToDipsX(T x)
- {
- return static_cast<float>(x) / scaleX;
- }
- template <typename T>
- static float PixelsToDipsY(T y)
- {
- return static_cast<float>(y) / scaleY;
- }
- template <typename T>
- static D2D1_POINT_2F PixelsToDips(T x, T y)
- {
- return D2D1::Point2F(static_cast<float>(x) / scaleX, static_cast<float>(y) / scaleY);
- }
- };
- template <class T> void SafeRelease(T **ppT)
- {
- if (*ppT)
- {
- (*ppT)->Release();
- *ppT = NULL;
- }
- }
- class Direct2D
- {
- ID2D1Factory * pFactory;
- public:
- ID2D1SolidColorBrush *pBlackBrush_;
- ID2D1HwndRenderTarget * pRenderTarget;
- IDWriteFactory* pDWriteFactory_;
- IDWriteTextFormat* pTextFormat_;
- const wchar_t* wszText_;
- UINT32 cTextLength_;
- Direct2D();
- ~Direct2D();
- bool CreateDeviceIndependentResources();
- HRESULT CreateGraphicsResources(HWND m_hwnd);
- void DiscardGraphicsResources();
- void ReleaseFactory()
- {
- SafeRelease(&pFactory);
- SafeRelease(&pDWriteFactory_);
- }
- void CalculateLayout();
- void OnPaintScene(HWND m_hwnd);
- };
- MainWindow.cpp
- #include <Windows.h>
- #include "MainWindow.h"
- void MainWindow::OnPaint()
- {
- PAINTSTRUCT ps;
- BeginPaint(m_hwnd, &ps);
- d2d.OnPaintScene(m_hwnd);
- EndPaint(m_hwnd, &ps);
- }
- void MainWindow::Resize()
- {
- if (d2d.pRenderTarget != NULL)
- {
- RECT rc;
- GetClientRect(m_hwnd, &rc);
- D2D1_SIZE_U size = D2D1::SizeU(rc.right, rc.bottom);
- d2d.pRenderTarget->Resize(size);
- d2d.CalculateLayout();
- InvalidateRect(m_hwnd, NULL, FALSE);
- }
- }
- LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch (uMsg)
- {
- case WM_CREATE:
- if (!d2d.CreateDeviceIndependentResources())
- {
- return -1; // Неудача CreateWindowEx.
- }
- return 0;
- case WM_DESTROY:
- d2d.DiscardGraphicsResources();
- d2d.ReleaseFactory();
- PostQuitMessage(0);
- return 0;
- case WM_PAINT:
- OnPaint();
- return 0;
- case WM_SIZE:
- Resize();
- return 0;
- }
- return DefWindowProc(m_hwnd, uMsg, wParam, lParam);
- }
- MainWindow.h
- #pragma once
- #include "basewin.h"
- #include "Direct2D.h"
- class MainWindow : public BaseWindow<MainWindow> {
- Direct2D d2d;
- public:
- void OnPaint();
- void Resize();
- PCWSTR ClassName() const { return L"SimpleText Window Class"; }
- LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
- };
- Source.cpp
- #include <windows.h>
- #include "MainWindow.h"
- int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
- {
- MainWindow win;
- if (!win.Create(L"Простой текст", WS_OVERLAPPEDWINDOW))
- {
- return 0;
- }
- ShowWindow(win.Window(), nCmdShow);
- // Run the message loop.
- MSG msg = {};
- while (GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return 0;
- }
- Lec5Pg19
- 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();
- //wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- 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;
- };
- Direct2D.cpp
- #include "Direct2D.h"
- #pragma comment(lib, "d2d1")
- #pragma comment(lib, "DWrite")
- float DPIScale::scaleX = 1.0f;
- float DPIScale::scaleY = 1.0f;
- Direct2D::Direct2D() : pFactory(NULL), pRenderTarget(NULL), pBlackBrush_(NULL), pTextLayout_(NULL)
- {
- wszText_ = L"Hello World using DirectWrite!";
- cTextLength_ = (UINT32)wcslen(wszText_);
- }
- Direct2D::~Direct2D()
- {
- }
- bool Direct2D::CreateDeviceIndependentResources(HWND m_hwnd)
- {
- HRESULT hr = D2D1CreateFactory(
- D2D1_FACTORY_TYPE_SINGLE_THREADED,
- &pFactory);
- if (SUCCEEDED(hr))
- {
- DPIScale::Initialize(pFactory);
- hr = DWriteCreateFactory(
- DWRITE_FACTORY_TYPE_SHARED,
- __uuidof(IDWriteFactory),
- reinterpret_cast<IUnknown**>(&pDWriteFactory_)
- );
- }
- if (SUCCEEDED(hr))
- {
- hr = pDWriteFactory_->CreateTextFormat(
- L"Gabriola", // Font family name.
- NULL, // Font collection (NULL sets it to use the system font collection).
- DWRITE_FONT_WEIGHT_REGULAR,
- DWRITE_FONT_STYLE_NORMAL,
- DWRITE_FONT_STRETCH_NORMAL,
- 72.0f,
- L"en-us",
- &pTextFormat_
- );
- }
- if (SUCCEEDED(hr))
- {
- hr = pTextFormat_->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);
- }
- if (SUCCEEDED(hr))
- {
- hr = pTextFormat_->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);
- }
- if (SUCCEEDED(hr))
- {
- // Create a text layout using the text format.
- RECT rc;
- GetClientRect(m_hwnd, &rc);
- float width = DPIScale::PixelsToDipsX(rc.right);
- float height = DPIScale::PixelsToDipsY(rc.bottom);
- HRESULT hr = pDWriteFactory_->CreateTextLayout(
- wszText_, // The string to be laid out and formatted.
- cTextLength_, // The length of the string.
- pTextFormat_, // The text format to apply to the string (contains font information, etc).
- width, // The width of the layout box.
- height, // The height of the layout box.
- &pTextLayout_ // The IDWriteTextLayout interface pointer.
- );
- }
- if (SUCCEEDED(hr))
- {
- DWRITE_TEXT_RANGE textRange = { 19, // Start index where "DirectWrite" appears.
- 6 }; // Length of the substring "Direct" in "DirectWrite".
- hr = pTextLayout_->SetFontSize(100.0f, textRange);
- }
- // Format the word "DWrite" to be underlined.
- if (SUCCEEDED(hr))
- {
- DWRITE_TEXT_RANGE textRange = { 19, // Start index where "DirectWrite" appears.
- 11 }; // Length of the substring "DirectWrite".
- hr = pTextLayout_->SetUnderline(TRUE, textRange);
- }
- if (SUCCEEDED(hr))
- {
- // Format the word "DWrite" to be bold.
- DWRITE_TEXT_RANGE textRange = { 19,
- 11 };
- hr = pTextLayout_->SetFontWeight(DWRITE_FONT_WEIGHT_BOLD, textRange);
- }
- // Create a typography interface object.
- if (SUCCEEDED(hr))
- {
- hr = pDWriteFactory_->CreateTypography(&pTypography);
- }
- // Set the stylistic set.
- DWRITE_FONT_FEATURE fontFeature = { DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_7,
- 1 };
- if (SUCCEEDED(hr))
- {
- hr = pTypography->AddFontFeature(fontFeature);
- }
- if (SUCCEEDED(hr))
- {
- // Set the typography for the entire string.
- DWRITE_TEXT_RANGE textRange = { 0,
- cTextLength_ };
- hr = pTextLayout_->SetTypography(pTypography, textRange);
- }
- return SUCCEEDED(hr);
- }
- HRESULT Direct2D::CreateGraphicsResources(HWND m_hwnd)
- {
- 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(D2D1::ColorF::Black);
- hr = pRenderTarget->CreateSolidColorBrush(color, &pBlackBrush_);
- if (SUCCEEDED(hr))
- {
- CalculateLayout(m_hwnd);
- }
- }
- }
- return hr;
- }
- void Direct2D::DiscardGraphicsResources()
- {
- SafeRelease(&pRenderTarget);
- SafeRelease(&pBlackBrush_);
- }
- // Пересчет изображения при изменении размера окна.
- void Direct2D::CalculateLayout(HWND m_hwnd)
- {
- RECT rc;
- GetClientRect(m_hwnd, &rc);
- if (pTextLayout_)
- {
- const float dipX = DPIScale::PixelsToDipsX(rc.right);
- const float dipY = DPIScale::PixelsToDipsY(rc.bottom);
- pTextLayout_->SetMaxWidth(dipX);
- pTextLayout_->SetMaxHeight(dipY);
- }
- }
- void Direct2D::OnPaintScene(HWND m_hwnd)
- {
- HRESULT hr = CreateGraphicsResources(m_hwnd);
- if (SUCCEEDED(hr))
- {
- D2D1_POINT_2F origin = D2D1::Point2F(0.0f, 0.0f);
- pRenderTarget->BeginDraw();
- pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
- pRenderTarget->DrawTextLayout(
- origin,
- pTextLayout_,
- pBlackBrush_
- );
- hr = pRenderTarget->EndDraw();
- if (FAILED(hr) || hr == D2DERR_RECREATE_TARGET)
- {
- DiscardGraphicsResources();
- }
- }
- }
- Direct2D.h
- #pragma once
- #include <d2d1.h>
- #include <dwrite.h>
- class DPIScale
- {
- static float scaleX;
- static float scaleY;
- public:
- static void Initialize(ID2D1Factory *pFactory)
- {
- FLOAT dpiX, dpiY;
- pFactory->GetDesktopDpi(&dpiX, &dpiY);
- scaleX = dpiX / 96.0f;
- scaleY = dpiY / 96.0f;
- }
- template <typename T>
- static float PixelsToDipsX(T x)
- {
- return static_cast<float>(x) / scaleX;
- }
- template <typename T>
- static float PixelsToDipsY(T y)
- {
- return static_cast<float>(y) / scaleY;
- }
- template <typename T>
- static D2D1_POINT_2F PixelsToDips(T x, T y)
- {
- return D2D1::Point2F(static_cast<float>(x) / scaleX, static_cast<float>(y) / scaleY);
- }
- };
- template <class T> void SafeRelease(T **ppT)
- {
- if (*ppT)
- {
- (*ppT)->Release();
- *ppT = NULL;
- }
- }
- class Direct2D
- {
- ID2D1Factory * pFactory;
- public:
- ID2D1SolidColorBrush *pBlackBrush_;
- ID2D1HwndRenderTarget * pRenderTarget;
- IDWriteFactory* pDWriteFactory_;
- IDWriteTextFormat* pTextFormat_;
- IDWriteTextLayout* pTextLayout_;
- IDWriteTypography* pTypography = NULL;
- const wchar_t* wszText_;
- UINT32 cTextLength_;
- Direct2D();
- ~Direct2D();
- bool CreateDeviceIndependentResources(HWND m_hwnd);
- HRESULT CreateGraphicsResources(HWND m_hwnd);
- void DiscardGraphicsResources();
- void ReleaseFactory()
- {
- SafeRelease(&pFactory);
- SafeRelease(&pDWriteFactory_);
- }
- void CalculateLayout(HWND m_hwnd);
- void OnPaintScene(HWND m_hwnd);
- };
- MainWindow.cpp
- #include <Windows.h>
- #include "MainWindow.h"
- void MainWindow::OnPaint()
- {
- PAINTSTRUCT ps;
- BeginPaint(m_hwnd, &ps);
- d2d.OnPaintScene(m_hwnd);
- EndPaint(m_hwnd, &ps);
- }
- void MainWindow::Resize()
- {
- if (d2d.pRenderTarget != NULL)
- {
- RECT rc;
- GetClientRect(m_hwnd, &rc);
- D2D1_SIZE_U size = D2D1::SizeU(rc.right, rc.bottom);
- d2d.pRenderTarget->Resize(size);
- d2d.CalculateLayout(m_hwnd);
- InvalidateRect(m_hwnd, NULL, FALSE);
- }
- }
- LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch (uMsg)
- {
- case WM_CREATE:
- if (!d2d.CreateDeviceIndependentResources(m_hwnd))
- {
- return -1; // Неудача CreateWindowEx.
- }
- return 0;
- case WM_DESTROY:
- d2d.DiscardGraphicsResources();
- d2d.ReleaseFactory();
- PostQuitMessage(0);
- return 0;
- case WM_PAINT:
- OnPaint();
- return 0;
- case WM_SIZE:
- Resize();
- return 0;
- }
- return DefWindowProc(m_hwnd, uMsg, wParam, lParam);
- }
- MainWindow.h
- #pragma once
- #include "basewin.h"
- #include "Direct2D.h"
- class MainWindow : public BaseWindow<MainWindow> {
- Direct2D d2d;
- public:
- void OnPaint();
- void Resize();
- PCWSTR ClassName() const { return L"MultiformattedText Window Class"; }
- LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
- };
- Source.cpp
- #include <windows.h>
- #include "MainWindow.h"
- int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
- {
- MainWindow win;
- if (!win.Create(L"Многоформатный текст", WS_OVERLAPPEDWINDOW))
- {
- return 0;
- }
- ShowWindow(win.Window(), nCmdShow);
- // Run the message loop.
- MSG msg = {};
- while (GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment