トップ回答者
ExtFloodFillを有効にするには?

質問
-
vb 2010についてはド素人の私です。
上図のように閉領域をExtFloodFillを使って緑で塗りつぶしたいのですが、どうもうまくいきません
組んでみたコードは次の通りです。
Public Class Form1
Private Declare Function ExtFloodFill Lib "gdi32" _
(ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long, ByVal wFillType As Long) As LongPrivate Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
End Sub
Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
Dim g As Graphics
g = e.Graphics
g.Clear(Color.White)'############## 3個の円を描く ##############
Dim x1 As Integer
Dim x2 As Integer
Dim x3 As Integer
Dim y1 As Integer
Dim y2 As Integer
Dim y3 As Integer
Dim cx1 As Integer
Dim cx2 As Integer
Dim cx3 As Integer
Dim cy1 As Integer
Dim cy2 As Integer
Dim cy3 As IntegerDim r As Integer
r = 70
cx1 = 150
cx2 = 100
cx3 = 200
cy1 = 100
cy2 = 180
cy3 = 180Dim mypen As New Pen(Color.Black, 1)
x1 = cx1 - r
y1 = cy1 - r
x2 = cx2 - r
y2 = cy2 - r
x3 = cx3 - r
y3 = cy3 - r
g.DrawEllipse(mypen, x1, y1, r * 2, r * 2)
g.DrawEllipse(mypen, x2, y2, r * 2, r * 2)
g.DrawEllipse(mypen, x3, y3, r * 2, r * 2)
'###############################################'########### 閉領域の一つをみどりで塗りつぶす '#####
Dim hdc As Long
Dim x As Integer
Dim y As Integer
Dim crColor As Long
Dim wFillType As Long
Dim FillColor As New Color
Dim FillStyle As GraphicsUnitx = cx1
y = cy1crColor = &HFFFFFF
wFillType = 1
FillStyle = 0
FillColor = Color.FromArgb(0, 255, 0)
ExtFloodFill(hdc, x, y, crColor, wFillType) ←ここがエラーになる。
'#########################################################いったいどうすれば、ExtFloodFillを有効にできるのでしょうか?
ド素人の私にどうかご教授ください。
回答
-
0これが使えないならもうお手上げです。ほかに良い記述方法が思いつきません。
Win32API を使うのであれば、使うためのお作法があります。
正攻法としては MSDN のページ でシグネチャを確認し、正しく型を対応させることです。
HDC などのハンドルは IntPtr 型、int 型は Integer 型などです。
正しい書き換えがわからないのであれば、関数名と「P/Invoke」と「Declare」あたりをキーワードをつければ見つけられるかもしれませんね。ただ、VB6 のコードは使えないので気をつけてください。あとhdcなんですが、どんな値を設定すればよいかさえも思いつきません。
なら、あきらめますか?
「思いつきません」と書くのは結構ですが、「そうですか」で返されたら終わりますよ。
「素人」や「初心者」は免罪符にすらなりませんし、自分で調べられるようになることは今後開発を続けていく上で必要なスキルです。とりあえず、検索すると言うことを覚えていただく意味でも、「VB.NET HDC」あたりでも検索してみませんかね。
質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
- 編集済み AzuleanMVP, Moderator 2012年4月21日 15:38
- 回答としてマーク doctor of osaka 2012年4月21日 18:40
-
web内を探っているうちに、「vb中学校」なるものを見つけることが出来まして、そこでひろったものを参考にしてコードを思い切って書き改めました。
今度はうまくいきました。 Azuleanさんの叱咤激励、感謝します。
Imports System.Runtime.InteropServices
Public Class Form1
Private Declare Function ExtFloodFill Lib "gdi32" ( _
ByVal hdc As IntPtr, _
ByVal x As Integer, _
ByVal y As Integer, _
ByVal crColor As Integer, _
ByVal wFillType As UInteger) As <MarshalAs(UnmanagedType.Bool)> BooleanPrivate Const FLOODFILLBORDER As UInteger = 0 ' 境界色を目印にして塗りつぶすとき
Private Const FLOODFILLSURFACE As UInteger = 1 ' 領域色を目印にして塗りつぶすとき(複数色の境界色で囲まれているときなど)'色を指定するためのブラシ作成関数
Private Declare Function CreateBrushIndirect Lib "gdi32" (ByRef lpLogBrush As LOGBRUSH) As IntPtr
'不要になったブラシの解放
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
'デバイスコンテキストの取得
Private Declare Function GetWindowDC Lib "user32" (ByVal hwnd As IntPtr) As IntPtr
'デバイスコンテキストの開放
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As IntPtr, ByVal hdc As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
'色を指定するために使う関数(ブラシのもちかえ)
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As IntPtr, _
ByVal hObject As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean'CreateBrushIndirectに渡す引数の構造体
Private Structure LOGBRUSH
Public lbStyle As Integer
Public lbColor As Integer
Public lbHatch As Integer
End Structure
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.LoadEnd Sub
Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
Dim g As Graphics
g = e.Graphics
g.Clear(Color.White) '画面を真っ白に。'############## 3個の円を描く ##############
Dim x1 As Integer
Dim x2 As Integer
Dim x3 As Integer
Dim y1 As Integer
Dim y2 As Integer
Dim y3 As Integer
Dim cx1 As Integer
Dim cx2 As Integer
Dim cx3 As Integer
Dim cy1 As Integer
Dim cy2 As Integer
Dim cy3 As IntegerDim r As Integer
r = 70
cx1 = 150
cx2 = 100
cx3 = 200
cy1 = 100
cy2 = 180
cy3 = 180Dim mypen As New Pen(Color.Black, 4)
x1 = cx1 - r
y1 = cy1 - r
x2 = cx2 - r
y2 = cy2 - r
x3 = cx3 - r
y3 = cy3 - r
g.DrawEllipse(mypen, x1, y1, r * 2, r * 2)
g.DrawEllipse(mypen, x2, y2, r * 2, r * 2)
g.DrawEllipse(mypen, x3, y3, r * 2, r * 2)
'###############################################'########### 閉領域の一つをみどりで塗りつぶす '#####
Dim hwnd As IntPtr = Me.Handle 'フォームのハンドル
Dim hdc As IntPtr = GetWindowDC(hwnd) 'デバイスコンテキスト
Dim x As Integer
Dim y As Integer
Dim crColor As Integer = ColorTranslator.ToWin32(Color.FromArgb(255, 255, 255, 255)) 'System.Drawing.Colorをint型に変換する関数
Dim wFillType As UIntegerDim hNewBrush As Integer
Dim hOldBrush As IntegerDim NewBrush As LOGBRUSH
x = cx1
y = cy1
wFillType = FLOODFILLSURFACE
'ブラシの作成
NewBrush.lbColor = ColorTranslator.ToWin32(Color.FromArgb(255, 0, 155, 0))
NewBrush.lbStyle = 0
NewBrush.lbHatch = 0
hNewBrush = CreateBrushIndirect(NewBrush)
'ブラシを持ち替える
hOldBrush = SelectObject(hdc, hNewBrush)'ブラシの色で塗りつぶし
ExtFloodFill(hdc, x, y, crColor, wFillType)
'#########################################################
'解放 これは必要なのかわからないけど念のため
ReleaseDC(hwnd, hdc) 'デバイスコンテキストを開放する
hNewBrush = SelectObject(hdc, hOldBrush) '元のブラシに戻す
DeleteObject(hNewBrush) '不要になったブラシを開放する
End SubEnd Class
- 回答としてマーク doctor of osaka 2012年4月21日 18:40
- 回答としてマークされていない doctor of osaka 2012年4月21日 18:56
- 回答としてマーク doctor of osaka 2012年4月21日 19:03
- 回答としてマークされていない doctor of osaka 2012年4月21日 19:50
- 編集済み doctor of osaka 2012年4月21日 19:52
- 回答としてマーク doctor of osaka 2012年4月21日 19:52
すべての返信
-
-
-
0これが使えないならもうお手上げです。ほかに良い記述方法が思いつきません。
Win32API を使うのであれば、使うためのお作法があります。
正攻法としては MSDN のページ でシグネチャを確認し、正しく型を対応させることです。
HDC などのハンドルは IntPtr 型、int 型は Integer 型などです。
正しい書き換えがわからないのであれば、関数名と「P/Invoke」と「Declare」あたりをキーワードをつければ見つけられるかもしれませんね。ただ、VB6 のコードは使えないので気をつけてください。あとhdcなんですが、どんな値を設定すればよいかさえも思いつきません。
なら、あきらめますか?
「思いつきません」と書くのは結構ですが、「そうですか」で返されたら終わりますよ。
「素人」や「初心者」は免罪符にすらなりませんし、自分で調べられるようになることは今後開発を続けていく上で必要なスキルです。とりあえず、検索すると言うことを覚えていただく意味でも、「VB.NET HDC」あたりでも検索してみませんかね。
質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
- 編集済み AzuleanMVP, Moderator 2012年4月21日 15:38
- 回答としてマーク doctor of osaka 2012年4月21日 18:40
-
web内を探っているうちに、「vb中学校」なるものを見つけることが出来まして、そこでひろったものを参考にしてコードを思い切って書き改めました。
今度はうまくいきました。 Azuleanさんの叱咤激励、感謝します。
Imports System.Runtime.InteropServices
Public Class Form1
Private Declare Function ExtFloodFill Lib "gdi32" ( _
ByVal hdc As IntPtr, _
ByVal x As Integer, _
ByVal y As Integer, _
ByVal crColor As Integer, _
ByVal wFillType As UInteger) As <MarshalAs(UnmanagedType.Bool)> BooleanPrivate Const FLOODFILLBORDER As UInteger = 0 ' 境界色を目印にして塗りつぶすとき
Private Const FLOODFILLSURFACE As UInteger = 1 ' 領域色を目印にして塗りつぶすとき(複数色の境界色で囲まれているときなど)'色を指定するためのブラシ作成関数
Private Declare Function CreateBrushIndirect Lib "gdi32" (ByRef lpLogBrush As LOGBRUSH) As IntPtr
'不要になったブラシの解放
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
'デバイスコンテキストの取得
Private Declare Function GetWindowDC Lib "user32" (ByVal hwnd As IntPtr) As IntPtr
'デバイスコンテキストの開放
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As IntPtr, ByVal hdc As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
'色を指定するために使う関数(ブラシのもちかえ)
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As IntPtr, _
ByVal hObject As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean'CreateBrushIndirectに渡す引数の構造体
Private Structure LOGBRUSH
Public lbStyle As Integer
Public lbColor As Integer
Public lbHatch As Integer
End Structure
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.LoadEnd Sub
Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
Dim g As Graphics
g = e.Graphics
g.Clear(Color.White) '画面を真っ白に。'############## 3個の円を描く ##############
Dim x1 As Integer
Dim x2 As Integer
Dim x3 As Integer
Dim y1 As Integer
Dim y2 As Integer
Dim y3 As Integer
Dim cx1 As Integer
Dim cx2 As Integer
Dim cx3 As Integer
Dim cy1 As Integer
Dim cy2 As Integer
Dim cy3 As IntegerDim r As Integer
r = 70
cx1 = 150
cx2 = 100
cx3 = 200
cy1 = 100
cy2 = 180
cy3 = 180Dim mypen As New Pen(Color.Black, 4)
x1 = cx1 - r
y1 = cy1 - r
x2 = cx2 - r
y2 = cy2 - r
x3 = cx3 - r
y3 = cy3 - r
g.DrawEllipse(mypen, x1, y1, r * 2, r * 2)
g.DrawEllipse(mypen, x2, y2, r * 2, r * 2)
g.DrawEllipse(mypen, x3, y3, r * 2, r * 2)
'###############################################'########### 閉領域の一つをみどりで塗りつぶす '#####
Dim hwnd As IntPtr = Me.Handle 'フォームのハンドル
Dim hdc As IntPtr = GetWindowDC(hwnd) 'デバイスコンテキスト
Dim x As Integer
Dim y As Integer
Dim crColor As Integer = ColorTranslator.ToWin32(Color.FromArgb(255, 255, 255, 255)) 'System.Drawing.Colorをint型に変換する関数
Dim wFillType As UIntegerDim hNewBrush As Integer
Dim hOldBrush As IntegerDim NewBrush As LOGBRUSH
x = cx1
y = cy1
wFillType = FLOODFILLSURFACE
'ブラシの作成
NewBrush.lbColor = ColorTranslator.ToWin32(Color.FromArgb(255, 0, 155, 0))
NewBrush.lbStyle = 0
NewBrush.lbHatch = 0
hNewBrush = CreateBrushIndirect(NewBrush)
'ブラシを持ち替える
hOldBrush = SelectObject(hdc, hNewBrush)'ブラシの色で塗りつぶし
ExtFloodFill(hdc, x, y, crColor, wFillType)
'#########################################################
'解放 これは必要なのかわからないけど念のため
ReleaseDC(hwnd, hdc) 'デバイスコンテキストを開放する
hNewBrush = SelectObject(hdc, hOldBrush) '元のブラシに戻す
DeleteObject(hNewBrush) '不要になったブラシを開放する
End SubEnd Class
- 回答としてマーク doctor of osaka 2012年4月21日 18:40
- 回答としてマークされていない doctor of osaka 2012年4月21日 18:56
- 回答としてマーク doctor of osaka 2012年4月21日 19:03
- 回答としてマークされていない doctor of osaka 2012年4月21日 19:50
- 編集済み doctor of osaka 2012年4月21日 19:52
- 回答としてマーク doctor of osaka 2012年4月21日 19:52