レガシー Windows API(概要)について

ここで紹介しているAPIは、Windows95、Windows NT3.5時代のAPI群であり、最新のAPIは含まれていないことに注しして欲しい。なお、当時の解説書は現在よりもより詳細に解説しているため、参考になるはずである。

  • レイアウトを変換する際、崩れているページがあります。
  • 概要およびSampleコードはありますが、APIの解説はありません。

ご要望があれば旧版のWin32 API(HELP形式)をお譲りします。問い合わせフォームより申し込みください。

Windows API 塗りつぶされた図形の概要

塗りつぶされた図形とは、 現在のペンで境界線を描画し、 現在のブラシで塗りつぶされた図形のことです。塗りつぶされた図形には、 だ円、 弓形、 扇形、 多角形、 長方形の5種類があります。Microsoft(R) Windows(TM) 用のアプリケーションでは、 塗りつぶされた図形をさまざまな方法で使うことができます。たとえば、 表計算アプリケーションでは、 塗りつぶされた図形を使って図やグラフを生成できます。また、 描画アプリケーションでは、 ユーザーは塗りつぶされた図形を使って絵やイラストを描画できます。

次に示すトピックでは、 塗りつぶされた図形について説明しています。

だ円

弓形

扇形

多角形

長方形

塗りつぶされた図形の使用

塗りつぶされた図形の関数

 

 

だ円

「だ円」とは、 2つの固定点 (f1f2) からの距離の和(d1 + d2)が一定である点の軌跡である閉曲線です。次の図は、 Ellipse関数を使って描画しただ円を示しています。

Ellipse関数を呼び出すときは、 だ円の境界長方形の左上隅と右下隅の座標を指定します。「境界長方形」とは、 だ円を完全に含む最小の長方形です。ワールド座標変換が設定されていなければ、 Windowsは、 だ円を描画するとき、 右と下の辺を除外します。このため、 幅がxで高さがyの長方形に対応するだ円の大きさは、 幅x-1、 高さy-1になります。アプリケーションがSetWorldTransform関数やModifyWorldTransform関数を呼び出してワールド座標変換を設定していれば、 Windowsは、 右と下の辺も含めます。

 

 

 

弓形

「弓形」とは、 弦と呼ばれる線分とだ円との交差で囲まれる領域です。次の図は、 Chord関数で描画した弓形を示しています。

Chord関数を呼び出すときは、 だ円の境界長方形の左上隅と右下隅の座標、 および2つの半径を定義する2点の座標を指定します。「半径」とは、 だ円の境界長方形の中心からだ円上の点に引かれる直線です。

Windowsは、 弓形の曲線部分を描画するとき、 指定されているデバイス コンテキストの現在の弧の方向を使います。デフォルトの弧の方向は、 反時計回りです。弧の方向をリセットするには、 SetArcDirection関数を呼び出してください。

 

 

扇形

「扇形」とは、 だ円と2つの半径の交差で囲まれる領域です。次の図は、 Pie関数を使って描画した扇形を示しています。

Pie関数を呼び出すときは、 だ円の境界長方形の左上隅と右下隅の座標、 および2つの半径を定義する2点の座標を指定します。

Windowsは、 扇形の曲線部分を描画するとき、 指定されているデバイス コンテキストの現在の弧の方向を使います。デフォルトの弧の方向は、 反時計回りです。弧の方向をリセットするには、 SetArcDirection関数を呼び出してください。

 

 

多角形

「多角形」とは、 直線の辺で構成された、 塗りつぶされた図形のことです。多角形の各辺は、 現在のペンで描画されます。Windowsは、 多角形を塗りつぶすとき、 現在のブラシと現在の多角形塗りつぶしモードを使います。交互モード (デフォルト) と全域モードの2つの塗りつぶしモードによって、 複雑な多角形の各領域を塗りつぶすかどうかが決まります。塗りつぶしモードを設定するには、 SetPolyFillMode関数を呼び出してください。多角形の塗りつぶしモードについて詳しくは、 リージョンの概要を参照してください。

次の図は、 Polygon関数を使って描画した多角形を示しています。

Polygon関数は多角形を1つだけ描画しますが、 PolyPolygon関数を使って複数の多角形を描画することもできます。

 

 

長方形

長方形とは、 対辺が平行で長さが等しい、 4辺の多角形です。長方形はPolygon関数に各頂点の座標を指定して描画することもできますが、 Windowsには、 より簡単な方法であるRectangle関数が用意されています。この関数に必要なのは、 左上隅と右下隅の座標だけです。アプリケーションがRectangle関数を呼び出すと、 Windowsは長方形を描画しますが、 デバイス コンテキストにワールド座標変換が設定されていなければ、 右と下の辺は除外します。

