〜 グラフィック 〜
任意の領域内を塗り潰し (要GDI32.DLL)

標準命令に任意の矩形を塗り潰すboxf命令が存在しますが、
三角形や五角形、その他複雑な形を一括して塗り潰す命令が用意されていません。
API関数のExtFloodFillで「任意座標の周囲同一色エリア一括塗り潰し」が可能なので、
この関数を用いて塗り潰すサンプルを紹介します。

GDIオブジェクトの図形内部の塗り潰す色がセットされたブラシを予めCreateSolidBrush関数等で作成し、
SelectObject関数でHSPウィンドウのデバイスコンテキストのブラシを選択した後に
ExtFloodFill関数で「塗り潰し箇所」と「指定色」、下記の「タイプ」を指定します。
0x0000FLOODFILLBORDER指定した色が囲んでいる領域を塗り潰す
0x0001FLOODFILLSURFACE指定した色と同じ色になっている領域を塗り潰す
わかりにくいですが、FLOODFILLBORDERは「指定色」を境界色として「塗り潰し箇所」とその周囲を塗り潰し、 FLOODFILLSURFACEは「塗り潰し箇所」とその周囲にある「指定色」を塗り潰すということです。 新しいブラシを使用した後は、SelectObject関数で元のブラシに戻す必要がありますので、 SelectObject関数を使用した際の戻り値である以前のブラシハンドルを変数に退避させておき、 使用後に再度SelectObject関数で元のブラシハンドルを指定するようにしてください。 また、不要になったブラシはDeleteObject関数で削除するようにしましょう。

areaf X座標, Y座標
X座標塗り潰すエリア内の任意のX座標を指定する
Y座標塗り潰すエリア内の任意のY座標を指定する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
	ll_libload gdi, "gdi32.dll"
	ll_getproc CreateSolidBrush, "CreateSolidBrush", gdi
	ll_getproc DeleteObject, "DeleteObject", gdi
	ll_getproc ExtFloodFill, "ExtFloodFill", gdi
	ll_getproc SelectObject, "SelectObject", gdi

#module
#deffunc areaf int, int
	mref x, 0 : mref y, 1
	mref bmscr, 67
	c = bmscr.40 // 現在のカレントカラーを退避
	ll_callfunc c, 1, CreateSolidBrush@ : ll_ret hBrush
	prm = bmscr.4, hBrush
	ll_callfunc prm, 2, SelectObject@ : ll_ret i
	pget x, y
	prm = bmscr.4, x, y, rval + (gval << 8) + (bval << 16), 1
	ll_callfunc prm, 5, ExtFloodFill@
	prm = bmscr.4, i
	ll_callfunc prm, 2, SelectObject@
	ll_callfunc hBrsuh, 1, DeleteObject@
	color c & 0xFF, c >> 8 & 0xFF, c >> 16 & 0xFF // 当初のカラーに戻す
	return
#global

	title "クリックで塗り潰し、右クリックでクリア"
	randomize
	button "変更", *init
	onclick *click

*init
	color
	rnd i.0, winx : rnd i.1, winx 
	line i, -1, i.1, winy
	rnd i.0, winy : rnd i.1, winy 
	line -1, i, winx, i.1
	repeat 3 : rnd c.cnt, 256 : loop : color c, c.1, c.2
	stop

*click
	if iparam {
		color 255, 255, 255 : boxf
		goto *init
	} else {
		areaf mousex, mousey // クリックした座標の周り、同色を一括で塗り潰す
		redraw
	}
	stop

areaf X座標, Y座標
X座標塗り潰すエリア内の任意のX座標を指定する
Y座標塗り潰すエリア内の任意のY座標を指定する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#uselib "gdi32.dll"
#cfunc global CreateSolidBrush "CreateSolidBrush" int
#func  global DeleteObject "DeleteObject" int
#func  global ExtFloodFill "ExtFloodFill" int, int, int, int, int
#func  global SelectObject "SelectObject" int,int

#module
#deffunc areaf int x, int y, local i
	c = ginfo_r, ginfo_g, ginfo_b // 現在のカレントカラーを退避
	hBrush = CreateSolidBrush(c + (c.1 << 8) + (c.2 << 16))
	SelectObject hdc, hBrush : i = stat
	pget x, y
	ExtFloodFill hdc, x, y, ginfo_r + (ginfo_g << 8) + (ginfo_b << 16), 1
	SelectObject hdc, i
	DeleteObject hBrsuh
	color c, c.1, c.2 // 当初のカラーに戻す
	return
#global

	title "クリックで塗り潰し、右クリックでクリア"
	randomize
	button gosub "変更", *init
	onclick gosub *click
	gosub *init
	stop

*init
	color
	line rnd(ginfo_winx), -1, rnd(ginfo_winx), ginfo_winy
	line -1, rnd(ginfo_winy), ginfo_winx, rnd(ginfo_winy)
	color rnd(256), rnd(256), rnd(256)
	return

*click
	if iparam {
		color 255, 255, 255 : boxf
		gosub *init
	} else {
		areaf mousex, mousey // クリックした座標の周り、同色を一括で塗り潰す
		redraw
	}
	return