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

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

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

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

Windows API 長方形の概要

Microsoft(R) Windows(TM) 用アプリケーションは、 長方形を使って、 画面やウィンドウの長方形領域を指定できます。長方形は、 カーソル クリッピング リージョン、 クライアント領域の無効部分、 書式化テキストの表示領域、 スクロール領域などに使われます。また、 アプリケーションは、 長方形を使って、 クライアント領域の一部を特定のブラシで塗りつぶしたり、 ウィンドウやそのクライアント領域の座標を取得できます。

次に示すトピックでは、 Win32の長方形について説明しています。

  • 長方形の座標
  • 長方形の操作
  • 長方形の使用
  • 長方形関数

 

長方形の座標

長方形を定義するには、 RECT構造体を使ってください。この構造体は、 長方形の2点 (左上隅と右下隅) の座標を示します。長方形の各辺はこの2点のどちらかを通り、 x軸かy軸に平行です。

長方形の座標の値は、 符号付き整数で表現します。長方形の右辺の座標値は、 左辺の座標値よりも大きくなければなりません。同様に、 下辺の座標値は上辺の座標値よりも大きくなければなりません。

アプリケーションは長方形をさまざまな用途に使えるため、 Windowsの長方形関数では、 計測単位をとくに決めていません。長方形の座標と寸法は、 すべて、 符号付きの論理値で指定します。計測の単位は、 長方形を使うときのマッピング モードと関数によって決まります。座標とマッピング モードについて、 詳しくは座標空間および座標変換の概要を参照してください。

 

長方形の操作

Microsoft(R) Win32(TM) アプリケーション プログラミング インターフェイス (API) は、 長方形を操作する関数をいくつか用意しています。

SetRect関数は長方形を作成します。CopyRect関数は、 指定された長方形をコピーします。また、 SetRectEmpty関数は、 空の長方形を作成します。空の長方形とは、 幅や高さのいずれかまたは両方が0の長方形です。IsRectEmpty関数は、 指定された長方形が空かどうか判断します。EqualRect関数は、 2つの長方形が同等 (座標が同じ) かどうか判断します。

InflateRect関数は、 長方形の幅や高さを増減します。この関数は、 長方形の左右の幅を増減したり、 上下の高さを増減します。

OffsetRect関数は、 長方形を指定された量だけ移動します。この関数は、 指定されたx移動量やy移動量を頂点の座標に追加することによって、 長方形を移動します。

PtInRect関数は、 指定された点が指定された長方形内にあるか調べます。点が左辺か上辺の上にあるか、 完全に長方形内にあれば、 点は長方形内にあります。点が右辺や下辺にあるときは、 点は長方形内にはありません。

IntersectRect関数は、 次の図のように、 2つの長方形の交差部分である新しい長方形を作成します。

UnionRect関数は、 次の図のように、 2つの長方形の結合部分である新しい長方形を作成します。

だ円や多角形を描画する関数について、 詳しくは、 塗りつぶされた図形の概要を参照してください。

 

 

長方形の使用

ここの例では、 長方形関数の使い方を示します。このコード例は、 ユーザーがビットマップを移動したりサイズ変更できるアプリケーションのメイン ウィンドウ プロシージャです。

アプリケーションは、 起動すると、 画面の左上隅に32x32ピクセルのビットマップを描画します。ユーザーは、 ビットマップをドラッグして移動できます。また、 ビットマップをサイズ変更するには、 マウスをドラッグしてターゲット長方形を作成してから、 ビットマップをドラッグしてそのターゲット長方形に「ドロップ」します。すると、 アプリケーションは、 ビットマップをターゲット長方形にコピーします。

ユーザーがビットマップを移動したりサイズ変更できるようにするウィンドウ プロシージャを次に示します。

 

LRESULT CALLBACK 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; /* device context (DC) for window */
RECT rcTmp; /* temporary rectangle */
PAINTSTRUCT ps; /* paint data for Begin/EndPaint */
POINT ptClientUL; /* client area upper left corner */
POINT ptClientLR; /* client area lower right corner */
static HDC hdcCompat; /* DC for copying bitmap */
static POINT pt; /* x and y coordinates of cursor */
static RECT rcBmp; /* rectangle that encloses bitmap */
static RECT rcTarget; /* rectangle to receive bitmap */
static RECT rcClient; /* client-area rectangle */
static BOOL fDragRect; /* TRUE if bitmap rect. is dragged */
static HBITMAP hbmp; /* handle of bitmap to display */
static HBRUSH hbrBkgnd; /* handle of background-color brush */
static COLORREF crBkgnd; /* color of client-area background */
static HPEN hpenDot; /* handle of dotted pen */

