境界の色が違う複数の図形の塗りつぶし への返答
投稿で使用できる特殊コードの説明。(別タブで開きます。)
以下の返答は逆順(新しい順)に並んでいます。
投稿者 shu  (社会人)
投稿日時
2012/2/20 07:35:31
> >開放
> 解放のほうがしっくりきますね・・・
開放・・・ドアとかを開けっ放しにすることです。
ITではポートの開放という使い方はします。
> 解放のほうがしっくりきますね・・・
開放・・・ドアとかを開けっ放しにすることです。
ITではポートの開放という使い方はします。
投稿者 ラオシス  (中学生)
投稿日時
2012/2/19 22:49:22
>開放とはどういうことなのでしようか。
開放とは、終了,破棄とかそういう感じですね。
いらなくなったものを、破棄、終了させ自由にさせるというニュアンスでしょうか。
Disposeも同じものです。なぜ開放をしなければならないかというと、メモリが重くなりパフォーマンスが低くなるためです。
たとえばファイルの読み書きなどの場合、開放をしなければほかのプロセスは読み書きできないという状態になるので開放させる必要があります。
>開放
解放のほうがしっくりきますね・・・
以下もご参照に。
http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard46.htm
>ListBox1.Items.Add(hdc)を実行してみましたが、 hDCは同じ数字がつづきます。
大丈夫だと思いますよ。
開放とは、終了,破棄とかそういう感じですね。
いらなくなったものを、破棄、終了させ自由にさせるというニュアンスでしょうか。
Disposeも同じものです。なぜ開放をしなければならないかというと、メモリが重くなりパフォーマンスが低くなるためです。
たとえばファイルの読み書きなどの場合、開放をしなければほかのプロセスは読み書きできないという状態になるので開放させる必要があります。
>開放
解放のほうがしっくりきますね・・・
以下もご参照に。
http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard46.htm
>ListBox1.Items.Add(hdc)を実行してみましたが、 hDCは同じ数字がつづきます。
大丈夫だと思いますよ。
投稿者 下田の住人  (社会人)
投稿日時
2012/2/19 15:55:11
Picturebox2を設け、そこにAPI BitBltでPicturebox1のコピーをとり、その後Picturebox2.ImageをPicturebox1に戻すことによって「塗りつぶし」は可能となりました。
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
If e.Button = System.Windows.Forms.MouseButtons.Right Then
Dim g As Graphics = Graphics.FromImage(PictureBox1.Image)
Dim hWnd As IntPtr = PictureBox1.Handle
Dim hdc As IntPtr = GetWindowDC(hWnd)
Dim wFillType As UInteger = 1 ' FLOODFILLSURFACE
Dim hNewBrush As IntPtr
Dim hOldBrush As IntPtr
Dim NewBrush As LOGBRUSH
NewBrush.lbColor = ColorTranslator.ToWin32(Color.Yellow)
NewBrush.lbStyle = 0
NewBrush.lbHatch = 0
hNewBrush = CreateBrushIndirect(NewBrush)
hOldBrush = SelectObject(hdc, hNewBrush)
ExtFloodFill(hdc, e.X, e.Y, GetPixel(hdc, e.X, e.Y), wFillType)
Dim gr As Graphics = Graphics.FromImage(PictureBox2.Image)
Dim hDC2 = gr.GetHdc()
PictureBox2.Visible = False
BitBlt(hDC2, 0, 0, 300, 300, hdc, 0, 0, &HCC0020&)
PictureBox1.Image = PictureBox2.Image
ReleaseDC(hWnd, hdc) 'デバイスコンテキストを開放する
hNewBrush = SelectObject(hdc, hOldBrush) '元のブラシに戻す
DeleteObject(hNewBrush) '不要になったブラシを開放する
g.Dispose()
ReleaseDC(hWnd, hDC2)
gr.Dispose()
'ListBox1.Items.Add(hdc)
End If
End Sub
End If の1行前 ListBox1.Items.Add(hdc)を実行してみましたが、 hDCは同じ数字がつづきます。そもそも開放とはどういうことなのでしようか。開放の為のコードの使い方が間違っているのでしょうか。
投稿者 下田の住人  (社会人)
投稿日時
2012/2/13 09:53:55
るきお様 投稿を拝見しExtFloodFillがだんだん遠く名なり、初心者の手には益々届かぬものになっていると感じています。
VB.NetではFillStyle、FillColorが無くなり、Pointも違うものになり、その為 初心者から遠く離れた存在になってしまいました。
複数の境界線の閉じた図形を描いておいて、後から図形の1つ1つを塗りつぶす時に、その個別の図形をいかに安定して選ぶか、また塗りつぶし後 それが消えないようにするか、皆様から御指導を頂きたく よろしくお願い致します。
VB6ではAutoredraw、FillStyle、FillColer、Pointのプロパティによって簡単に閉領域の塗りつぶしができました。
Picture1.FillStyle = 0
Picture1.FillColor = RGB(255, 255, 0)
ExtFloodFill Picture1.hdc, X, Y, Picture1.Point(X, Y), 1
VB.NetではFillStyle、FillColorが無くなり、Pointも違うものになり、その為 初心者から遠く離れた存在になってしまいました。
複数の境界線の閉じた図形を描いておいて、後から図形の1つ1つを塗りつぶす時に、その個別の図形をいかに安定して選ぶか、また塗りつぶし後 それが消えないようにするか、皆様から御指導を頂きたく よろしくお願い致します。
投稿者 るきお  (社会人)
投稿日時
2012/2/12 18:45:46
続きです。
Public Class GDIWrapper
Implements IDisposable
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 Integer) As Integer
Private Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Integer) As IntPtr
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As IntPtr, ByVal X As Integer, ByVal Y As Integer) As Integer
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As IntPtr, ByVal hObject As IntPtr) As IntPtr
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As IntPtr) As Integer
Private Declare Function GdiFlush Lib "gdi32" Alias "GdiFlush" () As Integer
Const PS_SOLID As Integer = 0
Private Declare Function CreatePen Lib "gdi32" (ByVal fnPenStyle As Integer, ByVal nWidth As Integer, ByVal crColor As Integer) As IntPtr
Private Declare Function MoveToEx Lib "gdi32" (ByVal hdc As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal lpPoint As Integer) As Boolean
Private Declare Function LineTo Lib "gdi32" (ByVal hdc As IntPtr, ByVal nXEnd As Integer, ByVal nYEnd As Integer) As Boolean
Private Const FLOODFILLBORDER As Integer = 0
Private Const FLOODFILLSURFACE As Integer = 1
Protected mainGraphics As Graphics
Protected hDC As IntPtr
Public Sub New(image As Bitmap)
mainGraphics = Graphics.FromImage(image)
hDC = mainGraphics.GetHdc
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
mainGraphics.ReleaseHdc()
mainGraphics.Dispose()
End Sub
Private Sub CreatePen(color As Color)
'新しいペンを作成
Dim hPen As IntPtr
hPen = CreatePen(PS_SOLID, 2, ColorTranslator.ToOle(color))
Dim hOldPen As IntPtr
hOldPen = SelectObject(hDC, hPen)
DeleteObject(hOldPen)
End Sub
Private Sub CreateBrush(color As Color)
'新しいブラシを作成
Dim hBrush As IntPtr
hBrush = CreateSolidBrush(ColorTranslator.ToOle(color))
Dim hOldBrush As IntPtr
hOldBrush = SelectObject(hDC, hBrush)
DeleteObject(hOldBrush)
End Sub
Public Sub DrawLine(pen As Pen, x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer)
Me.DrawLine(pen, New Point(x1, y1), New Point(x2, y2))
End Sub
Public Sub DrawLine(pen As Pen, pt1 As Point, pt2 As Point)
CreatePen(pen.Color)
MoveToEx(hDC, pt1.X, pt1.Y, 0)
LineTo(hDC, pt2.X, pt2.Y)
End Sub
Public Sub FloodFill(color As Color, pt As Point)
CreateBrush(color)
Dim backColor As Integer = GetPixel(hDC, pt.X, pt.Y)
ExtFloodFill(hDC, pt.X, pt.Y, backColor, FLOODFILLSURFACE)
End Sub
Public Sub Flush()
GdiFlush()
End Sub
End Class
投稿者 るきお  (社会人)
投稿日時
2012/2/12 18:45:21
直接の回答ではありません。
ExtFloodFillは誰にも使いこなせない意地悪な関数です。
VBの数々の高度な描画処理の中に採用されなかった理由もこの意地悪さに由来しているのかもしれません。
誰か、簡単でよいので塗りつぶし機能付きのお絵かきプログラムの作り方がわかる方は是非教えてください。
手段は2つあります。
手段1.ExtFloodFillでなんとかする。
手段2.塗りつぶしのロジックを自作する。
手段1については、下田の住人さんもExtFloodFillで描画するところまではできているのに、うまくほかの機能と調和が採れていませんよね?世間に公開されているサンプルでもExtFloodFill自体はなんとかできているものがありますが、望みどおりになるかは疑問があります。
参考:ExtFloodFill in VB.NET
http://www.planetsourcecode.com/vb/scripts/ShowCode.asp?txtCodeId=3977&lngWId=10
手段2の「塗りつぶしのロジックを自作」は試したことはありませんが、他の機能と調和させるという意味では有望だと思います。
参考:Flood Fill Algorithms in C# and GDI+
http://www.codeproject.com/Articles/5133/Flood-Fill-Algorithms-in-C-and-GDI
unsafeを使っているのでVBに翻訳するのは困難ですが、.NET言語同士の呼び出しは簡単なのでそのまま利用してVBから呼び出せばいいかもしれません。(私はダウンロードしていないので実際のところは不明です。)
さて、うまくはいきませんでしたが、私が手段1に挑戦してみた結果も載せておきます。
GDI+をほとんど使わず、GDIだけで処理すればなんとかなるのではないかと考えてみました。
Graphics.GetHdc~Graphics.ReleaseHdcの間で行う描画と塗りつぶしはうまくできました。
ただ、ReleaseHdcしないと画面には表示されないようで、目隠しされた状態でのお絵かきを強いられます。(Button2のクリックでReleaseHdcできるようにしておきました。)
また、GetHdc~ReleaseHdcの間を仮に「セッション」と呼ぶことにすると、別のセッションどうしはうまく連携してくれず、前のセッションで描画した線の中に、次のセッションで黄色く塗ろうとすると全体が黄色になってしまいます。
・ReleaseHdcしないでも表示が更新されるようにできれば、全体が1つのセッションになるので問題は解決できますが、その手段が不明です。
・複数セッションをまたいでお互いが連携できるようにしても問題は解決できますが、その手段が不明です。
長いので分割します。
ExtFloodFillは誰にも使いこなせない意地悪な関数です。
VBの数々の高度な描画処理の中に採用されなかった理由もこの意地悪さに由来しているのかもしれません。
誰か、簡単でよいので塗りつぶし機能付きのお絵かきプログラムの作り方がわかる方は是非教えてください。
手段は2つあります。
手段1.ExtFloodFillでなんとかする。
手段2.塗りつぶしのロジックを自作する。
手段1については、下田の住人さんもExtFloodFillで描画するところまではできているのに、うまくほかの機能と調和が採れていませんよね?世間に公開されているサンプルでもExtFloodFill自体はなんとかできているものがありますが、望みどおりになるかは疑問があります。
参考:ExtFloodFill in VB.NET
http://www.planetsourcecode.com/vb/scripts/ShowCode.asp?txtCodeId=3977&lngWId=10
手段2の「塗りつぶしのロジックを自作」は試したことはありませんが、他の機能と調和させるという意味では有望だと思います。
参考:Flood Fill Algorithms in C# and GDI+
http://www.codeproject.com/Articles/5133/Flood-Fill-Algorithms-in-C-and-GDI
unsafeを使っているのでVBに翻訳するのは困難ですが、.NET言語同士の呼び出しは簡単なのでそのまま利用してVBから呼び出せばいいかもしれません。(私はダウンロードしていないので実際のところは不明です。)
さて、うまくはいきませんでしたが、私が手段1に挑戦してみた結果も載せておきます。
GDI+をほとんど使わず、GDIだけで処理すればなんとかなるのではないかと考えてみました。
Graphics.GetHdc~Graphics.ReleaseHdcの間で行う描画と塗りつぶしはうまくできました。
ただ、ReleaseHdcしないと画面には表示されないようで、目隠しされた状態でのお絵かきを強いられます。(Button2のクリックでReleaseHdcできるようにしておきました。)
また、GetHdc~ReleaseHdcの間を仮に「セッション」と呼ぶことにすると、別のセッションどうしはうまく連携してくれず、前のセッションで描画した線の中に、次のセッションで黄色く塗ろうとすると全体が黄色になってしまいます。
・ReleaseHdcしないでも表示が更新されるようにできれば、全体が1つのセッションになるので問題は解決できますが、その手段が不明です。
・複数セッションをまたいでお互いが連携できるようにしても問題は解決できますが、その手段が不明です。
Option Strict On
Public Class Form1
Dim oldX, oldY As Integer
Dim gdi As GDIWrapper
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim baseImage As Bitmap = New Bitmap(PictureBox1.Width, PictureBox1.Height)
PictureBox1.Image = baseImage
gdi = New GDIWrapper(baseImage)
End Sub
Private Sub Form1_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
'gdi.Dispose()
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
If e.Button = System.Windows.Forms.MouseButtons.Left Then
gdi.DrawLine(Pens.Green, oldX, oldY, e.X, e.Y)
End If
oldX = e.X
oldY = e.Y
End Sub
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
If e.Button = System.Windows.Forms.MouseButtons.Right Then
gdi.FloodFill(Color.Yellow, New Point(e.X, e.Y))
End If
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
gdi.Dispose()
PictureBox1.Invalidate()
gdi = New GDIWrapper(CType(PictureBox1.Image, Bitmap))
End Sub
End Class
長いので分割します。
投稿者 ラオシス  (中学生)
投稿日時
2012/2/12 17:05:52
こんにちは。
質問とは関係ありませんが、
列挙体としてまとめるべきかなと思います。
Enum ステートメント (Visual Basic)
http://msdn.microsoft.com/ja-jp/library/8h84wky1.aspx
UInteger型も使えるみたいですし。
>デバイスコンテキストを得るための手法につきましては、完全に行き詰まっています
何で行き詰っていますか?
質問とは関係ありませんが、
Private Const FLOODFILLBORDER As UInteger = 0 'UI
Private Const FLOODFILLSURFACE As UInteger = 1 'UI
列挙体としてまとめるべきかなと思います。
Enum ステートメント (Visual Basic)
http://msdn.microsoft.com/ja-jp/library/8h84wky1.aspx
UInteger型も使えるみたいですし。
>デバイスコンテキストを得るための手法につきましては、完全に行き詰まっています
何で行き詰っていますか?
投稿者 下田の住人  (社会人)
投稿日時
2012/2/12 14:50:41
>また、Paint 内での描画内容が固定的な場合は、Paint をその都度処理する代わりに、
>予め Bitmap に描画しておいて、それを PictureBox に表示した方が楽かもしれません。
固定的なものてはではなく「子供達のための「お絵かき」を作ろうと思っています。
デバイスコンテキストを得るための手法につきましては、完全に行き詰まっています。具体的なヒントを頂ければと存じます。
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 Boolean
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
Private Declare Function GetPixel Lib "gdi32" Alias "GetPixel" (ByVal hdc As IntPtr, ByVal x As Integer, ByVal y As Integer) As Integer
Private Declare Function CreateCompatibleDC Lib "gdi32" Alias "CreateCompatibleDC" (ByVal hdc As IntPtr) As IntPtr
Private Const FLOODFILLBORDER As UInteger = 0 'UI
Private Const FLOODFILLSURFACE As UInteger = 1 'UI
Private Structure LOGBRUSH
Public lbStyle As Integer
Public lbColor As Integer
Public lbHatch As Integer
End Structure
Dim oldX, oldY As Integer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'PictureBox1.Refresh()
PictureBox1.Image = New Bitmap(PictureBox1.Width, PictureBox1.Height)
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
'---- 自由ラインを描く ---- 閉じた図形とする
If e.Button = System.Windows.Forms.MouseButtons.Left Then
Dim g As Graphics = Graphics.FromImage(PictureBox1.Image)
Dim myPen As New Pen(Color.Green, 2)
g.DrawLine(myPen, oldX, oldY, e.X, e.Y)
PictureBox1.Image = PictureBox1.Image
g.Dispose()
PictureBox1.Refresh() 'Invalidate()
End If
oldX = e.X : oldY = e.Y
End Sub
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
'----- 塗りつぶしは マウス 右クリック -------
Dim g As Graphics = PictureBox1.CreateGraphics
If e.Button = System.Windows.Forms.MouseButtons.Right Then
Dim hDC As Long = g.GetHdc()
Dim wFillType As UInteger = 1 ' FLOODFILLSURFACE
Dim hNewBrush As IntPtr
Dim hOldBrush As IntPtr
Dim NewBrush As LOGBRUSH
NewBrush.lbColor = ColorTranslator.ToWin32(Color.Yellow)
NewBrush.lbStyle = 0
NewBrush.lbHatch = 0
hNewBrush = CreateBrushIndirect(NewBrush)
hOldBrush = SelectObject(hDC, hNewBrush)
ExtFloodFill(hDC, e.X, e.Y, GetPixel(hDC, e.X, e.Y), wFillType)
g.ReleaseHdc()
hNewBrush = SelectObject(hDC, hOldBrush)
DeleteObject(hNewBrush)
End If
g.Dispose()
End Sub
End Class
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2012/2/10 18:01:31
> CreateGraphicsは使用するなという 御注意があることは覚悟しておりました。
Paint イベントなら、e.Graphics に描画するのが本来のありようですから、
わざわざ CreateGraphics する必要は無いはずです。
それに先のコードでは、Paint イベント時の CreateGraphics を Dispose していませんよね。
(MouseClick 時には Dispose しているのに…)
また、Paint 内での描画内容が固定的な場合は、Paint をその都度処理する代わりに、
予め Bitmap に描画しておいて、それを PictureBox に表示した方が楽かもしれません。
> 「そのビットマップを PictureBox の Image / BackgroundImage に割り当てる。」にはどういう手法を用いるのか御教示下さい。
PictureBox1.Image = bmp
のように、描画結果の Bitmap オブジェクトを指定するということです。
こうしておけば、Paint イベントで毎回描画する必要は無くなりますし。
> デバイスコンテキストhDCを得るためにCreateGraphicsを使用しましたがこれはよろしいのでしようか
ビットマップに対して描画する場合は、以下が参考になりそうです。
http://hanatyan.sakura.ne.jp/vbnetbbs/wforum.cgi?mode=allread&no=8474&page=0
Paint イベントなら、e.Graphics に描画するのが本来のありようですから、
わざわざ CreateGraphics する必要は無いはずです。
それに先のコードでは、Paint イベント時の CreateGraphics を Dispose していませんよね。
(MouseClick 時には Dispose しているのに…)
また、Paint 内での描画内容が固定的な場合は、Paint をその都度処理する代わりに、
予め Bitmap に描画しておいて、それを PictureBox に表示した方が楽かもしれません。
> 「そのビットマップを PictureBox の Image / BackgroundImage に割り当てる。」にはどういう手法を用いるのか御教示下さい。
PictureBox1.Image = bmp
のように、描画結果の Bitmap オブジェクトを指定するということです。
こうしておけば、Paint イベントで毎回描画する必要は無くなりますし。
> デバイスコンテキストhDCを得るためにCreateGraphicsを使用しましたがこれはよろしいのでしようか
ビットマップに対して描画する場合は、以下が参考になりそうです。
http://hanatyan.sakura.ne.jp/vbnetbbs/wforum.cgi?mode=allread&no=8474&page=0
投稿者 下田の住人  (社会人)
投稿日時
2012/2/10 15:12:25
早速に御投稿有難うございます。
CreateGraphicsは使用するなという 御注意があることは覚悟しておりました。
(案1) 「そのビットマップを PictureBox の Image / BackgroundImage に割り当てる。」にはどういう手法を用いるのか御教示下さい。
マウスでクリックした閉領域のみのデバイスコンテキストhDCを得るためにCreateGraphicsを使用しましたがこれはよろしいのでしようか。
塗りつぶしが消えた後,再度のクリックで塗りつぶしが安定するカラクリがわかればよいのでしょうが
87歳の超初心者には難問です。
よろしく御指導下さい。
CreateGraphicsは使用するなという 御注意があることは覚悟しておりました。
(案1) 「そのビットマップを PictureBox の Image / BackgroundImage に割り当てる。」にはどういう手法を用いるのか御教示下さい。
マウスでクリックした閉領域のみのデバイスコンテキストhDCを得るためにCreateGraphicsを使用しましたがこれはよろしいのでしようか。
塗りつぶしが消えた後,再度のクリックで塗りつぶしが安定するカラクリがわかればよいのでしょうが
87歳の超初心者には難問です。
よろしく御指導下さい。
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2012/2/9 18:49:20
CreateGraphics は、基本的には使わないでください。
これで描画した結果は、次の再描画タイミングでは消去されるため、
描画された状態を維持するためには向いていません。
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.control.creategraphics.aspx
》 CreateGraphics メソッドを通じて取得する Graphics オブジェクトは通常、
》 現在の Windows メッセージが処理された後には保持されません。
》 これは、このオブジェクトを使用して塗りつぶされたオブジェクトは、
》 次の WM_PAINT メッセージで消去されるためです。
PictureBox への描画結果を残しておきたい場合には、以下のいずれかの方法を使います。
(案1) New Bitmap で空のビットマップを作成し、Graphics.FromImage に対して描画した後、
そのビットマップを PictureBox の Image / BackgroundImage に割り当てる。
(案2) PictureBox の Paint イベントで、e.Graphics に対して、毎回再描画する。
(Paint は、再描画が必要になった場合にそれを知らせるためのイベントです)
これで描画した結果は、次の再描画タイミングでは消去されるため、
描画された状態を維持するためには向いていません。
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.control.creategraphics.aspx
》 CreateGraphics メソッドを通じて取得する Graphics オブジェクトは通常、
》 現在の Windows メッセージが処理された後には保持されません。
》 これは、このオブジェクトを使用して塗りつぶされたオブジェクトは、
》 次の WM_PAINT メッセージで消去されるためです。
PictureBox への描画結果を残しておきたい場合には、以下のいずれかの方法を使います。
(案1) New Bitmap で空のビットマップを作成し、Graphics.FromImage に対して描画した後、
そのビットマップを PictureBox の Image / BackgroundImage に割り当てる。
(案2) PictureBox の Paint イベントで、e.Graphics に対して、毎回再描画する。
(Paint は、再描画が必要になった場合にそれを知らせるためのイベントです)
投稿者 下田の住人  (社会人)
投稿日時
2012/2/9 17:13:23
初めて投稿致します。よろしくお願い致します。
http://rucio.cloudapp.net/ThreadDetail.aspx?ThreadId=9715のyamada様の投稿を基本にして、2つの境界色を異にする長方形を描き、その領域の塗りつぶしを試みました。
閉領域の塗りつぶしは出来るようにはなりましたが、すぐ消えてしまい、再度のマウスクリックで安定する状態となります。「消え」を防ぐための方法につきよろしく御指導下さい。
[CODE]
Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
PictureBox1.Refresh()
PictureBox1.CreateGraphics.DrawRectangle(Pens.Red, 50, 80, 120, 100)
PictureBox1.CreateGraphics.DrawRectangle(Pens.Black, 80, 120, 120, 100)
End Sub
Private Sub PictureBox1_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseClick
Dim g As Graphics = PictureBox1.CreateGraphics
Dim wFillType As UInteger = 1 ' FLOODFILLSURFACE
Dim hNewBrush As IntPtr
Dim hOldBrush As IntPtr
Dim NewBrush As LOGBRUSH
Dim hDC As IntPtr
hDC = g.GetHdc
NewBrush.lbColor = ColorTranslator.ToWin32(Color.Yellow)
NewBrush.lbStyle = 0
NewBrush.lbHatch = 0
hNewBrush = CreateBrushIndirect(NewBrush)
hOldBrush = SelectObject(hDC, hNewBrush)
ExtFloodFill(hDC, e.X, e.Y, GetPixel(hDC, e.X, e.Y), wFillType)
g.ReleaseHdc()
hNewBrush = SelectObject(hDC, hOldBrush)
DeleteObject(hNewBrush)
g.Dispose()
end sub
{/CODE]
http://rucio.cloudapp.net/ThreadDetail.aspx?ThreadId=9715のyamada様の投稿を基本にして、2つの境界色を異にする長方形を描き、その領域の塗りつぶしを試みました。
閉領域の塗りつぶしは出来るようにはなりましたが、すぐ消えてしまい、再度のマウスクリックで安定する状態となります。「消え」を防ぐための方法につきよろしく御指導下さい。
[CODE]
Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
PictureBox1.Refresh()
PictureBox1.CreateGraphics.DrawRectangle(Pens.Red, 50, 80, 120, 100)
PictureBox1.CreateGraphics.DrawRectangle(Pens.Black, 80, 120, 120, 100)
End Sub
Private Sub PictureBox1_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseClick
Dim g As Graphics = PictureBox1.CreateGraphics
Dim wFillType As UInteger = 1 ' FLOODFILLSURFACE
Dim hNewBrush As IntPtr
Dim hOldBrush As IntPtr
Dim NewBrush As LOGBRUSH
Dim hDC As IntPtr
hDC = g.GetHdc
NewBrush.lbColor = ColorTranslator.ToWin32(Color.Yellow)
NewBrush.lbStyle = 0
NewBrush.lbHatch = 0
hNewBrush = CreateBrushIndirect(NewBrush)
hOldBrush = SelectObject(hDC, hNewBrush)
ExtFloodFill(hDC, e.X, e.Y, GetPixel(hDC, e.X, e.Y), wFillType)
g.ReleaseHdc()
hNewBrush = SelectObject(hDC, hOldBrush)
DeleteObject(hNewBrush)
g.Dispose()
end sub
{/CODE]
>開放・・・ドアとかを開けっ放しにすることです。
というshuさんの御説明でスッキ理解出来ました。やはり「開放」ですね。
初心者は自分のコーディングしたものが、たまたま出来たのか、或いは正しいのか、判断がつきません。すなわち、「解決」にチェックを入れていいのか迷っている状態です。つまり通信簿か採点をお願い出来れば、今後の励みとなります。御意見を頂きたく存じます。