わびさびサンプルソース

WindowsやHTML5などのプログラムのサンプルコードやフリーソフトを提供します。

Direct2Dで円の描画を行う

Direct2Dで円の描画を行うには、ID2D1HwndRenderTarget::DrawEllipse()メソッドを呼び出します。 円はブラシで描画されますので、好きな色でブラシを生成しておきます。DrawEllipse()メソッドでは線の幅も指定できます。

#include <stdio.h>
#include <tchar.h>
#include <locale.h>
#include <iostream>
#include <windows.h>
#include <d2d1.h>
#include <wincodec.h>
#include <wincodecsdk.h>



// lib
#pragma comment( lib, "d2d1.lib" )
#pragma comment( lib, "WindowsCodecs.lib" )



/*
	メインウインドウイベント処理
*/
LRESULT CALLBACK eMainWindowProc(
	  HWND	 hwnd	// handle to window
	, UINT	 uMsg	// message identifier
	, WPARAM wParam // first message parameter
	, LPARAM lParam // second message parameter
);



// グローバル変数
ID2D1Factory* pD2d1Factory = NULL;
ID2D1HwndRenderTarget* pRenderTarget = NULL;



/*
	Direct2Dで円を描画する
*/
int _tmain
(
	  int argc
	, _TCHAR* argv[]
)
{
	// std::wcoutのロケールを設定
	std::wcout.imbue( std::locale( "", std::locale::ctype ) );

	// COM初期化
	::CoInitialize( NULL );

	WNDCLASSEX tWndClass;
	HINSTANCE  hInstance;
	TCHAR*	   cpClassName;
	TCHAR*	   cpWindowName;
	TCHAR*	   cpMenu;
	HWND	   hWnd;
	MSG		   tMsg;


	// アプリケーションインスタンス
	hInstance	 = ::GetModuleHandle( NULL );

	// クラス名称
	cpClassName	 = _T("MainWindowClass");

	// メニュー
	cpMenu		 = MAKEINTRESOURCE( NULL );

	// ウインドウ名称
	cpWindowName = _T("Direct2Dで円を描画");

	// ウインドウクラスパラメータセット
	tWndClass.cbSize		= sizeof( WNDCLASSEX );
	tWndClass.style			= CS_HREDRAW | CS_VREDRAW;
	tWndClass.lpfnWndProc	= eMainWindowProc;
	tWndClass.cbClsExtra	= 0;	// ::GetClassLong で取得可能なメモリ
	tWndClass.cbWndExtra	= 0;	// ::GetWindowLong で取得可能なメモリ
	tWndClass.hInstance		= hInstance; 
	tWndClass.hIcon			= ::LoadIcon( NULL, IDI_APPLICATION );
	tWndClass.hCursor		= ::LoadCursor( NULL, IDC_ARROW );
	tWndClass.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 );
	tWndClass.lpszMenuName	= cpMenu;
	tWndClass.lpszClassName = cpClassName;
	tWndClass.hIconSm		= NULL;

	// ウインドウクラス生成
	if ( 0 == ::RegisterClassEx( &tWndClass ) ) {

		/* 失敗 */
		return( -1 );
	}

	// ウインドウを生成する
	hWnd = ::CreateWindowEx (
		  0						  // extended window style
		, tWndClass.lpszClassName // pointer to registered class name
		, cpWindowName			  // pointer to window name
		, WS_OVERLAPPEDWINDOW	  // window style
		, CW_USEDEFAULT			  // horizontal position of window
		, CW_USEDEFAULT			  // vertical position of window
		, 640					  // window width
		, 480					  // window height
		, NULL					  // handle to parent or owner window
		, NULL					  // handle to menu, or child-window identifier
		, hInstance				  // handle to application instance
		, (VOID*)0x12345678		  // pointer to window-creation data
	);


	/*
		メッセージループ
	*/
	while( 0 != ::GetMessage( &tMsg, NULL, 0, 0 ) ) {
		::TranslateMessage ( &tMsg );
		::DispatchMessage ( &tMsg );
	}

	// COM初期化
	::CoUninitialize();

	// WM_QUITの終了コードを返却する
	return( tMsg.wParam );
}



