Direct2Dスケルトンコード

公開:2009-11-07 21:12
更新:2020-02-15 04:36
カテゴリ:

Direct2DのスケルトンコードをSimpleDirect2DApplicationサンプルのコードをベースに作成してみた。
殆どパクリだけど、COMスマートポインタを使っているのが違うところ。例外処理はいれていない。
・ヘッダ(Direct2DBurn.h)


#pragma once
#include "resource.h"
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
//
#pragma once
// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER              // Allow use of features specific to Windows 7 or later.
#define WINVER 0x0700       // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef _WIN32_WINNT        // Allow use of features specific to Windows 7 or later.
#define _WIN32_WINNT 0x0700 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN     // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
// C RunTime Header Files
/******************************************************************
*                                                                 *
*  Macros                                                         *
*                                                                 *
******************************************************************/
#ifndef Assert
#if defined( DEBUG ) || defined( _DEBUG )
#define Assert(b) do {if (!(b)) {OutputDebugStringA("Assert: " #b "\n");}} while(0)
#else
#define Assert(b)
#endif //DEBUG || _DEBUG
#endif
#ifndef HINST_THISCOMPONENT
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
#endif
_COM_SMARTPTR_TYPEDEF(ID2D1Factory,__uuidof(ID2D1Factory));
_COM_SMARTPTR_TYPEDEF(IWICImagingFactory, __uuidof(IWICImagingFactory));
_COM_SMARTPTR_TYPEDEF(IDWriteFactory , __uuidof(IDWriteFactory));
_COM_SMARTPTR_TYPEDEF(ID2D1HwndRenderTarget , __uuidof(ID2D1HwndRenderTarget));
_COM_SMARTPTR_TYPEDEF(IDWriteTextFormat, __uuidof(IDWriteTextFormat));
_COM_SMARTPTR_TYPEDEF(ID2D1PathGeometry , __uuidof(ID2D1PathGeometry));
_COM_SMARTPTR_TYPEDEF(ID2D1LinearGradientBrush , __uuidof(ID2D1LinearGradientBrush));
_COM_SMARTPTR_TYPEDEF(ID2D1SolidColorBrush , __uuidof(ID2D1SolidColorBrush));
_COM_SMARTPTR_TYPEDEF(ID2D1BitmapBrush , __uuidof(ID2D1BitmapBrush));
_COM_SMARTPTR_TYPEDEF(ID2D1Bitmap , __uuidof(ID2D1Bitmap));
/******************************************************************
*                                                                 *
*  Direct2dWindow                                                        *
*                                                                 *
******************************************************************/
namespace sf{
class Direct2dWindow
{
public:
Direct2dWindow();
~Direct2dWindow();
void Initialize();
void RunMessageLoop();
private:
HRESULT OnRender();
void CreateDeviceResources();
void DiscardDeviceResources();
void OnResize(
UINT width,
UINT height
);
static LRESULT CALLBACK WndProc(
HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam
);
private:
HWND hwnd_;
ID2D1FactoryPtr pD2DFactory_;
ID2D1HwndRenderTargetPtr pRenderTarget_;
};
}

・本体


