ペン
今までの図形の描画では、線はすべて黒の細い線で描画されていました。
線の色や種類は変更することができます。
ストックオブジェクト
図形の線はペンというオブジェクトによって描画されます。
ペンはストックオブジェクトにあらかじめ用意されています。
(→GetStockObject関数)
定数 | 説明 |
---|---|
WHITE_PEN | 白色のペン |
BLACK_PEN | 黒色のペン |
NULL_PEN | 透明ペン (何も描画しない) |
DC_PEN | 色を変更可能なペン |
初期状態ではBLACK_PEN
がデバイスコンテキストに設定されています。
SetDCPenColor関数
DC_PEN
はSetDCPenColor
関数で色を設定できます。
- COLORREF SetDCPenColor(
HDC hdc,
COLORREF color
); - DC_PENの色を設定する。
戻り値は設定した色。
失敗した場合はCLR_INVALIDを返す。
COLORREF型に関しては文字色と背景色の項を参照してください。
case WM_PAINT: //ウィンドウの描画
hdc = BeginPaint(hWnd, &ps);
SetDCPenColor(hdc, RGB(255, 0, 0));
SelectObject(hdc, GetStockObject(DC_PEN));
//何か描画
MoveToEx(hdc, 10, 10, NULL);
LineTo(hdc, 110, 110);
EndPaint(hWnd, &ps);
break;
GetDCPenColor関数
GetDCPenColor
関数はDC_PENに設定されている色を取得します。
- COLORREF GetDCPenColor(
HDC hdc,
); - DC_PENの色を取得する。
CreatePen関数
ストックオブジェクトのペンは種類が少ないので、詳細な設定を行う場合は自分でペンを定義します。
ペンの作成はCreatePen
関数で行います。
- HPEN CreatePen(
int iStyle,
int cWidth,
COLORREF color
); - 論理ペンを作成する。
第一引数iStyle
は、後述するペンのスタイルを示す定数を指定します。
第二引数cWidth
はペンの幅(太さ)です。
第三引数color
はペンの色です。
ペンのスタイル定数は以下のものを指定します。
定数 | 説明 |
---|---|
PS_SOLID | 実線 |
PS_DASH | 破線 ペン幅は1以下にする必要がある |
PS_DOT | 点線 ペン幅は1以下にする必要がある |
PS_DASHDOT | PS_DASH→PS_DOTの繰り返し ペン幅は1以下にする必要がある |
PS_DASHDOTDOT | PS_DASH→PS_DOT→PS_DOTの繰り返し ペン幅は1以下にする必要がある |
PS_NULL | 透明ペン(描画しない) |
PS_INSIDEFRAME | 実線 Rectangle関数などの「内側」を持つ図形で使用すると、内側からはみ出さないように描画される (図形は縮小される) |
CreatePen関数はHPEN型を返します。
これはGDIオブジェクトで、不要になったらDeleteObject関数で破棄する必要があります。
//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
HPEN pen;
HGDIOBJ hgdi;
switch (message)
{
case WM_PAINT: //ウィンドウの描画
hdc = BeginPaint(hWnd, &ps);
//実線、太さ3、赤
pen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));
hgdi = SelectObject(hdc, pen);
MoveToEx(hdc, 10, 10, NULL);
LineTo(hdc, 110, 10);
SelectObject(hdc, hgdi);
DeleteObject(pen);
//破線、太さ1、青
pen = CreatePen(PS_DASH, 1, RGB(0, 255, 0));
hgdi = SelectObject(hdc, pen);
MoveToEx(hdc, 10, 20, NULL);
LineTo(hdc, 110, 20);
SelectObject(hdc, hgdi);
DeleteObject(pen);
//点線、太さ1、緑
pen = CreatePen(PS_DOT, 1, RGB(0, 0, 255));
hgdi = SelectObject(hdc, pen);
MoveToEx(hdc, 10, 30, NULL);
LineTo(hdc, 110, 30);
SelectObject(hdc, hgdi);
DeleteObject(pen);
//PS_SOLID、太さ6、赤
pen = CreatePen(PS_SOLID, 6, RGB(255, 0, 0));
hgdi = SelectObject(hdc, pen);
Rectangle(hdc, 120, 10, 220, 60);
SelectObject(hdc, hgdi);
DeleteObject(pen);
//PS_INSIDEFRAME、太さ6、赤
pen = CreatePen(PS_INSIDEFRAME, 6, RGB(255, 0, 0));
hgdi = SelectObject(hdc, pen);
Rectangle(hdc, 120, 70, 220, 120);
SelectObject(hdc, hgdi);
DeleteObject(pen);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY: //ウィンドウの破棄
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
様々なペンで描画した結果です。
四角形の上側はPS_SOLID
、下側はPS_INSIDEFRAME
に設定しています。
サイズの指定は同じですが、PS_INSIDEFRAMEで描画した四角形は、PS_SOLIDで描画した四角形よりも少し小さくなっているのがわかると思います。
PS_SOLIDは枠線の左右にペンの太さを反映させるのに対し、PS_INSIDEFRAMEは領域からはみ出さないように、枠線の内側にペンの太さが反映させるためです。
なお、破線や点線は実際には線の色と背景色とが交互に描画されています。
(ウィンドウの背景色ではなく、デバイスコンテキストに設定されている背景色)
背景色の変更はSetBkColor
関数で行えます。
SetBkMode
関数でTRANSPARENT
(透明モード)に設定すると、線と線の間は描画されません。
(→背景色の変更)
CreatePenIndirect関数
ペンの作成はCreatePenIndirect
関数を使用することもできます。
引数の中身が違うだけで使い方は同じです。
- HPEN CreatePenIndirect(
const LOGPEN *plpen
); - 論理ペンを作成する。
LOGPEN
は構造体です。
- typedef struct tagLOGPEN {
UINT lopnStyle;
POINT lopnWidth;
COLORREF lopnColor;
} LOGPEN, *PLOGPEN, *NPLOGPEN, *LPLOGPEN; - 論理ペンの情報を格納する構造体。
CreatePen関数の引数をそのまま格納するのがLOGPEN構造体です。
ただし、線の太さを指定するlopnWidth
メンバの型がint型ではなくPOINT型になっています。
LOGPEN構造体では、POINT構造体のx
メンバのみを使用します。
y
メンバは使用されません。
HPEN hPen;
LOGPEN logPen;
logPen.lopnStyle = PS_SOLID;
logPen.lopnWidth.x = 3;
logPen.lopnColor = RGB(255, 0, 0);
hPen = CreatePenIndirect(&logPen);