SetWorldTransform関数やModifyWorldTransform関数でワールド座標変換が設定されているときは、 Windowsは右と下の辺を含めます。

Win32アプリケーション プログラミング インターフェイス (API) では、 通常の長方形の描画のほかに、 角が丸い長方形を描画するための関数も用意しています。このRoundRectには、 左上隅と右下隅の座標のほかに、 角の丸みに使われるだ円の幅と高さを指定します。

また、 次の表に示すように、 Win32 APIには、 長方形を操作するための関数が3つ用意されています。

 

関数 説明

FillRect 長方形の内部を再描画します。

FrameRect 長方形の辺を再描画します。

InvertRect 長方形の内部の色を反転します。

 

 

 

 

塗りつぶされた図形の使用

ここでは、 塗りつぶされた図形用の関数の使い方の例を示します。この例では、 だ円や長方形、 角の丸い長方形をユーザーが描画できるようにするアプリケーションのメイン ウィンドウ プロシージャを使っています。

ユーザーは、 メニューから特定の図形を選択し、 図形 (だ円の場合は境界長方形) の左上隅にカーソルを置き、 必要な寸法までドラッグすることによって、 塗りつぶされた図形を描画できます。

次の図は、 このコードを使って描画した、 3つの塗りつぶされた図形を示しています。

ユーザーが塗りつぶされた図形を描画できるようにするには、 次に示すコードを使ってください。

 

