wxWidgets   グラフィックス

ホーム   C/C++チュートリアル


デバイスコンテキスト


デバイスコンテキスト(Device context)とは、ディスプレイやプリンターなどのデバイス(Device、装置)に描画するためのGUIパーツです。wxwidgetsでは、DC(デバイスコンテキスト)に、いろいろなグラフィックスを描きます。

ライン

line.cpp


#include <wx/wx.h>

class Line : public wxFrame
{
public:
    Line();
    void OnPaint(wxPaintEvent & event);
};

class App : public wxApp
{
public:
    virtual bool OnInit();
};

Line::Line() : wxFrame(NULL, -1, "Line", wxDefaultPosition, wxSize(400, 340))
{
    
    Connect(wxEVT_PAINT, wxPaintEventHandler(Line::OnPaint));
}

void Line::OnPaint(wxPaintEvent & event)
{
    wxPaintDC *dc = new wxPaintDC(this);
    dc->SetPen(wxPen(wxColour("yellow"),   1, wxSOLID));
    dc->DrawLine(20, 40, 380, 40);
    dc->SetPen(wxPen(wxColour("magenta"), 10, wxDOT));
    dc->DrawLine(20, 80, 380, 80);
    dc->SetPen(wxPen(wxColour("cyan"),     1, wxLONG_DASH));
    dc->DrawLine(20, 120, 380, 120);
    dc->SetPen(wxPen(wxColour("red"),     10, wxSHORT_DASH));
    dc->DrawLine(20, 160, 380, 160);
    dc->SetPen(wxPen(wxColour("green"),    1, wxDOT_DASH));
    dc->DrawLine(20, 200, 380, 200);
    dc->SetPen(wxPen(wxColour("blue"),    10, wxTRANSPARENT));
    dc->DrawLine(200, 240, 380, 240);
    dc->SetPen(wxPen(wxColour("black")));
    dc->DrawLine(20, 280, 380, 280);
}

IMPLEMENT_APP(App)

bool App::OnInit()
{
    Line *line = new Line();
    line->Show();
    return true;
}
    



コード説明

  1. void OnPaint(wxPaintEvent & event);
    グラフィックに関するイベントは wxPainEvent 型で渡します。
  2. Connect(wxEVT_PAINT, wxPaintEventHandler(Line::OnPaint));
    フレームが描画される時に発するイベントは wxEVT_PAINT です。何が描画されうのが 分かってるからなのか、IDは指定しません。
  3. wxPaintDC *dc = new wxPaintDC(this);
    wxPaintDCクラスからデバイスコンテキストを作ります。 引数に所属するウィンドウを指定します。
  4. dc->SetPen(wxPen(wxColour("yellow"), 1, wxSOLID));
    デバイスコンテキストのSetPen関数で描画するペンの設定をします。 この設定は次に設定し直すまで有効になります。 引数は次のとおりです。
    1. 第1引数に色を指定します。wxColoruで 引数に指定した文字列が表す色が作れます
    2. 第2引数にペンの幅を指定します
    3. 第3引数にペンで描く線の種類を設定します。wxSOLIDは普通の線になります
  5. dc->DrawLine(20, 40, 380, 40);
    デバイスコンテキストのDrawLine関数で直線を描きます。引数は次のとおりです。
    1. 第1引数に線の開始点の横の位置を指定します
    2. 第2引数に線の開始点の縦の位置を指定します
    3. 第3引数に線の終了点の横の位置を指定します
    4. 第4引数に線の終了点の縦の位置を指定します
  6. dc->SetPen(wxPen(wxColour("magenta"), 10, wxDOT));
    第3引数のwxDOTは、点線という意味になります。
  7. dc->SetPen(wxPen(wxColour("cyan"), 1, wxLONG_DASH));
    第3引数のwxLOGN_DASHは長い横棒という意味になります。
  8. dc->SetPen(wxPen(wxColour("red"), 10, wxSHORT_DASH));
    第3引数のwxSHORT_DASHは短い横棒という意味になります。
  9. dc->SetPen(wxPen(wxColour("blue"), 10, wxTRANSPARENT));
    第3引数のwxTRANSPARENTは透明という意味です。
  10. dc->SetPen(wxPen(wxColour("black")));
    第2引数と、第3引数を省略した場合は、ペン幅が1で、線の種類がwxSOLID(普通の線) になります。


ポイント

point.cpp


#include <wx/wx.h>
#include <time.h>