switch (uMsg) {
case WM_CREATE:

/* Load the bitmap resource. */

hbmp = LoadBitmap(hinst, MAKEINTRESOURCE(1));

/*
* Create a device context (DC) to hold the bitmap.
* The bitmap is copied from this DC to the window's DC
* whenever it must be drawn.
*/

hdc = GetDC(hwnd);
hdcCompat = CreateCompatibleDC(hdc);
SelectObject(hdcCompat, hbmp);

/*
* Create a brush of the same color as the background
* of the client area. The brush is used later to erase
* the old bitmap before copying the bitmap into the
* target rectangle.
*/

crBkgnd = GetBkColor(hdc);
hbrBkgnd = CreateSolidBrush(crBkgnd);
ReleaseDC(hwnd, hdc);

/*
* Create a dotted pen. The pen is used to draw the
* bitmap rectangle as the user drags it.
*/

hpenDot = CreatePen(PS_DOT, 1, RGB(0, 0, 0));

/*
* Set the initial rectangle for the bitmap. Note that
* this application supports only a 32- by 32-pixel
* bitmap. The rectangle is slightly larger than the
* bitmap.
*/

SetRect(&rcBmp, 1, 1, 34, 34);
return 0;

case WM_PAINT:

/*
* Draw the bitmap rectangle and copy the bitmap into
* it. The 32-pixel by 32-pixel bitmap is centered
* in the rectangle by adding 1 to the left and top
* coordinates of the bitmap rectangle, and subtracting
* 2 from the right and bottom coordinates.
*/

BeginPaint(hwnd, &ps);
Rectangle(ps.hdc, rcBmp.left, rcBmp.top,
rcBmp.right, rcBmp.bottom);
StretchBlt(ps.hdc, rcBmp.left + 1, rcBmp.top + 1,
(rcBmp.right - rcBmp.left) - 2,
(rcBmp.bottom - rcBmp.top) - 2, hdcCompat,
0, 0, 32, 32, SRCCOPY);
EndPaint(hwnd, &ps);
break;

case WM_MOVE:
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 mouse cursor to the client area. This
* ensures that the window receives a matching
* WM_LBUTTONUP message.
*/

ClipCursor(&rcClient);

/* Save the coordinates of the mouse cursor. */

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

/*
* If the user has clicked the bitmap rectangle, redraw
* it using the dotted pen. Set the fDragRect flag to
* indicate that the user is about to drag the
* rectangle.
*/

if (PtInRect(&rcBmp, pt)) {
hdc = GetDC(hwnd);
SelectObject(hdc, hpenDot);
Rectangle(hdc, rcBmp.left, rcBmp.top, rcBmp.right,
rcBmp.bottom);
fDragRect = TRUE;
ReleaseDC(hwnd, hdc);
}
return 0;

case WM_MOUSEMOVE:

/*
* Draw a target rectangle or drag the bitmap
* rectangle, depending on the status of the fDragRect
* flag.
*/

if ((wParam && MK_LBUTTON)
&& !fDragRect) { /* draw a target rectangle */

/*
* Set the mix 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 of it.
*/

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 coordinate, 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);
}
else if ((wParam && MK_LBUTTON)
&& fDragRect) { /* drag the bitmap rectangle */

/*
* Set the mix mode so that the pen color is the
* inverse of the background color.
*/

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

/*
* Select the dotted pen into the DC and erase
* the previous bitmap rectangle by drawing
* another rectangle on top of it.
*/

SelectObject(hdc, hpenDot);
Rectangle(hdc, rcBmp.left, rcBmp.top,
rcBmp.right, rcBmp.bottom);

/*
* Set the new coordinates of the bitmap
* rectangle, then redraw it.
*/

OffsetRect(&rcBmp, LOWORD(lParam) - pt.x,
HIWORD(lParam) - pt.y);
Rectangle(hdc, rcBmp.left, rcBmp.top,
rcBmp.right, rcBmp.bottom);
ReleaseDC(hwnd, hdc);

/* Save the coordinates of the mouse cursor. */

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

case WM_LBUTTONUP:

/*
* If the bitmap rectangle and target rectangle
* intersect, copy the bitmap into the target
* rectangle. Otherwise, copy the bitmap into the
* rectangle bitmap at its new location.
*/

if (IntersectRect(&rcTmp, &rcBmp, &rcTarget)) {

/*
* Erase the bitmap rectangle by filling it with
* the background color.
*/

hdc = GetDC(hwnd);
FillRect(hdc, &rcBmp, hbrBkgnd);

/*
* Redraw the target rectangle because the part
* that intersected with the bitmap rectangle was
* erased by the call to FillRect.
*/

Rectangle(hdc, rcTarget.left, rcTarget.top,
rcTarget.right, rcTarget.bottom);

/* Copy the bitmap into the target rectangle. */

StretchBlt(hdc, rcTarget.left + 1, rcTarget.top + 1,
(rcTarget.right - rcTarget.left) - 2,
(rcTarget.bottom - rcTarget.top) - 2, hdcCompat,
0, 0, 32, 32, SRCCOPY);

/*
* Copy the target rectangle to the bitmap
* rectangle, set the coordinates of the target
* rectangle to 0, then reset the fDragRect flag.
*/

CopyRect(&rcBmp, &rcTarget);
SetRectEmpty(&rcTarget);
ReleaseDC(hwnd, hdc);
fDragRect = FALSE;
}

else if (fDragRect) {

/*
* Draw the bitmap rectangle, copy the bitmap into
* it, and reset the fDragRect flag.
*/

hdc = GetDC(hwnd);
Rectangle(hdc, rcBmp.left, rcBmp.top,
rcBmp.right, rcBmp.bottom);
StretchBlt(hdc, rcBmp.left + 1, rcBmp.top + 1,
(rcBmp.right - rcBmp.left) - 2,
(rcBmp.bottom - rcBmp.top) - 2, hdcCompat,
0, 0, 32, 32, SRCCOPY);
ReleaseDC(hwnd, hdc);
fDragRect = FALSE;
}

/* Release the mouse cursor. */

ClipCursor((LPRECT) NULL);
return 0;

case WM_DESTROY:

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

DeleteObject(hbrBkgnd);
DeleteDC(hdcCompat);
DeleteObject(hbmp);
PostQuitMessage(0);
break;

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

 

長方形関数

長方形に関する関数を次に示します。

  • CopyRect
  • EqualRect
  • InflateRect
  • IntersectRect
  • IsRectEmpty
  • OffsetRect
  • PtInRect
  • SetRect
  • SetRectEmpty
  • UnionRect

 

▲ページトップに戻る

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