VBのコード記述作法に自身がなく不安です。
CADのラバーラインのような感じです。
PictureBoxを置いてFormの上下左右にアンカーしてるだけです。
lineモードにXorがないので下記のようにしました。
今は、とりあえず動いてますが、<?>印部分をここに記述しても安定動作しますか?
(メモリの無駄使いとか・CPUの負荷とか)
又Form1_Resizeで再描画してますが、Windowを最小化すると当然でしょうが
PictureBox1.Image = New Bitmap(PictureBox1.Width, PictureBox1.Height)
でエラーになります。
これを防ぐ方法を教えて下さい。
Public Class Form1
Private sx, sy, ex, ey As Integer
Private flg As Boolean = False
Private fg, bg As Graphics '----<?>----
Private d(100, 4) As Integer
Private po As Integer = 1
'--------------------------------
Private Sub PictureBox1_MouseDown(~~
If flg = False Then
sx = e.X
sy = e.Y
ex = sx
ey = sy
flg = True
fg = PictureBox1.CreateGraphics() '----<?>----
Else
flg = False
ex = e.X
ey = e.Y
PictureBox1.Refresh()
fg.Dispose() '----<?>----
bg = Graphics.FromImage(PictureBox1.Image) '----<?>----
bg.DrawLine(Pens.Black, sx, sy, ex, ey)
bg.Dispose() '----<?>----
PictureBox1.Refresh()
d(po, 1) = sx
d(po, 2) = sy
d(po, 3) = ex
d(po, 4) = ey
po = po + 1
End If
End Sub
'--------------------------------
Private Sub PictureBox1_MouseMove(~~
If flg = True Then
PictureBox1.Refresh()
fg.DrawLine(Pens.Blue, sx, sy, e.X, e.Y)
ex = e.X
ey = e.Y
End If
End Sub
'--------------------------------
Private Sub Form1_Resize(~~
Dim x As Integer
PictureBox1.Image = New Bitmap(PictureBox1.Width, PictureBox1.Height)
bg = Graphics.FromImage(PictureBox1.Image) ' ----<?>----
For x = 1 To po - 1
bg.DrawLine(Pens.Black, d(x, 1), d(x, 2), d(x, 3), d(x, 4))
Next
bg.Dispose() ' ----<?>----
End Sub
'--------------------------------
End Class
No.2ベストアンサー
- 回答日時:
gはペイントイベントの引数のプロパティを使っているのでDisposeする必要はありませんよ
コレは Framework側で管理してますのでユーザー側でDisposeしてしまうとおかしくなってしまいます
Disposeするのはユーザーが作成したオブジェクトと考えればほぼ間違えないでしょう
またオブジェクトが10000とかあるのでしたら描画のしなおしに対し自分自身が描画対象なのか判定する必要が出てくるでしょう
今は Invalidateで無条件に コントロール全体を無効にしています
描画しなおしたい範囲を指定することも可能ですので無効化を
Invalidate(New Rectangle( sx, sy, abs(ex-sx), abs( ey-sy )) )
といった具合にします
描画ルーチンで
dim rc,rcPaint as Rectangle
rcPaint = e.ClipRectangle
For x=1 to po -1
rc = new Rectangle( d(x,1), d(x,2), abs(d(x,3) - d(x,1)), abs(d(x,4) - d(x,2))
' 交差部分があるかチェック
if rc.IntersectsWith( rcPaint ) then
g.DrawLine( Pens.Black, d(x,1) ,d(x,2), d(x,3), d(x,4) )
end if
next
といった具合にしてみてはいかがでしょう ・・・
この回答への補足
Dispose そうだったんですか。
よくサンプル等でDispose記述があったので書くものだと思ってました。
IntersectsWith これはクリッピングということですね。
「abs」関数がなく、math.absでとうりました。
CPUの使用率を監視すると、負荷が軽減されているような気がします。
でも、PictureBoxを大きくしたり小さくしたりすると、線描画が部分的に欠けたりします。
何か解決法がありましたらご教授お願いできれば幸です。
No.1
- 回答日時:
fg,bgは要らないかも知れないですよ ・・・
線の描画をPaintイベントに任せてしまう
Private PictureBox1_Paint( ... )
dim g as Graphics = e.Graphics
' 記憶した線を描画
for n as integer = 1 to po-1
g.DrawLine( Pens.Black, d(x,1),d(x,2),d(x,3),d(x,4))
next
if sx<>ex and sy<>ey then
' 現在の線を描画
g.DrawLine( Pens.Blue, sx, sy, ex, ey )
end if
End Sub
Private sub PictureBox1_MouseDown( ... )
if flg = false then
' 始点を設定
sx = e.X : sy = e.Y
ex = sx : ey = sy
flag = true
else
' 線を登録
d(po,1) = sx : d(po,2) = sy
d(po,2) = e.X : d(po,4) = e.Y
' 現在の線の始点=終点に設定
sx = ex : sy = ey
flg = false
' ピクチャーボックス再描画
PictureBox1.Invalidate()
end if
End Sub
Private sub PictureBox1_MouseMove( ... )
if flg then
' 現在のマウス位置を終点に設定
ex = e.X : ey = e.Y
' ピクチャーボックス再描画
PictureBox1.Invalidate()
end if
End Sub
こんな感じで 上手くいくと思いますよ
この処理だけなら Form1_Resizeは必要ないように思います
この回答への補足
ご指導頂いたコードに2,3の訂正を加え(d(po,3) = e.Xとか)実行しました。
windowを最小化しても大丈夫でした。
For Next文の初期値に As integer を入れれるなんて知りませんでした。
さらに質問ですが、このコードだと青い線を描画し直すたびに、記憶した線も全て描画し直しているのですか?
仮に記憶した線が10000本あったら・・・・
古いPCだったらCPUの負担は大きくなりませんか?
それと、gはどこでDisposeしたらよいのでしょうか?
しなくてもいいのかな?
まだまだVBのマナーを知らなくて、よろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) Visual Basic : ImageListの画像がそろったときにメッセージを表示 1 2023/07/20 13:53
- Visual Basic(VBA) 【VBA】写真の貼り付けコードがうまく機能しません。 5 2022/09/01 18:43
- Visual Basic(VBA) VBAで質問ですが、皆さんはどの様に導き出しているのでしょうか? 6 2022/05/03 21:53
- Visual Basic(VBA) いつもお世話になっております、VBAで教えて頂きたいのですが 2 2022/05/05 22:20
- Excel(エクセル) エクセルVBAでオブジェクトが必要です 2 2022/09/10 16:37
- Visual Basic(VBA) 【Excel VBA】自動メール送信の機能追加 5 2022/09/29 12:53
- Visual Basic(VBA) VBAプログラミング 2 2022/11/27 12:07
- Visual Basic(VBA) ①ExcelVBAでカレンダーを作り、別のユザーフォームで日付を入力したいのですがエラーになります。 1 2023/02/17 18:39
- Visual Basic(VBA) Excel vbaについての質問 3 2023/04/18 16:14
- Excel(エクセル) エクセルで同じ数字同士を自動で線で結ぶVBAを教えてください 6 2022/04/26 23:13
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
win32api複数のタイマーを同時...
-
scilabでのグラフ描画時の軸設定
-
C#で壁の当たり判定と自キャラ...
-
ビットマップに描画をしてピク...
-
給紙トレイをダイアログを使わ...
-
C#を用いて描画する四角形の角...
-
画面に絵を出す方法
-
ListBoxで改行したい
-
VB2010にて、プロットエリア...
-
線の描画速度
-
ポリゴン 球体を三角形パッチ...
-
VC++2010 MFC EDIT に格子
-
worksheetFunctionクラスのVloo...
-
VBA シートのボタン名を変更し...
-
ユーザーフォームを表示中にシ...
-
【C#/Java?】try-catchでcatch...
-
エクセルエラー13型が一致しま...
-
ExcelVBAのユーザーフォームの...
-
「Columns("A:C")」の列文字を...
-
VBA(エクセル)で自動的にボタン...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ListBoxで改行したい
-
for文の実行速度を遅くしたいの...
-
Word 描画オブジェクトを削除...
-
C#を用いて描画する四角形の角...
-
ビットマップに描画をしてピク...
-
PowerPoint の VBA
-
給紙トレイをダイアログを使わ...
-
win32api複数のタイマーを同時...
-
画面に絵を出す方法
-
MFCでのコンボボックスについて
-
.NETのPictureBoxでウインドウ...
-
scilabでのグラフ描画時の軸設定
-
Excel VBA:コントロールボタン...
-
VC;;6.0のMFCで線を簡単に引け...
-
花火のアルゴリズム
-
VB.NETでグラフィックを描くと...
-
水平線の描画
-
Excel 2007で、フリーフォーム描画
-
C# DrawImage 物理サイズでな...
-
円の頂点の求め方を知りたいです。
おすすめ情報