Top > WINDOWS >TurboC++でGDI+

TurboC++でGDI+

TurboC++では、VCLを利用することで比較的簡単にグラフィックの描画を行うことができます。 しかしながら、右の画像のように半透明処理やアンチエイリアシングなどの 高度なグラフィック処理を実現するためには、必要な処理を自分で用意する必要がありました。 GDI+はベクタベースのクラスライブラリで、 あまり高速なグラフィック処理を行うことはできませんが、 このような処理を簡単に実現することができます。 また、GDI+はDLLとして用意されているため、アプリケーションとリンクさせる必要があるほか、 開始・終了処理を行う必要があります。以下にGDI+をTurboC++で利用するために必要な処理を示していきます。

なお、WindowsXP以降ではGDI+がDLLとしてOSに組み込まれているため、 特にアプリケーションを実行するために必要なものはありませんが、 Windows2000以前のOSではgdiplus.dllをMicrosoftのホームページからダウンロードして、 アプリケーションと同じディレクトリにおいておく必要があります。


GDI+のリンク

TurboC++で新規VCLプロジェクトを作成すると、<プロジェクト名>.cppという ファイルが作成されているはずです。そこで、gdiplus.libをリンクします。

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
USEFORM("Unit1.cpp", Form1);
//---------------------------------------------------------------------------

//gdiplus.libをリンク
#pragma link "gdiplus.lib"

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
	try
	{
		Application->Initialize();
		Application->CreateForm(__classid(TForm1), &Form1);
		Application->Run();
	}
	catch (Exception &exception)
	{
		Application->ShowException(&exception);
	}
	catch (...)
	{
		try
		{
			throw Exception("");
		}
		catch (Exception &exception)
		{
			Application->ShowException(&exception);
		}
	}
	return 0;
}
//---------------------------------------------------------------------------

GDI+の初期化と終了処理

GDI+の使用前、使用後には、それぞれ初期化処理と終了処理を行う必要があります。 また、すべてのGDI+オブジェクトは初期化処理と終了処理の間で使用しなければなりません。 今回はメインフォームのコンストラクタで初期化処理を、 デストラクタで終了処理を行っています。

初期化・終了時に必要な引数

GDI+を初期化するために必要なgdiplusTokenおよび、 gdiplusStartupInputを用意します。 以下の例では、メインフォームのメンバ変数として用意していますが、 グローバル変数として宣言してもよいです。

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE 管理のコンポーネント
	void __fastcall FormPaint(TObject *Sender);
private:	// ユーザー宣言

	//GDI+の初期化に必要なオブジェクト
	ULONG_PTR	gdiplusToken;
	Gdiplus::GdiplusStartupInput	gdiplusStartupInput;

public:		// ユーザー宣言

	//コンストラクタとデストラクタ
	__fastcall TForm1(TComponent* Owner);
	__fastcall ~TForm1();
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

初期化処理と終了処理

GDI+の初期化処理と終了処理を以下に示します。 いずれも1行程度の簡単な処理です。

//コンストラクタ
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	//GDIPLUSの初期化
	Gdiplus::GdiplusStartup( &gdiplusToken, &gdiplusStartupInput, NULL );
}
//---------------------------------------------------------------------------

//デストラクタ
__fastcall TForm1::~TForm1()
{
	//GDIPLUSの開放
	Gdiplus::GdiplusShutdown( gdiplusToken );
}
//---------------------------------------------------------------------------

GDI+による描画処理

GDI+を使うための準備が整ったので、あとは描画処理を記述するだけです。 以下にサンプルプログラムを置いておきます。 実行するとおよそ右の画像のような結果が得られるはずです。


ヘッダファイルのインクルード

ソースファイルの先頭で、GDI+を使用するためにgdiplus.hをインクルードします。 また、ハンドルの識別を行うためにSTRICTを定義しておきます。

//---------------------------------------------------------------------------

#define STRICT
#include <vcl.h>
#pragma hdrstop

#include <gdiplus.h>

#include "Unit1.h"
//---------------------------------------------------------------------------

グラフィックの描画

あとは、任意にGDI+を使用して描画処理を行います。 今回は、フォームのOnPaintイベントで描画処理を行いました。 GDI+の描画処理は、すべてGdiplus::Graphicsオブジェクトを介して行われます。 また、Graphicsオブジェクトはデバイスコンテキストを引数に生成されます。

//描画リクエスト
void __fastcall TForm1::FormPaint(TObject *Sender)
{
	//変換行列の生成
	Gdiplus::Matrix mx;
	mx.RotateAt(30, Gdiplus::PointF(50, 50), Gdiplus::MatrixOrderAppend);

 	//キャンバスを作って、塗りつぶします
	Gdiplus::Graphics g(Canvas->Handle);
	g.SetTransform(&mx);
	g.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
	g.Clear(Gdiplus::Color(255, 255, 255));

	//指定のペンで線を描画します
	Gdiplus::Pen pen(Gdiplus::Color(100, 100, 255), 2.0f);
	g.DrawLine(&pen, 100, 0, 100, 300);

	pen.SetColor(Gdiplus::Color(100, 255, 100, 100));
	pen.SetWidth(8.0f);
	g.DrawLine(&pen, 30, 30, 300, 30);

	//指定のブラシで楕円を描画します
	Gdiplus::SolidBrush brush(Gdiplus::Color(120, 100, 255, 100));
	g.FillEllipse(&brush, 50, 0, 150, 100);
}
//---------------------------------------------------------------------------