class Point : public wxFrame
{
public:
    Point();
    void OnPoint(wxPaintEvent & event);
};

class App : public wxApp
{
public:
    virtual bool OnInit();
};

Point::Point() : wxFrame(NULL, -1, "Point")
{
    Connect(wxEVT_PAINT, wxPaintEventHandler(Point::OnPoint));
    srand(time(NULL));
}

void Point::OnPoint(wxPaintEvent & event)
{
    wxPaintDC dc(this);
    int x = 0, y = 0;
    wxSize size = GetSize();
    for (int i = 0; i < 1000; i++) {
        x = rand() % size.x + 1;
        y = rand() % size.y + 1;
        dc.DrawPoint(x, y);
    }
}

IMPLEMENT_APP(App)

bool App::OnInit()
{
    Point *point = new Point();
    point->Show();
    return true;
}
    



コード説明

  1. #include <time.h>
    乱数を初期化するのに現在の時刻を使うために、time.h を読みます。
  2. srand(time(NULL));
    C++の乱数は決めれられた乱数表から取得されます。 このため、そのまま使うと毎回同じ乱数になります。 そこで現在の時刻で初期化することで乱数表をずらして違う乱数にします。
    1. time(NULL)は1970年1月1日から現在までの経過秒数が得られます
    2. srand( )関数は引数の値で乱数を初期化します
  3. wxSize size = GetSize();
    GetSize( )関数でフレーム(ウィンドウ)のサイズが得られます。
  4. x = rand() % size.x + 1;
    1. rand( )関数は 0 から 2147483647 (約21億)までの乱数を発生します。 Windowsの場合は 0 から 32767 までの乱数を発生します
    2. size.xはウィンドウの横のサイズを表します
    3. rand() を size.x で割った余りは 0 からウィンドウの横サイズ-1 までの値になります
    4. 上記の値に 1 を足せば 1 からウィンドウの横サイズまでの乱数が得られます
  5. dc.DrawPoint(x, y);
    デバイスコンテキストのDrawPoint関数は点を描きます。引数は次のとおりです。
    1. 第1引数に点の横位置を指定します
    2. 第2引数に点の縦位置を指定します


カラー

color.cpp


#include <wx/wx.h>

class Color : public wxFrame
{
public:
    Color();
    void OnColor(wxPaintEvent & event);
};

class App : public wxApp
{
    virtual bool OnInit();
};

Color::Color() : wxFrame(NULL, -1, "Color", wxDefaultPosition, wxSize(380, 235))
{
    Connect(wxEVT_PAINT, wxPaintEventHandler(Color::OnColor));
}

void Color::OnColor(wxPaintEvent & event)
{
    wxPaintDC dc(this);
    dc.SetPen(wxColour("yellow"));
    dc.SetBrush(wxColour("yellow"));
    dc.DrawRectangle(20, 20, 100, 75);
    dc.SetPen(wxColour("magenta"));
    dc.SetBrush(wxColour("magenta"));
    dc.DrawRectangle(140, 20, 100, 75);
    dc.SetPen(wxColour("cyan"));
    dc.SetBrush(wxColour("cyan"));
    dc.DrawRectangle(260, 20, 100, 75);
    dc.SetPen(wxColour("red"));
    dc.SetBrush(wxColour("red"));
    dc.DrawRectangle(20, 115, 100, 75);
    dc.SetPen(wxColour("green"));
    dc.SetBrush(wxColour("green"));
    dc.DrawRectangle(140, 115, 100, 75);
    dc.SetPen(wxColour("blue"));
    dc.SetBrush(wxColour("blue"));
    dc.DrawRectangle(260, 115, 100, 75);
}

IMPLEMENT_APP(App)

bool App::OnInit()
{
    Color *color = new Color();
    color->Show();
    return true;
}
	



コード説明

  1. dc.SetPen(wxColour("yellow"));
    SetPen関数に色だけを指定すれば、幅が1ピクセルの普通の線になります。
  2. dc.SetBrush(wxColour("yellow"));
    SetBrush関数で引数の色で図形を塗りつぶすことになります。
  3. dc.DrawRectangle(20, 20, 100, 75);
    DrawRectangle関数で長方形を描きます。 SetBrushも設定していますので中も塗り潰されます。引数は次のとおりです。
    1. 第1引数に長方形の左上の横の位置を指定します
    2. 第2引数に長方形の左上の縦の位置を指定します
    3. 第3引数に長方形の横のサイズ(大きさ)を指定します
    4. 第4引数に長方形の縦のサイズ(大きだ)を指定します


