図形の描画2
長方形の描画
前ページで直線を引く方法を説明しました。
直線が引ければ長方形も描画できるのですが、長方形の描画は専用の関数が用意されています。
Rectangle関数
長方形の描画はRectangle
関数を使用します。
- BOOL Rectangle(
HDC hdc,
int left,
int top,
int right,
int bottom
); - 長方形を描画する。
成功した場合は0以外を、失敗した場合は0を返す。
座標の指定方法はRECT構造体と同じです。
left
、top
が長方形の左上の座標を、right
、bottom
が右下の座標を表します。
この関数はLineTo関数などとは異なり現在の座標を使用しません。
描画の起点としても使用しませんし、描画後も現在の座標を更新しません。
このページで紹介する図形描画関数は、図形の内部に「塗り」という処理が行われています。
LineTo関数で同じ形の四角形を描画しても「塗り」は行われません。
「塗り」についてはブラシの項で説明します。
RoundRect関数
RoundRect
関数は角丸の長方形を描画できます。
-
BOOL RoundRect(
HDC hdc,
int left,
int top,
int right,
int bottom,
int width,
int height
); - 角丸長方形を描画する。
成功した場合は0以外を、失敗した場合は0を返す。
width
は角の楕円の幅を、height
は高さを表します。
サンプルコード
ここまでのサンプルコードです。
//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
switch (message)
{
case WM_PAINT: //ウィンドウの描画
hdc = BeginPaint(hWnd, &ps);
Rectangle(hdc, 10, 10, 210, 60);
RoundRect(hdc, 10, 70, 210, 120, 10, 10);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY: //ウィンドウの破棄
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
通常の長方形と角丸の長方形を描画しています。
多角形の描画
Polygon関数
多角形はPolygon
関数で描画できます。
- BOOL Polygon(
HDC hdc,
const POINT *apt,
int cpt
); - POINT配列aptの各座標を結んだ多角形を描画する。
成功した場合は0以外を、失敗した場合は0を返す。
引数apt
はPOINT構造体の配列、引数cpt
は配列apt
の要素数です。
配列の要素数は2以上が必要です。
要素数が2の場合は直線が描画されます。
要素数が3以上の時、最後の座標から最初の座標への直線が描画されます。
つまり三角形の描画ならば座標情報は3つで良いということです。
PolyPolygon関数
PolyPolygon
関数は多角形を複数同時に描画できます。
使い方はPolyPolyline関数とよく似ています。
- BOOL PolyPolygon(
HDC hdc,
const POINT *apt,
const INT *asz,
int csz
); - 多角形を複数描画する。
成功した場合は0以外を、失敗した場合は0を返す。
第二引数apt
はPOINT構造体の配列です。
第三引数asz
は各多角形の頂点の数を格納する配列で、この配列の要素数が描画可能な多角形の数になります。
この配列の各要素の値は2以上が必要です。
第四引数csz
は描画する多角形の数です。
//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
POINT points1[] = {
{60, 10},
{20, 100},
{110, 40},
{10, 40},
{100, 100}
};
POINT points2[] = {
{60 + 120, 10},
{10 + 120, 85},
{110 + 120, 85},
{60 + 120, 110},
{10 + 120, 35},
{110 + 120, 35}
};
DWORD vertices[] = {
3, 3
};
switch (message)
{
case WM_PAINT: //ウィンドウの描画
hdc = BeginPaint(hWnd, &ps);
Polygon(hdc, points1, 5);
PolyPolygon(hdc, points2, vertices, 2);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY: //ウィンドウの破棄
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
五個の頂点情報で五芒星を、三個の頂点情報ふたつで六芒星を描画しています。
円の描画
Ellipse関数
円はEllipse
関数で描画できます。
- BOOL Ellipse(
HDC hdc,
int left,
int top,
int right,
int bottom
); - 円を描画する。
成功した場合は0以外を、失敗した場合は0を返す。
この関数の引数はRectangle
関数と同じで、長方形の四辺に内接する円を描画します。
正方形を指定すれば正円になります。
//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
switch (message)
{
case WM_PAINT: //ウィンドウの描画
hdc = BeginPaint(hWnd, &ps);
Rectangle(hdc, 10, 10, 110, 110);
Ellipse(hdc, 10, 10, 110, 110);
Rectangle(hdc, 120, 10, 220, 60);
Ellipse(hdc, 120, 10, 220, 60);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY: //ウィンドウの破棄
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
このサンプルコードではEllipse関数と同じ引数でRectangle関数を実行し、長方形も一緒に描画しています。
Ellipse関数だけでは長方形自体は描画されない点に注意してください。
扇、円弧、弦の描画
Pie関数、Arc関数、Chord関数
扇型の図形はPie
関数で、円弧はArc
関数で、弦はChord
で描画できます。
- BOOL Pie(
HDC hdc,
int left,
int top,
int right,
int bottom,
int xr1,
int yr1,
int xr2,
int yr2
); - 扇を描画する。
成功した場合は0以外を、失敗した場合は0を返す。
- BOOL Arc(
HDC hdc,
int left,
int top,
int right,
int bottom,
int xr1,
int yr1,
int xr2,
int yr2
); - 円弧を描画する。
成功した場合は0以外を、失敗した場合は0を返す。
- BOOL Chord(
HDC hdc,
int left,
int top,
int right,
int bottom,
int xr1,
int yr1,
int xr2,
int yr2
); - 弦を描画する。
成功した場合は0以外を、失敗した場合は0を返す。
これらの関数は同じ形状の図形を定義するので、引数の意味は三つとも同じです。
扇は円の中心から円周への二本の線と孤を描画します。
円弧は円周の孤のみを描画します。
弦は二本の線が円周に接する点同士を結ぶ線と孤を描画します。
「円の中心から円周への二本の線」の一本目は引数xr1
とyr1
、二本目はxr2
とyr2
で定義します。
一本目から反時計回りに二本目の間が描画されます。
これらの座標は円周上を指定する必要はなく、円周に接する長さに自動で伸縮されます。
//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
POINT points[] = {
{ 60, 60 },
{ 40, 130 },
{ 60, 60 },
{ 130, 50 }
};
DWORD vertices[] = {
2, 2
};
int x, y;
switch (message)
{
case WM_PAINT: //ウィンドウの描画
hdc = BeginPaint(hWnd, &ps);
Rectangle(hdc, 10, 10, 110, 110);
Ellipse(hdc, 10, 10, 110, 110);
PolyPolyline(hdc, points, vertices, 2);
TextOut(hdc, points[1].x, points[1].y, L"線1", 2);
TextOut(hdc, points[3].x, points[3].y, L"線2", 2);
x = 0;
y = 170;
TextOut(hdc, 30, 10 + y, L"Pie", 3);
Pie(hdc, 10 + x, 10 + y, 110 + x, 110 + y,
40 + x, 130 + y, 130 + x, 50 + y);
x = 100;
y = 170;
TextOut(hdc, 30 + x, 10 + y, L"Arc", 3);
Arc(hdc, 10 + x, 10 + y, 110 + x, 110 + y,
40 + x, 130 + y, 130 + x, 50 + y);
x = 200;
y = 170;
TextOut(hdc, 30 + x, 10 + y, L"Chord", 5);
Chord(hdc, 10 + x, 10 + y, 110 + x, 110 + y,
40 + x, 130 + y, 130 + x, 50 + y);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY: //ウィンドウの破棄
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
この画像の上の図形は説明用に描画したものです。
反時計回りに、一本目の線と二本目の線の間が描画対象になっていることがわかります。