LRESULT APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam)
HWND hwnd; /* handle of window */
UINT uMsg; /* message */
WPARAM wParam; /* first message parameter */
LPARAM lParam; /* second message parameter */
{
HDC hdc; /* handle of device context (DC) */
PAINTSTRUCT ps; /* paint data for Begin/EndPaint */
POINT ptClientUL; /* client area upper-left corner */
POINT ptClientLR; /* client area lower-right corner */
static HDC hdcCompat; /* handle of DC for copying bitmap */
static POINT pt; /* x- and y-coordinates of cursor */
static RECT rcTarget; /* rectangle to receive filled shape */
static RECT rcClient; /* client area rectangle */
static BOOL fSizeEllipse; /* TRUE if ellipse is being sized */
static BOOL fDrawEllipse; /* TRUE if ellipse is being drawn */
static BOOL fDrawRectangle; /* TRUE if rectangle is being drawn */
static BOOL fSizeRectangle; /* TRUE if rectangle is being sized */
static BOOL fSizeRoundRect; /* TRUE if rounded rect. is being sized */
static BOOL fDrawRoundRect; /* TRUE if rounded rect. is being drawn */
static int nEllipseWidth; /* ellipse width for round corners */
static int nEllipseHeight; /* ellipse height for round corners */

switch (uMsg) {

case WM_COMMAND:
switch (wParam) {

/*
* Set the appropriate flag to indicate which
* filled shape the user is drawing.
*/

case IDM_ELLIPSE:
fSizeEllipse = TRUE;
break;

case IDM_RECTANGLE:
fSizeRectangle = TRUE;
break;

case IDM_ROUNDRECT:
fSizeRoundRect = TRUE;
break;

default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
break;


case WM_CREATE:

nEllipseWidth = 20;
nEllipseHeight = 20;

return 0;

case WM_PAINT:


BeginPaint(hwnd, &ps);

/*
* Because the default brush is white, select
* a different brush into the device context
* to demonstrate the painting of filled shapes.
*/

SelectObject(ps.hdc, GetStockObject(GRAY_BRUSH));

/*
* If one of the filled shape "draw" flags is TRUE,
* draw the corresponding shape.
*/

if (fDrawEllipse) { /* draws ellipse */
Ellipse(ps.hdc, rcTarget.left, rcTarget.top,
rcTarget.right, rcTarget.bottom);
fDrawEllipse = FALSE;
rcTarget.left = rcTarget.right = 0;
rcTarget.top = rcTarget.bottom = 0;
}

if (fDrawRectangle) { /* Draws rectangle */
Rectangle(ps.hdc, rcTarget.left, rcTarget.top,
rcTarget.right, rcTarget.bottom);
fDrawRectangle = FALSE;
rcTarget.left = rcTarget.right = 0;
rcTarget.top = rcTarget.bottom = 0;
}

if (fDrawRoundRect) { /* Draws rounded rectangle */
RoundRect(ps.hdc, rcTarget.left, rcTarget.top,
rcTarget.right, rcTarget.bottom,
nEllipseWidth, nEllipseHeight);
fDrawRectangle = FALSE;
rcTarget.left = rcTarget.right = 0;
rcTarget.top = rcTarget.bottom = 0;
}

EndPaint(hwnd, &ps);
break;

case WM_SIZE:

/*
* Convert the client coordinates of the client area
* rectangle to screen coordinates and save them in a
* rectangle. The rectangle is passed to the ClipCursor
* function during WM_LBUTTONDOWN processing.
*/

GetClientRect(hwnd, &rcClient);
ptClientUL.x = rcClient.left;
ptClientUL.y = rcClient.top;
ptClientLR.x = rcClient.right;
ptClientLR.y = rcClient.bottom;
ClientToScreen(hwnd, &ptClientUL);
ClientToScreen(hwnd, &ptClientLR);
SetRect(&rcClient, ptClientUL.x, ptClientUL.y,
ptClientLR.x, ptClientLR.y);
return 0;

case WM_LBUTTONDOWN:

/*
* Restrict the cursor to the client area.
* This ensures that the window receives a matching
* WM_LBUTTONUP message.
*/

ClipCursor(&rcClient);

/* Save the coordinates of the cursor. */

pt.x = (LONG) LOWORD(lParam);
pt.y = (LONG) HIWORD(lParam);

/*
* If the user chooses one of the filled shapes,
* set the appropriate flag to indicate that the
* shape is being sized.
*/

if (fDrawEllipse)
fSizeEllipse = TRUE;

return 0;

case WM_MOUSEMOVE:

/*
*
* If one of the "size" flags is set, draw
* the target rectangle as the user drags
* the mouse.
*/

if ((wParam && MK_LBUTTON)
&& (fSizeEllipse || fSizeRectangle
|| fSizeRoundRect)) { /* draws target rect. */

/*
* Set the mixing mode so that the pen color is the
* inverse of the background color. The previous
* rectangle can then be erased by drawing
* another rectangle on top of it.
*/

hdc = GetDC(hwnd);
SetROP2(hdc, R2_NOTXORPEN);

/*
* If a previous target rectangle exists, erase
* it by drawing another rectangle on top.
*/

if (!IsRectEmpty(&rcTarget))
Rectangle(hdc, rcTarget.left, rcTarget.top,
rcTarget.right, rcTarget.bottom);

/*
* Save the coordinates of the target rectangle.
* Avoid invalid rectangles by ensuring that the
* value of the left coordinate is greater than
* that of the right, and that the value of the
* bottom coordinate is greater than that of
* the top.
*/

if ((pt.x < (LONG) LOWORD(lParam)) &&
(pt.y > (LONG) HIWORD(lParam)))
SetRect(&rcTarget, pt.x, HIWORD(lParam),
LOWORD(lParam), pt.y);

else if ((pt.x > (LONG) LOWORD(lParam)) &&
(pt.y > (LONG) HIWORD(lParam)))
SetRect(&rcTarget, LOWORD(lParam),
HIWORD(lParam), pt.x, pt.y);

else if ((pt.x > (LONG) LOWORD(lParam)) &&
(pt.y < (LONG) HIWORD(lParam)))
SetRect(&rcTarget, LOWORD(lParam), pt.y,
pt.x, HIWORD(lParam));
else
SetRect(&rcTarget, pt.x, pt.y, LOWORD(lParam),
HIWORD(lParam));

/* Draw the new target rectangle. */

Rectangle(hdc, rcTarget.left, rcTarget.top,
rcTarget.right, rcTarget.bottom);
ReleaseDC(hwnd, hdc);
}
return 0;

case WM_LBUTTONUP:

/*
* If one of the "size" flags is TRUE, reset
* it to FALSE, and then set the corresponding "draw" flag.
* Invalidate the appropriate rectangle and issue
* a WM_PAINT message.
*/

if (fSizeEllipse) {
fSizeEllipse = FALSE;
fDrawEllipse = TRUE;
}

if (fSizeRectangle) {
fSizeRectangle = FALSE;
fDrawRectangle = TRUE;
}

if (fSizeRoundRect) {
fSizeRoundRect = FALSE;
fDrawRoundRect = TRUE;
}

if (fDrawEllipse || fDrawRectangle || fDrawRoundRect) {
InvalidateRect(hwnd, &rcTarget, TRUE);
UpdateWindow(hwnd);
}

/* Release the cursor. */

ClipCursor((LPRECT) NULL);
return 0;

case WM_DESTROY:

/*
* Destroy the background brush, compatible bitmap,
* and bitmap.
*/

DeleteDC(hdcCompat);
PostQuitMessage(0);
break;

default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return (LRESULT) NULL;
}

 

 

塗りつぶされた図形の関数

塗りつぶされた図形に関する関数を次に示します。

Chord

Ellipse

FillRect

FrameRect

InvertRect

Pie

Polygon

PolyPolygon

Rectangle

RoundRect

▲ページトップに戻る

【本を読んでもよくらからない】 … 個別指導でわかりやすくお教えします