シェープ

shape.cpp


#include <wx/wx.h>

class Shape : public wxFrame
{
public:
    Shape();
    void OnShape(wxPaintEvent & event);
};

class App : public wxApp
{
public:
    virtual bool OnInit();
};

Shape::Shape() : wxFrame(NULL, -1, "Shape", wxPoint(-1,-1), wxSize(390, 260))
{
    Connect(wxEVT_PAINT, wxPaintEventHandler(Shape::OnShape));
}

void Shape::OnShape(wxPaintEvent & event)
{
    wxPaintDC dc(this);
    dc.SetPen(wxColour(255, 17, 17));
    dc.SetBrush(wxColour(17, 255, 17));
    //dc.SetBrush(wxColour("#777777"));
    dc.DrawEllipse(20, 20, 100, 75);
    dc.DrawRoundedRectangle(140, 20, 100, 75, 10);
    dc.DrawArc(250, 57, 370, 57,310, 20);
    dc.DrawCircle(70, 165,50);
    dc.DrawRectangle(140, 115, 100, 100);
    dc.DrawText("Hello wxWidgets!", 270, 160);
}

IMPLEMENT_APP(App)

bool App::OnInit()
{
    Shape *shape = new Shape();
    shape->Show();
    return true;
}
	



コード説明

  1. dc.SetPen(wxColour(255, 17, 17));
    色を作る時に、色を表す文字列を指定する方法以外に、 光の三原色の値を指定する方法もあります。
    1. 第1引数に光の三原色の赤の値を 0 から 255 までの整数で指定します
    2. 第1引数に光の三原色の緑の値を 0 から 255 までの整数で指定します
    3. 第1引数に光の三原色の青の値を 0 から 255 までの整数で指定します
  2. dc.SetBrush(wxColour("#777777"));
    色を表す16進数の文字列で色を指定することもできます。
  3. dc.DrawEllipse(20, 20, 100, 75);
    DrawEllipse関数は楕円形を描きます。引数は次のとおりです。
    1. 第1引数に楕円形が内接する長方形の左上の横位置を指定します
    2. 第2引数に楕円形が内接する長方形の左上の縦位置を指定します
    3. 第3引数に楕円形が内接する長方形の横のサイズを指定します
    4. 第4引数に楕円形が内接する長方形の縦のサイズを指定します
  4. dc.DrawRoundedRectangle(140, 20, 100, 75, 10);
    DrawRoundedRectangle関数は角丸長方形を作ります。引数は次のとおりです。
    1. 第1引数に角丸長方形が内接する長方形の左上の横位置を指定します
    2. 第2引数に角丸長方形が内接する長方形の左上の縦位置を指定します
    3. 第3引数に角丸長方形が内接する長方形の横のサイズを指定します
    4. 第4引数に角丸長方形が内接する長方形の縦のサイズを指定します
    5. 第5引数に角丸長方形の角丸の半径を指定します
  5. DrawArc関数は円弧を描きます。円弧は反時計回りに描かれます。 円弧とその円の中心点を結ぶ線も描かれます。引数は次のとおりです。
    1. 第1引数に円弧の開始地点の横の位置を指定します
    2. 第2引数に円弧の開始地点の縦の位置を指定します
    3. 第3引数に円弧の終了地点の横の位置を指定します
    4. 第4引数に円弧の終了地点の縦の位置を指定します
    5. 第5引数に円弧の円の中心点の横の位置を指定します
    6. 第6引数に円弧の円の中心点の縦の位置を指定します
  6. dc.DrawCircle(70, 165,50);
    DrawCircle関数は正円を描きます。引数は次のとおりです。
    1. 第1引数に正円の中心点の横位置を指定します
    2. 第2引数に正円の中心点の縦位置を指定します
    3. 第3引数に正円の半径を指定します
  7. dc.DrawRectangle(140, 115, 100, 100);
    DrawRectangle関数で横と縦のサイズを同じにすると正方形になります。
  8. dc.DrawText("Hello wxWidgets!", 270, 160);
    DrawText関数はデバイスコンテキストに文字列を描きます。引数は次のとおりです。
    1. 第1引数に描画する文字列を指定します
    2. 第2引数に文字列が描かれる開始地点の横位置を指定します
    3. 第3引数に文字列が描かれる開始地点の縦位置を指定します



702 visits
Posted: Nov. 29, 2019
Update: Dec. 29, 2019

ホーム   C/C++チュートリアル   目次