/*
	メインウインドウイベント処理
*/
LRESULT CALLBACK eMainWindowProc
(
	  HWND	 hWnd	// handle to window
	, UINT	 uMsg	// message identifier
	, WPARAM wParam // first message parameter
	, LPARAM lParam // second message parameter
)
{
	switch( uMsg ) {
	case WM_CREATE:
	//--------------------------------------------
	// WM_CREATE
	//--------------------------------------------
		{
			CREATESTRUCT* tpCreateSt = (CREATESTRUCT*)lParam;

			/* パラメータ表示 */
			wprintf(
				L"CREATESTRUCT¥n"
				L"¥tlpCreateParams = 0x%08x¥n"
				L"¥thInstance	   = 0x%08x¥n"
				L"¥thMenu		   = 0x%08x¥n"
				L"¥thwndParent	   = 0x%08x¥n"
				L"¥tcy			   = %d¥n"
				L"¥tcx			   = %d¥n"
				L"¥ty			   = %d¥n"
				L"¥tx			   = %d¥n"
				L"¥tstyle		   = 0x%08x¥n"
				L"¥tlpszName	   = ¥"%s¥"¥n"
				L"¥tlpszClass	   = ¥"%s¥"¥n"
				L"¥tdwExStyle	   = 0x%08x¥n"
				, tpCreateSt->lpCreateParams
				, tpCreateSt->hInstance
				, tpCreateSt->hMenu
				, tpCreateSt->hwndParent
				, tpCreateSt->cy
				, tpCreateSt->cx
				, tpCreateSt->y
				, tpCreateSt->x
				, tpCreateSt->style
				, tpCreateSt->lpszName
				, tpCreateSt->lpszClass
				, tpCreateSt->dwExStyle
			);

			HRESULT hResult = S_OK;


			/*
				ID2D1Factoryの生成
			*/
			hResult = ::D2D1CreateFactory( D2D1_FACTORY_TYPE_MULTI_THREADED, &pD2d1Factory );
			if ( FAILED( hResult ) ) {

				// エラー
				std::wcout << L"D2D1CreateFactory失敗" << std::endl;
				break;
			}


			/*
				ID2D1HwndRenderTargetの生成
			*/
			{
				D2D1_SIZE_U oPixelSize = {
					  tpCreateSt->cx
					, tpCreateSt->cy
				};

				D2D1_RENDER_TARGET_PROPERTIES oRenderTargetProperties = D2D1::RenderTargetProperties();

				D2D1_HWND_RENDER_TARGET_PROPERTIES oHwndRenderTargetProperties = D2D1::HwndRenderTargetProperties( hWnd, oPixelSize );


				/*
					ID2D1HwndRenderTargetの生成
				*/
				hResult = pD2d1Factory->CreateHwndRenderTarget(
						  oRenderTargetProperties
						, oHwndRenderTargetProperties
						, &pRenderTarget
					);
				if ( FAILED( hResult ) ) {

					// エラー
					std::wcout << L"CreateHwndRenderTarget失敗" << std::endl;
					break;
				}
			}

			// ウインドウを表示する
			::ShowWindow( hWnd, SW_SHOW );
		}
		break;


	case WM_DESTROY:
	//--------------------------------------------
	// WM_DESTROY
	//--------------------------------------------
		{
			// ID2D1HwndRenderTargetの破棄
			if ( NULL != pRenderTarget )  {
				pRenderTarget->Release();
			}

			// ID2D1Factoryの破棄
			if ( NULL != pD2d1Factory )  {
				pD2d1Factory->Release();
			}

			// 終了する( 引数はそのまま終了コードとなります )
			::PostQuitMessage( 0 );
		}
		break;


	case WM_SIZE:
	//--------------------------------------------
	// WM_SIZE
	//--------------------------------------------
		{
			D2D1_SIZE_U oPixelSize = { LOWORD( lParam ), HIWORD( lParam ) };

			// ターゲットリサイズ
			pRenderTarget->Resize( &oPixelSize );
		}
		break;


	case WM_ERASEBKGND:
	//--------------------------------------------
	// WM_ERASEBKGND
	//--------------------------------------------
		{
			;
		}
		return( TRUE );


	case WM_PAINT:
	//--------------------------------------------
	// WM_PAINT
	//--------------------------------------------
		{
			HRESULT hResult = S_OK;

			// ターゲットサイズの取得
			D2D1_SIZE_F oTargetSize = pRenderTarget->GetSize();

			// 描画開始
			PAINTSTRUCT tPaintStruct;
			::BeginPaint( hWnd, &tPaintStruct );

			// 描画開始(Direct2D)
			pRenderTarget->BeginDraw();

			// 背景のクリア
			D2D1_COLOR_F oBKColor = { 1.0f, 1.0f, 1.0f, 1.0f };
			pRenderTarget->Clear( oBKColor );



			/*
				円の描画
			*/
			{
				for ( int nI = 0; nI < oTargetSize.height * 2; nI += 10 ) {

					// ブラシの生成
					ID2D1SolidColorBrush* pBrush = NULL;
					{
						pRenderTarget->CreateSolidColorBrush(
								  D2D1::ColorF(
										  (float)( nI / ( oTargetSize.height * 2 ) )	// R
										, 0.0f											// G
										, 0.0f											// B
										, 1.0f											// A
									)
								, &pBrush
							);
					}

					if ( NULL != pBrush ) {

						// 中心
						D2D1_POINT_2F tCenter = D2D1::Point2F(
								  oTargetSize.width  / 2
								, oTargetSize.height / 2
							);

						// 線の幅
						float fStrokeWidth = (float)( ( nI / 10 ) % 3 + 1 );

						// 楕円パラメータ
						D2D1_ELLIPSE tEllipse = D2D1::Ellipse(
								  tCenter		// 中心
								, (float)nI		// 半径X
								, (float)nI / 2	// 半径Y
							);


						// 円の描画
						pRenderTarget->DrawEllipse( &tEllipse, pBrush, fStrokeWidth );

						// ブラシの破棄
						pBrush->Release();
					}
				}
			}

			// 描画終了(Direct2D)
			pRenderTarget->EndDraw();

			// 描画終了
			::EndPaint( hWnd, &tPaintStruct );
		}
		return( FALSE );
	}

	// デフォルト処理呼び出し
	return ::DefWindowProc( hWnd, uMsg, wParam, lParam );
}



実行結果







わびさびサンプルソース

WindowsやHTML5などのプログラムのサンプルコードやフリーソフトを提供します。