ブラシ
四角形や円などは線で閉じられた「内側」の領域を持っています。
これらの図形は、線で外形を描画すると同時に内側は塗りつぶされています。
この塗りつぶすためのオブジェクトをブラシ(刷毛、はけ)といいます。
ブラシで内側が塗りつぶされるのはRectangle
関数、RoundRect
関数、Polygon
関数、PolyPolygon
関数、Ellipse
関数、Pie
関数、Chord
関数などです。
(→図形の描画2)
LineTo
関数などの線描画関数で三角形などを描画しても塗りつぶしは行われません。
ストックオブジェクト
ペン同様、ブラシにもストックオブジェクト
が用意されています。
(→GetStockObject関数)
定数 | 説明 |
---|---|
WHITE_BRUSH | 白色のブラシ |
LTGRAY_BRUSH | 明るい灰色のブラシ |
GRAY_BRUSH | 灰色のブラシ |
DKGRAY_BRUSH | 暗い灰色のブラシ |
BLACK_BRUSH | 黒色のブラシ |
NULL_BRUSH | 透明ブラシ (何も描画しない) |
HOLLOW_BRUSH | NULL_BRUSHと同じ |
DC_BRUSH | 色を変更可能なブラシ |
色の種類が少し増えましたが、使い方はペンの時と同じです。
初期状態ではWHITE_BRUSH
が設定されています。
SetDCBrushColor関数
DC_BRUSH
はSetDCBrushColor
関数で任意の色に変更できます。
- COLORREF SetDCBrushColor(
HDC hdc,
COLORREF color
); - DC_BRUSHの色を設定する。
戻り値は設定した色。
失敗した場合はCLR_INVALIDを返す。
COLORREF型に関しては→文字色と背景色を参照してください。
GetDCBrushColor関数
ペンと同様、現在のブラシの色を取得するGetDCBrushColor
関数もあります。
- COLORREF GetDCBrushColor(
HDC hdc,
); - DC_BRUSHの色を取得する。
サンプルコード
//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
switch (message)
{
case WM_PAINT: //ウィンドウの描画
hdc = BeginPaint(hWnd, &ps);
//明るい灰色ブラシ
SelectObject(hdc, GetStockObject(LTGRAY_BRUSH));
Rectangle(hdc, 10, 10, 110, 60);
//透明ペン、明るい灰色ブラシ
SelectObject(hdc, GetStockObject(NULL_PEN));
Rectangle(hdc, 10, 70, 110, 120);
//黒ペン、白ブラシ(初期状態)
SelectObject(hdc, GetStockObject(BLACK_PEN));
SelectObject(hdc, GetStockObject(WHITE_BRUSH));
MoveToEx(hdc, 5, 155, NULL);
LineTo(hdc, 115, 155);
Rectangle(hdc, 10, 130, 110, 180);
//黒ペン、透明ブラシ
SelectObject(hdc, GetStockObject(NULL_BRUSH));
MoveToEx(hdc, 5, 215, NULL);
LineTo(hdc, 115, 215);
Rectangle(hdc, 10, 190, 110, 240);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY: //ウィンドウの破棄
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
このコードの実行結果です。
最初の四角形は灰色のブラシで描画しています。
二番目の四角形は透明ペンを設定しています。
透明ペンは描画されないので、輪郭線のない四角形が描画されます。
三番目はペンとブラシを初期設定に戻し、横線を引いた上に四角形を描画しています。
線は上書きされ、途切れてしまっています。
四番目は三番目と同じ手順で描画していますが、ブラシを透明ブラシにしています。
内側は塗りつぶされないため、線は上書きされません。
ブラシの作成
ペン同様、ブラシも自分で作成することができます。
ブラシは単色での塗りつぶしのほか、模様や画像などで塗りつぶすこともできます。
そのための関数もいくつか用意されています。
ここでは単色と模様を使用した塗りつぶしを紹介します。
なお、作成したブラシは不要になったらDeleteObject関数で破棄する必要があります。
CreateSolidBrush関数
CreateSolidBrush
関数は単色のブラシを作成します。
- HBRUSH CreateSolidBrush(
COLORREF color
); - color色の単色の論理ブラシを作成する。
この関数は難しいことはないでしょう。
戻り値はHBRUSH型です。
CreateHatchBrush関数
CreateHatchBrush
関数はハッチ模様のブラシを作成します。
- HBRUSH CreateHatchBrush(
int iHatch,
COLORREF color
); - color色のハッチ模様の論理ブラシを作成する。
ハッチ模様とは平行な線で面を埋めた模様です。
第一引数iHatch
は以下の定数を指定します。
定数 | 説明 |
---|---|
HS_HORIZONTAL | 水平 |
HS_VERTICAL | 垂直 |
HS_FDIAGONAL | 右下がり |
HS_BDIAGONAL | 右上がり |
HS_CROSS | 水平交差 |
HS_DIAGCROSS | 斜め交差 |
第二引数color
は平行線の色です。
線と線の間はデバイスコンテキストの背景色で塗りつぶされます。
背景色を変更するにはSetBkColor
関数を、背景色を透明にするにはSetBkMode
関数を使用します。
(→背景色の変更)
//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
HBRUSH brush;
HGDIOBJ hgdi;
int x, y;
switch (message)
{
case WM_PAINT: //ウィンドウの描画
hdc = BeginPaint(hWnd, &ps);
x = y = 10;
//水平
brush = CreateHatchBrush(HS_HORIZONTAL, RGB(255, 0, 0));
hgdi = SelectObject(hdc, brush);
Rectangle(hdc, x, y, x + 60, y + 60);
SelectObject(hdc, hgdi);
DeleteObject(brush);
x = y += 30;
//垂直
brush = CreateHatchBrush(HS_VERTICAL, RGB(0, 255, 0));
hgdi = SelectObject(hdc, brush);
Rectangle(hdc, x, y, x + 60, y + 60);
SelectObject(hdc, hgdi);
DeleteObject(brush);
x = y += 30;
//右下がり
brush = CreateHatchBrush(HS_FDIAGONAL, RGB(0, 0, 255));
hgdi = SelectObject(hdc, brush);
Rectangle(hdc, x, y, x + 60, y + 60);
SelectObject(hdc, hgdi);
DeleteObject(brush);
//ここから背景色を透明に変更
SetBkMode(hdc, TRANSPARENT);
x = y += 30;
//右上がり
brush = CreateHatchBrush(HS_BDIAGONAL, RGB(0, 0, 0));
hgdi = SelectObject(hdc, brush);
Rectangle(hdc, x, y, x + 60, y + 60);
SelectObject(hdc, hgdi);
DeleteObject(brush);
x = y += 30;
//水平交差
brush = CreateHatchBrush(HS_CROSS, RGB(0, 255, 255));
hgdi = SelectObject(hdc, brush);
Rectangle(hdc, x, y, x + 60, y + 60);
SelectObject(hdc, hgdi);
DeleteObject(brush);
x = y += 30;
//斜め交差
brush = CreateHatchBrush(HS_DIAGCROSS, RGB(255, 0, 255));
hgdi = SelectObject(hdc, brush);
Rectangle(hdc, x, y, x + 60, y + 60);
SelectObject(hdc, hgdi);
DeleteObject(brush);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY: //ウィンドウの破棄
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
上で説明した順番でブラシを作成し四角形を描画するサンプルコードです。
後半の三つは背景色を透明にしています。
多角形の塗りつぶしモード
Polygon
関数やPolyPolygon
関数は多角形を描画しますが、初期設定では重なり合った面の塗りつぶしは行われません。
重なり合った面も塗りつぶしたい場合はSetPolyFillMode
関数で多角形の塗りつぶしモードを変更します。
- int SetPolyFillMode(
HDC hdc,
int mode
); - 多角形塗りつぶしモードを変更する。
戻り値は変更前の塗りつぶしモード。
失敗した場合は0を返す。
塗りつぶしモードは以下の定数を指定します。
定数 | 説明 |
---|---|
ALTERNATE | 交互モード。 (重なり合った面は塗りつぶさない) |
WINDING | 全域モード。 (重なり合った面も塗りつぶす) |
初期状態ではALTERNATE
が選択されています。
//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
HBRUSH brush;
POINT points1[] = {
{10, 30},
{110, 30},
{110, 90},
{10, 90},
{60, 10},
{90, 120},
{30, 120}
};
POINT points2[] = {
{10 + 110, 30},
{110 + 110, 30},
{110 + 110, 90},
{10 + 110, 90},
{60 + 110, 10},
{90 + 110, 120},
{30 + 110, 120}
};
DWORD vertices[] = {
4, 3
};
switch (message)
{
case WM_PAINT: //ウィンドウの描画
hdc = BeginPaint(hWnd, &ps);
brush = CreateSolidBrush(RGB(255, 0, 0));
SelectObject(hdc, brush);
PolyPolygon(hdc, points1, vertices, 2);
//全域モードに切り替える
SetPolyFillMode(hdc, WINDING);
PolyPolygon(hdc, points2, vertices, 2);
EndPaint(hWnd, &ps);
DeleteObject(brush);
break;
case WM_DESTROY: //ウィンドウの破棄
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
左がALTERNATE
モード、右がWINDING
モードです。