お絵かき
GDI
今回はウインドウに、図形を描きます。
GDI(Graphic Device Interface)というのを使います。意訳するとお絵かき道具セットという意味です。
まず、ウインドウを作ってください。今回はコントロールは何も付けません。何も無いウインドウに絵を描きます。
お絵かきをするには画用紙が必要です。GDIではデバイスコンテキスト(以下DC)といいます。
ウインドウのDC(=画用紙)を取得しないことにはお絵かきができません。
GetDC関数を使います。
HDCはDCのハンドルです。ウインドウハンドルと同じハンドルです。HDCはデバイスコンテキストの識別番号です。
つぎに、ペンが必要です。CreatePen関数で作ることができます。戻り値はHPEN、つまりペンのハンドル=識別番号です。
塗りつぶしにはブラシが必要です。CriateSolidBrush関数で作ります。戻り値はHBRUSHです。ハンドルです。
色ですがRGB関数を使います。RGB(赤 ,緑 ,青)で、色を指定します。
道具を作ったら、手に持ちます。SelectObject関数です。
重要なことをいいます。使った物は必ず返さなければなりません。
DeleteObject関数でCreate○○で作ったものを、ReleaseDCでGetDCで取得したものをWindowsに返します。
次に、描写方法です。
ヘルプにいっぱいあるので、全部説明しません。
| |
SetPixel(hDC ,x座標 ,y座標 , 色) | 点を打つ |
MoveToEx(HDC ,x ,y , 以前の位置) | カレントポジション変更 |
LineTo(HDC , x , y) | カレントポジションから線を引く |
Rectangle(HDC , x左上 ,y左上 ,x右下 , y右下) | 四角形を描く+塗りつぶし |
とりあえず、以上の関数でお絵かきはできそうです。問題は、いつ描写するかです。
答えをいうと、タイミングを教えてくれるメッセージが届きます。WM_PAINTです。
WM_PAINTはウインドウの再描写が必要だと教えてくれるメッセージです。
つまりWM_PAINTを受け取ったら、描写処理を実行すればいいのです。
実際にやる
今回は、何も無い(コントロール無しの)ウインドウを作ります。
次に、ウインドウ上で右クリック→イベントコード(C)でWM_PAINTのところをクリックして、コーディングボタンを押します。

Sub MainWnd_Paint(hDC As HDC)
End Sub
こんなコードが作られるので、以下のようにします。
Sub MainWnd_Paint(hDC As HDC)
'すいません。GetDCは必要ないです。引数がHDCでした…
Dim hPen As HPEN
Dim hBrush As HBRUSH
'道具を作ります
hPen = CreatePen(PS_SOLID , 1 , RGB(255 , 0 , 0))
hBrush = CreateSolidBrush(RGB(0 , 255 , 0))
'手に持ちます
SelectObject(hDC , hPen)
SelectObject(hDC , hBrush)
'お絵かき
MoveToEx(hDC , 0 ,0 , ByVal NULL)
LineTo(hDC , 300 , 300)
Rectangle(hDC , 100 , 100 , 150 , 150 )
'お返し
DeleteObject(hPen)
DeleteObject(hBrush)
End Sub
実行結果です。

上級編
今度は上級編です。
三角関数を使いますので、VCランタイムをインクルードします。
ABの三角関数でもいいのですが、せっかくなのでVCランタイムを使います。
関数の外ならどこでもいいんですが、読みやすくするため、
MainWnd.sbpの8行目(' TODO: この位置にグローバルな変数、構造体、定数、関数を定義します。の下)
に#include<vcrt71.sbp>を入れます。
Sub MainWnd_Paint(hDC As HDC)
Dim hPen As HPEN
Dim x As Double , y As Double
Dim t As Double , k As Double
Dim r As Double , a As Long
a = 4
k = 1
t = 0
hPen = CreatePen(PS_SOLID , 1 , RGB(255 , 0 , 0))
SelectObject(hDC , hPen)
r = a *pow(t , k)
MoveToEx(hDC , 100 - r*cos(t) ,100 - r*sin(t), ByVal NULL)
For t = 0 To 8 * M_PI Step M_PI/30
r = a *pow(t , k)
LineTo(hDC , 100 - r*cos(t) ,100 - r*sin(t))
Next
DeleteObject(hPen)
End Sub
警告がでますね。Double型からLong型に変換するとか言うのが。でも実行は問題なくできます。気持ち悪いかも知れませんが無視してください。
