Direct2Dで線の描画を行うには、ID2D1HwndRenderTarget::DrawLine()メソッドを呼び出します。 線はブラシで描画されますので、好きな色でブラシを生成しておきます。DrawLine()メソッドでは線の幅も指定できます。
#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 * 4; nI += 20 ) {
// ブラシの生成
ID2D1SolidColorBrush* pBrush = NULL;
{
pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(
(float)( nI / ( oTargetSize.height * 4 ) ) // R
, 0.0f // G
, 0.0f // B
, 1.0f // A
)
, &pBrush
);
}
if ( NULL != pBrush ) {
// 始点
D2D1_POINT_2F tPosS = D2D1::Point2F( 0, 0 );
// 終点
D2D1_POINT_2F tPosE = D2D1::Point2F( oTargetSize.width, (float)nI );
// 線の幅
float fStrokeWidth = (float)( ( nI / 10 ) % 3 + 1 );
// 線の描画
pRenderTarget->DrawLine( tPosS, tPosE, pBrush, fStrokeWidth );
// ブラシの破棄
pBrush->Release();
}
}
}
// 描画終了(Direct2D)
pRenderTarget->EndDraw();
// 描画終了
::EndPaint( hWnd, &tPaintStruct );
}
return( FALSE );
}
// デフォルト処理呼び出し
return ::DefWindowProc( hWnd, uMsg, wParam, lParam );
}
