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 がないんですね。
ご教授、宜しくお願い致します。