TabPageに線を描画する方法について
投稿者 とくま  (社会人)
投稿日時
2025/5/22 09:15:36
TabPage にも Paint イベントは実装されているようです。
前回の質問と何が違うのですか?
https://keijiban.umayadia.com/ThreadDetail.aspx?ThreadId=31013
前回の質問と何が違うのですか?
https://keijiban.umayadia.com/ThreadDetail.aspx?ThreadId=31013
投稿者 hige3  (社会人)
投稿日時
2025/5/24 06:52:09
とくま様
前回、フォームに描画する方法として下記を教えていただきました。
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
e.Graphics.DrawLine(New Pen(Color.Red, 2), 10, 120, 50, 220)
End Sub
今回は Form1 上に作成した TabPage に描画したいんですが、TabPageの指定方法が分からないんです。
因みに下記では不可でした。
Private Sub TabPage1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
e.Graphics.DrawLine(New Pen(Color.Gray, 1), 90, 170, 90, 210)
End Sub
御教授よろしくお願いいたします。
前回、フォームに描画する方法として下記を教えていただきました。
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
e.Graphics.DrawLine(New Pen(Color.Red, 2), 10, 120, 50, 220)
End Sub
今回は Form1 上に作成した TabPage に描画したいんですが、TabPageの指定方法が分からないんです。
因みに下記では不可でした。
Private Sub TabPage1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
e.Graphics.DrawLine(New Pen(Color.Gray, 1), 90, 170, 90, 210)
End Sub
御教授よろしくお願いいたします。
投稿者 KOZ  (社会人)
投稿日時
2025/5/24 07:04:25
VB6 と違い、メソッド名とコントロールのイベントは結びついていません。
Handles の後に続くのがコントロールのイベントです。
つまり、Handles MyBase.Paint ではフォームのイベントになってしまいます。
イベントハンドラーの追加は
第4回 イベントを逃すな
http://rucio.o.oo7.jp/VBNyumon/BEGIN4.htm
「3-2.プロパティウィンドウによるイベントハンドラーの生成」
を読んでください。
Handles の後に続くのがコントロールのイベントです。
つまり、Handles MyBase.Paint ではフォームのイベントになってしまいます。
イベントハンドラーの追加は
第4回 イベントを逃すな
http://rucio.o.oo7.jp/VBNyumon/BEGIN4.htm
「3-2.プロパティウィンドウによるイベントハンドラーの生成」
を読んでください。
投稿者 hige3  (社会人)
投稿日時
2025/5/24 18:17:39
KOZ様
起動時の設定は load しか知りませんでしたが、下記でShown を知りました。
>http://rucio.o.oo7.jp/VBNyumon/BEGIN4.htm
Load ではうまくいかなかったのが、Shown でうまく描画されました。
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
SenKaki_1()
End Sub
Private Sub SenKaki_1()
Me.CreateGraphics.DrawLine(penR, 90, 170, 420, 170)
End Sub
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
SenKaki_1()
End Sub
TabPage の描画については、これから取りかかりますが理解出来るかどうか(泣)
先ずは、急ぎ御礼まで。
有り難う御座いました。
起動時の設定は load しか知りませんでしたが、下記でShown を知りました。
>http://rucio.o.oo7.jp/VBNyumon/BEGIN4.htm
Load ではうまくいかなかったのが、Shown でうまく描画されました。
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
SenKaki_1()
End Sub
Private Sub SenKaki_1()
Me.CreateGraphics.DrawLine(penR, 90, 170, 420, 170)
End Sub
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
SenKaki_1()
End Sub
TabPage の描画については、これから取りかかりますが理解出来るかどうか(泣)
先ずは、急ぎ御礼まで。
有り難う御座いました。
投稿者 KOZ  (社会人)
投稿日時
2025/5/25 07:50:56
フォームを最小化して元に戻してみてください。
書かれたものが消えているはずです。
描画は Paint イベントで行いましょう。
書かれたものが消えているはずです。
描画は Paint イベントで行いましょう。
投稿者 とくま  (社会人)
投稿日時
2025/5/26 09:19:30
他のウィンドウ(メモ帳とか)をフォームの上に重ねた後に取り除いても消えると思います。
ディスプレイ上は2次元の話なので、ウィンドウを重ねると下に描画されていたフォームは上書きされて存在しなくなります。
取り除いたときに、もう一度、描画しなおす必要があります。ディスプレイ上では、常に再描画が行われていることを覚えてください。
フォーム自体は、描画する処理が裏の見えない処理に書かれていますが、後からプログラムした描画処理も再描画する
必要があります。この手っ取り早いやり方が Paint イベントです。つまり初心者は、画面に描画する処理で
Paint イベント以外は使ったらNGだと思って下さい。
> Private Sub SenKaki_1()
> Me.CreateGraphics.DrawLine(penR, 90, 170, 420, 170)
> End Sub
これもNG。
Paint イベントの引数(e.Graphics)を使いまわす場合は、裏の処理が後始末してくれるので問題ありませんが、
自分で CreateGraphics するとリソース(メモリ)の確保が行われます。
その場合、解放処理まで自分で書く必要があります。画像系のプログラムはメモリを食うので、
繰り返すと目に見える形でメモリリークが起こる場合があります。
https://dobon.net/vb/dotnet/graphics/drawline.html
>'リソースを解放する
>g.Dispose()
の処理が必要です。
penR も使いまわすのは良いですが、フォームの Dispose イベントで解放するのを覚えたほうが良い場面となります。
penR.Dispose() を呼ぶ必要があります。
ディスプレイ上は2次元の話なので、ウィンドウを重ねると下に描画されていたフォームは上書きされて存在しなくなります。
取り除いたときに、もう一度、描画しなおす必要があります。ディスプレイ上では、常に再描画が行われていることを覚えてください。
フォーム自体は、描画する処理が裏の見えない処理に書かれていますが、後からプログラムした描画処理も再描画する
必要があります。この手っ取り早いやり方が Paint イベントです。つまり初心者は、画面に描画する処理で
Paint イベント以外は使ったらNGだと思って下さい。
> Private Sub SenKaki_1()
> Me.CreateGraphics.DrawLine(penR, 90, 170, 420, 170)
> End Sub
これもNG。
Paint イベントの引数(e.Graphics)を使いまわす場合は、裏の処理が後始末してくれるので問題ありませんが、
自分で CreateGraphics するとリソース(メモリ)の確保が行われます。
その場合、解放処理まで自分で書く必要があります。画像系のプログラムはメモリを食うので、
繰り返すと目に見える形でメモリリークが起こる場合があります。
https://dobon.net/vb/dotnet/graphics/drawline.html
>'リソースを解放する
>g.Dispose()
の処理が必要です。
penR も使いまわすのは良いですが、フォームの Dispose イベントで解放するのを覚えたほうが良い場面となります。
penR.Dispose() を呼ぶ必要があります。
投稿者 とくま  (社会人)
投稿日時
2025/5/26 09:45:58
Public Class Form1
'フォームが生きている限り使いまわす
Private penR As Pen
Private penG As Pen
Private penB As Pen
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'初期処理
penR = New Pen(Color.Red, 2)
penG = New Pen(Color.Green, 2)
penB = New Pen(Color.Blue, 2)
End Sub
'TabPage の Paint イベント
Private Sub TabPage1_Paint(sender As Object, e As PaintEventArgs) Handles TabPage1.Paint
'システムが裏で作成した e を利用
e.Graphics.DrawLine(penR, 10, 120, 50, 220)
'オリジナル処理(自分で描画オブジェクト確保)
SenKaki_1()
End Sub
'オリジナル処理は関数内でリソースも解放しておく
Private Sub SenKaki_1()
'TabPage1のGraphicsオブジェクトを作成
Dim g As Graphics = TabPage1.CreateGraphics()
'画像を描画
g.DrawLine(penB, 60, 10, 20, 30)
'Graphics破棄(メモリ解放)
g.Dispose()
End Sub
Private Sub Form1_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
'ペンの破棄(メモリ解放)
penR.Dispose()
penG.Dispose()
penB.Dispose()
End Sub
End Class
投稿者 KOZ  (社会人)
投稿日時
2025/5/26 18:54:57
> 他のウィンドウ(メモ帳とか)をフォームの上に重ねた後に取り除いても消えると思います。
XP 以前は消えてたんですが、「Desktop Window Manager(DWM)」が Vista で導入されてから消えなくなってますよ。
各ウインドウはオフスクリーンバッファ(バックバッファ)に描画され、最終的にGPUで合成されるようになりました。
重なったウインドウが移動しても DWMがキャッシュした内容を使って表示するので消えません。
XP 以前は消えてたんですが、「Desktop Window Manager(DWM)」が Vista で導入されてから消えなくなってますよ。
各ウインドウはオフスクリーンバッファ(バックバッファ)に描画され、最終的にGPUで合成されるようになりました。
重なったウインドウが移動しても DWMがキャッシュした内容を使って表示するので消えません。
投稿者 hige3  (社会人)
投稿日時
2025/5/27 07:45:12
KOZ様
TabPage に描画する事は出来ました。
問題は、ご指摘通りでTabPageを移動すると消えてしまう事です。
解決策を下記で勉強中でしたが理解力不足で(泣)
初級講座 第2回 絵を書く
http://rucio.o.oo7.jp/main/dotnet/shokyu/standard2.htm
とくま様
>ディスプレイ上では、常に再描画が行われていることを覚えてください。
下記で確認、ビックリポンでした。
Private Sub TabPage1_Paint(sender As Object, e As PaintEventArgs) Handles TabPage1.Paint
MessageBox.Show(" TabPage1_Paint ", "確認", MessageBoxButtons.OK)
End Sub
>つまり初心者は、画面に描画する処理でPaint イベント以外は使ったらNGだと思って下さい。
承知致しました。
勉強不足、理解力不足を痛感しております。
お二方、御教授を有り難う御座いました。
今後ともよろしくお願い致します。
TabPage に描画する事は出来ました。
問題は、ご指摘通りでTabPageを移動すると消えてしまう事です。
解決策を下記で勉強中でしたが理解力不足で(泣)
初級講座 第2回 絵を書く
http://rucio.o.oo7.jp/main/dotnet/shokyu/standard2.htm
とくま様
>ディスプレイ上では、常に再描画が行われていることを覚えてください。
下記で確認、ビックリポンでした。
Private Sub TabPage1_Paint(sender As Object, e As PaintEventArgs) Handles TabPage1.Paint
MessageBox.Show(" TabPage1_Paint ", "確認", MessageBoxButtons.OK)
End Sub
>つまり初心者は、画面に描画する処理でPaint イベント以外は使ったらNGだと思って下さい。
承知致しました。
勉強不足、理解力不足を痛感しております。
お二方、御教授を有り難う御座いました。
今後ともよろしくお願い致します。
Formに TabControl で TabPage を作成します。
そのTabPage に線を描画する方法をお知らせ下さい。
ToolBox に Line がないんですね。
ご教授、宜しくお願い致します。