#include &lt;stdlib.h>
#include &lt;malloc.h>
#include &lt;memory.h>
#include &lt;wchar.h>
#include &lt;math.h>
#include &lt;d2d1.h>
#include &lt;d2d1helper.h>
#include &lt;dwrite.h>
#include &lt;wincodec.h>
#include &lt;comdef.h>
#include "Direct2DBurn.h"
using namespace sf;
//
// Provides the entry point to the application.
//
int WINAPI WinMain(
HINSTANCE /* hInstance */,
HINSTANCE /* hPrevInstance */,
LPSTR /* lpCmdLine */,
int /* nCmdShow */
)
{
// Ignore the return value because we want to continue running even in the
// unlikely event that HeapSetInformation fails.
HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
if (SUCCEEDED(CoInitialize(NULL)))
{
{
Direct2dWindow app;
app.Initialize();
app.RunMessageLoop();
}
CoUninitialize();
}
return 0;
}
//
// Initialize members.
//
Direct2dWindow::Direct2dWindow() :hwnd_(NULL)
{
}
//
// Release resources.
//
Direct2dWindow::~Direct2dWindow()
{
pD2DFactory_.Release();
pRenderTarget_.Release();
}
//
// Creates the application window and initializes
// device-independent resources.
//
void Direct2dWindow::Initialize()
{
HRESULT hr;
// Create a Direct2D factory.
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory_);
if (SUCCEEDED(hr))
{
// Register the window class.
WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
wcex.style         = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc   = Direct2dWindow::WndProc;
wcex.cbClsExtra    = 0;
wcex.cbWndExtra    = sizeof(LONG_PTR);
wcex.hInstance     = HINST_THISCOMPONENT;
wcex.hbrBackground = NULL;
wcex.lpszMenuName  = NULL;
wcex.hCursor       = LoadCursor(NULL, IDC_ARROW);
wcex.lpszClassName = L"D2DDirect2dWindow";
RegisterClassEx(&wcex);
// Create the application window.
//
// Because the CreateWindow function takes its size in pixels, we
// obtain the system DPI and use it to scale the window size.
FLOAT dpiX, dpiY;
pD2DFactory_->GetDesktopDpi(&dpiX, &dpiY);
// Create the application window.
hwnd_ = CreateWindow(
L"D2DDirect2dWindow",
L"Direct2D Demo Application",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
static_cast<UINT>(ceil(640.f * dpiX / 96.f)),
static_cast<UINT>(ceil(480.f * dpiY / 96.f)),
NULL,
NULL,
HINST_THISCOMPONENT,
this
);
hr = hwnd_ ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
ShowWindow(hwnd_, SW_SHOWNORMAL);
UpdateWindow(hwnd_);
}
}
}
//
//  This method creates resources which are bound to a particular
//  Direct3D device. It's all centralized here, in case the resources
//  need to be recreated in case of Direct3D device loss (eg. display
//  change, remoting, removal of video card, etc).
//
void Direct2dWindow::CreateDeviceResources()
{
HRESULT hr = S_OK;
if (!pRenderTarget_)
{
RECT rc;
GetClientRect(hwnd_, &rc);
D2D1_SIZE_U size = D2D1::SizeU(
rc.right - rc.left,
rc.bottom - rc.top
);
// Create a Direct2D render target.
hr = pD2DFactory_->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(hwnd_, size),
&pRenderTarget_
);
}
}
//
// The main window message loop.
//
void Direct2dWindow::RunMessageLoop()
{
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
//
//  Called whenever the application needs to display the client
//  window. This method draws a bitmap a couple times, draws some
//  geometries, and writes "Hello, World"
//
//  Note that this function will not render anything if the window
//  is occluded (e.g. when the screen is locked).
//  Also, this function will automatically discard device-specific
//  resources if the Direct3D device disappears during function
//  invocation, and will recreate the resources the next time it's
//  invoked.
//
HRESULT Direct2dWindow::OnRender()
{
HRESULT hr;
CreateDeviceResources();
if (!(pRenderTarget_->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED))
{
static const WCHAR sc_helloWorld[] = L"Hello, World!";
// Retrieve the size of the render target.
D2D1_SIZE_F renderTargetSize = pRenderTarget_->GetSize();
pRenderTarget_->BeginDraw();
pRenderTarget_->SetTransform(D2D1::Matrix3x2F::Identity());
pRenderTarget_->Clear(D2D1::ColorF(D2D1::ColorF::White));
hr = pRenderTarget_->EndDraw();
if (hr == D2DERR_RECREATE_TARGET)
{
//hr = S_OK;
DiscardDeviceResources();
}
}
return hr;
}
void Direct2dWindow::DiscardDeviceResources()
{
}
//
//  If the application receives a WM_SIZE message, this method
//  resize the render target appropriately.
//
void Direct2dWindow::OnResize(UINT width, UINT height)
{
if (pRenderTarget_)
{
D2D1_SIZE_U size;
size.width = width;
size.height = height;
// Note: This method can fail, but it's okay to ignore the
// error here -- it will be repeated on the next call to
// EndDraw.
pRenderTarget_->Resize(size);
}
}
//
// The window message handler.
//
LRESULT CALLBACK Direct2dWindow::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT result = 0;
if (message == WM_CREATE)
{
LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
Direct2dWindow *pDirect2dWindow = (Direct2dWindow *)pcs->lpCreateParams;
::SetWindowLongPtrW(
hwnd,
GWLP_USERDATA,
PtrToUlong(pDirect2dWindow)
);
result = 1;
}
else
{
Direct2dWindow *pDirect2dWindow = reinterpret_cast<Direct2dWindow *>(static_cast<LONG_PTR>(
::GetWindowLongPtrW(
hwnd,
GWLP_USERDATA
)));
bool wasHandled = false;
if (pDirect2dWindow)
{
switch (message)
{
case WM_SIZE:
{
UINT width = LOWORD(lParam);
UINT height = HIWORD(lParam);
pDirect2dWindow->OnResize(width, height);
}
result = 0;
wasHandled = true;
break;
case WM_PAINT:
case WM_DISPLAYCHANGE:
{
PAINTSTRUCT ps;
BeginPaint(hwnd, &ps);
pDirect2dWindow->OnRender();
EndPaint(hwnd, &ps);
}
result = 0;
wasHandled = true;
break;
case WM_DESTROY:
{
PostQuitMessage(0);
}
result = 1;
wasHandled = true;
break;
}
}
if (!wasHandled)
{
result = DefWindowProc(hwnd, message, wParam, lParam);
}
}
return result;
}