第24章 四角形を描く


今回は、四角形の描画についてします。

BOOL Rectangle( HDC hdc, // デバイスコンテキストハンドル int nLeftRect, int nTopRect, int nRightRect, int nBottomRect );

これは、もう説明の必要はないですね。ただ気を付けなくてはいけないのは これで描画した四角形の内部は、現在のブラシで塗りつぶされるという点です。 四角形を2つ重ねて描画すると重なった部分は、後から描いた四角形の 内部を塗りつぶすブラシで消されてしまいます。

ところでブラシ関係については一部すでに出てきています。

エッ!?そんなの知らないよ!

実は、第2章

GetStockObject(WHITE_BRUSH);

というのが出てきています。しかし説明はしていませんでした。 第2章どころか、プログラムを作る度に出てきています。 これは、背景を塗りつぶすブラシを選択しているところです。 背景を塗りつぶすブラシは最初からいくつか用意されています。(ストックオブジェクト)

GetStockObjectとは、定義済みのペンとか、ブラシとか、フォントなどの ハンドルを取得する関数なのです。ストックオブジェクトはDeleteObjectしては いけません。

自分でペンやらブラシを作って四角形を描くには

hPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0)); SelectObject(hdc, hPen); hBrush = CreateHatchBrush(HS_CROSS, RGB(0, 255, 0)); SelectObject(hdc, hBrush); Rectangle(hdc, 10, 10, 200, 100);

とまあ、こんな感じです。 CreatePenで作ったペンで四角形の辺を描きます。 CreateHatchBrushで作ったブラシで四角形の内部を塗りつぶすことになります。 ペンもブラシも作ったらSelectObject関数で選択します。 そして、Rectangle関数で四角形を描きます。

四角形の内部を塗りつぶさない(下が透けて見える)ようにするにはどうするの?

はい。NULL_BRUSHというのを使います。 では、サンプルのプログラムを作ってみましょう。 ウィンドウの背景がいつもWHITE_BRUSHではつまらないので、 今回はちょっと変えてみました。プログラムを注意深く眺めてみて下さい。

// grph02.rc の一部 ///////////////////////////////////////////////////////////////////////////// // // Menu // GRPH MENU DISCARDABLE BEGIN MENUITEM "終了(&Q)", IDM_END END

メニューリソースです。これは、前回と全く同じです。

// grph02.cpp #include <windows.h> #include <windowsx.h> #include "resource.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); BOOL InitApp(HINSTANCE, LPCSTR); BOOL InitInstance(HINSTANCE, LPCSTR, int); int DrawGr(HDC); int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { MSG msg; char szClassName[] = "grph02"; if (!hPrevInst) { if (!InitApp(hCurInst, szClassName)) return FALSE; } if (!InitInstance(hCurInst, szClassName, nCmdShow)) { return FALSE; } while (GetMessage(&msg, NULL, NULL, NULL)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } BOOL InitApp(HINSTANCE hInst, LPCSTR szClassName) { WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = GetStockObject(GRAY_BRUSH); wc.lpszMenuName = "GRPH"; wc.lpszClassName = (LPCSTR)szClassName; return (RegisterClass(&wc)); } BOOL InitInstance(HINSTANCE hInst, LPCSTR szClassName, int nCmdShow) { HWND hWnd; hWnd = CreateWindow(szClassName, "猫でもわかるGRPH", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, NULL); if (!hWnd) return FALSE; ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { int id; HDC hdc; PAINTSTRUCT ps; switch (msg) { case WM_COMMAND: switch (GET_WM_COMMAND_ID(wp, lp)) { case IDM_END: SendMessage(hWnd, WM_CLOSE, 0, 0L); break; } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); DrawGr(hdc); EndPaint(hWnd, &ps); break; case WM_CLOSE: id = MessageBox(hWnd, (LPCTSTR)"終了しますか", (LPCTSTR)"終了確認", MB_OKCANCEL | MB_ICONQUESTION); if (id == IDOK) { DestroyWindow(hWnd); } if (id == IDCANCEL) { return FALSE; } break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0L; } // グラフィックス描画 int DrawGr(HDC hdc) { HPEN hPen, hOldPen; HBRUSH hBrush, hOldBrush; hPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0)); hOldPen = SelectObject(hdc, hPen); hBrush = CreateHatchBrush(HS_CROSS, RGB(0, 255, 0)); hOldBrush = SelectObject(hdc, hBrush); Rectangle(hdc, 10, 10, 200, 100); SelectObject(hdc, hOldPen); SelectObject(hdc, hOldBrush); DeleteObject(hPen); DeleteObject(hBrush); hPen = CreatePen(PS_DASH, 1, RGB(255, 100, 10)); hOldPen = SelectObject(hdc, hPen); hBrush = CreateHatchBrush(HS_BDIAGONAL, RGB(0, 0, 255)); hOldBrush = SelectObject(hdc, hBrush); Rectangle(hdc, 40, 40, 240, 140); SelectObject(hdc, hOldPen); SelectObject(hdc, hOldBrush); DeleteObject(hPen); DeleteObject(hBrush); hPen = CreatePen(PS_DOT, 1, RGB(100, 100, 100)); hOldPen = SelectObject(hdc, hPen); SelectObject(hdc, GetStockObject(NULL_BRUSH)); Rectangle(hdc, 70, 70, 270, 270); SelectObject(hdc, hOldPen); DeleteObject(hPen); hPen = CreatePen(PS_DASHDOTDOT, 1, RGB(0, 255, 0)); hOldPen = SelectObject(hdc, hPen); hBrush = CreateHatchBrush(HS_DIAGCROSS, RGB(255, 0, 255)); hOldBrush = SelectObject(hdc, hBrush); Rectangle(hdc, 100, 100, 200, 160); SelectObject(hdc, hOldPen); SelectObject(hdc, hOldBrush); DeleteObject(hPen); DeleteObject(hBrush); return 0; }


では、実行してみましょう。

ウィンドウの背景が白ではなくて灰色であることに注意して下さい。 また、点線で描かれた四角形は内部が透けている点にも 注意して下さい。

ハッチスタイルについては解説をしませんでしたが簡単に言うと

HS_BDIAGONAL・・・右上から左下への斜め線 HS_FDIAGONAL・・・左上から右下への斜め線 HS_CROSS・・・・・グラフ用紙状 HS_HORIZONTAL・・・横縞 HS_DIAGCROSS・・・・斜めの格子 HS_VERTICAL・・・・縦縞

と、言うことになります。

DIAGONALとは「対角線」という意味です。ちなみに「あやとり」 もdiagonalというらしいです。(プログラムとは関係ありません)


[SDK Index] [総合Index] [Previous Chapter] [Next Chapter]

Update Apr/25/1997 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。