質問者
オブジェクト参照がオブジェクト インスタンスに設定されていません。への対応 in vb.net

質問
-
vb.netで自作のトレインビジョンを作成しています。1つのCSVファイルから統合した2つのプロジェクトを動かすプログラムを作成しているのですが、下から193行目のg.DrawString(m, fnt, Brushes.Black, pointer, 110, stfom)で「オブジェクト参照がオブジェクト インスタンスに設定されていません。」というエラーが出てしまい困っています。どう対処すればいいのかを教えてください。(エラーが出た部分は太字で表示させてあります)急いでいますのでコードを提示しつつお願いします。
問題のvb.netのコード
Imports System.Drawing '図形や線を描画できる基本的なグラフィックス機能を追加
Imports System.Drawing.Drawing2D '上記コードの2 次元高度な機能Public Class Form1
Private con()() As Control
Private change As Integer
Dim canvas As Bitmap 'canvas を画像とその属性のピクセルデータを扱うクラスBitmapで宣言する
Dim g As Graphics 'g を描画クラスGraphicsで宣言する
Dim colower As Brush = Brushes.Red 'colowerを四角形、楕円、扇形、多角形を塗りつぶすクラスBrushで宣言して同時に塗りつぶしておく最初の色を赤に設定する
Dim fnt As Font 'fntをテキストの特定の書式を定義するクラスFontで宣言する。
Dim line As Integer = 4 'cを整数型Integerで宣言してそれと同時に4を代入する
Public ix1 As Long = 0 'ローカル変数ixをintの倍の8バイトに当たるlong型で宣言をしてそれと同時に0を代入する。
Public ix2 As Long = 0
Public ix3 As Long = 0
Public msg1() As String = {"다음 것", "次は", "つぎは", "Next", "下一个"} 'ローカル変数msgを文字列型の配列入りで宣言をしてそれと同時に表示させたい文字列を代入する。
Public msg2() As String = {"에대한", "行き", "ゆき", "for", "为"}
Public msg3() As String = {"자동차", "号車", "Cars", "汽车"}
Dim scloltext As String
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
con = New Control()() {
New Control() {TextBox5},
New Control() {PictureBox1}}
change = 0
For m As Integer = 0 To con.Length - 1
con(m).ToList().ForEach(Sub(x) x.Visible = False)
If m = change Then con(change).ToList().ForEach(Sub(x) x.Visible = True)Next
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim objFile1 As New System.IO.StreamReader("Z:\traindata\東海道・山陽新幹線.csv", System.Text.Encoding.GetEncoding("shift_jis"))
'ファイルを指定して読み込むためのオブジェクト
Dim strLine1 As String 'ファイルから読み取った全駅名の文字列を格納する
Dim strTemp1() As String 'strLine1からデータを受け取り、配列にする
Dim strData1 As String 'strTemp1の配列したデータを受け取る
Dim Lineno1 As Integer 'CSVファイルから読み込みたい列の値を格納する
Dim linesta As Integer 'aを整数型で宣言をしてそれと同時にstrTempの配列を指定して、文字の最大値を返す。
Dim objFile2 As New System.IO.StreamReader("Z:\traindata\種別等.csv", System.Text.Encoding.GetEncoding("shift_jis"))
'ファイルを指定して読み込むためのオブジェクト
Dim strLine2 As String 'ファイルから読み取った全駅名の文字列を格納する
Dim strTemp2() As String 'strLine2からデータを受け取り、配列にする
Dim strData2 As String 'strTemp2の配列したデータを受け取る
Dim Lineno2 As Integer 'CSVファイルから読み込みたい列の値を格納する
Dim station1 As Integer 'CSVファイルから読み込みたい複数の行の値を格納する
Dim stationlist As String 'strTemp2とstationのファイルから読み込んだ文字列を受け取
Lineno1 = 1 'CSVファイルから読み込みたい列を指定する
strLine1 = objFile1.ReadLine() 'objFile1に1行分の文字を読み込んで配列にして、strLine1に格納する
While (strLine1 <> "") 'strlineが空白""と等しくない限り処理を続ける
strTemp1 = Split(strLine1, ",") 'strLine1とカンマで区切られたファイルの文字列から配列を作成してstrtemp1に格納する
For intCnt = 0 To UBound(strTemp1) 'カウンタintcatが0からstrtemp1の添字の最大値以下(csvファイルに入力された終着駅の行番号)である間,処理を繰り返し行う
strData1 = strData1 + strTemp1(intCnt) 'strData1にstrTemp1の配列カウンタintcatとstrData1を足して代入する
Next
If Lineno1 = 2 Then 'Lineno1に格納したCSVファイル内の空白を除いた文字列から2列目を指定して読み込む
TextBox1.Text = strTemp1(0) '列に続いて文字列から行の番号を指定してその内容の文字をテキストボックスやラベルに入れる(種別を示すTextBox1の内容)
TextBox2.Text = strTemp1(2) '(行き先を示すTextBox2の内容)
Label1.Text = strTemp1(1) '(列車番号を示すLabel1の内容)
ElseIf Lineno1 = 1 Then 'Lineno1に1行目の列を指定して読み込む
TextBox3.Text = strTemp1(8) '(次駅を示すTextBox3の内容)
ElseIf Lineno1 = 65 Then 'Lineno1にCSVファイル上の65行目(この場合、のぞみ2号東京行きの6:08分)の列を指定して読み込む。
Label5.Text = strTemp1(8) '(時刻を示すLabel5の内容)End If
' csvファイルを閉じる
strLine1 = objFile1.ReadLine() 'objFileを読み込んで配列にしてstrLineに格納する
Lineno1 = Lineno1 + 1 ' Lineno と 1を足してLinenoに代入するEnd While
strLine2 = objFile2.ReadLine() 'objFile2に1行分の文字を読み込んで、strLine2に格納する
While (strLine2 <> "") 'strline2が空白""と等しくない限り処理を続ける
strTemp2 = Split(strLine2, ",") 'strLine2とカンマで区切られたファイルの文字列から配列を作成してstrtemp2に格納する
For intCnt = 0 To UBound(strTemp2) 'カウンタintcatが0からstrtemp2の添字の最大値以下である間,処理を繰り返し行う
strData2 = strData2 + strTemp2(intCnt) 'strData2にstrTemp1の配列カウンタintcatとstrData2を足して代入する
Next
If Lineno2 = 2 Then 'Lineno2に格納したCSVファイル内の空白を除いた文字列から2列目を指定して読み込む
TextBox4.Text = strTemp2(0) '列に続いて文字列から行の番号を指定してその内容の文字をテキストボックスやラベルに入れる(号車を示すTextBox4の内容)ElseIf Lineno2 = 1 Then 'Lineno2に格納したCSVファイル内の空白を除いた文字列から1列目を指定して読み込む
stationlist = "" ' stationlistの文字列をリセットして空欄にする
For station1 = 4 To 38 '複数の駅名の行を指定してstationに格納する
stationlist = stationlist + strTemp2(station1) 'stationに格納されている指定された駅名の文字列をstationlistで呼び出す。
Nextstationlist = "停車駅は" + stationlist + "です" '呼び出された駅名の文字列を文章にして表示させる。
TextBox5.Text = stationlist 'TextBox5にstationlistを代入するEnd If
If Lineno2 = 4 Then 'Linenoに4を代入するExit While
End If
strLine2 = objFile2.ReadLine() 'strLine2にobjFile2の配列を読み込む
Lineno2 = Lineno2 + 1 'Lineno2にLineno2と1を足して代入する
End Whilelinesta = UBound(strTemp2)
fnt = New Font("MS UI Gothic", 20) 'テキストの特定の書式を設定できるクラスFontを初期化して文字スタイルをMS UI Gothicに、大きさを20に設定してfnt に格納する。
station2(strTemp2(line), -110) 'stationに配列strTempに配列c, と座標-110を配列にして挿入する
If line + 1 <= linesta Then 'aはc+1より大きければ上記と同じ配列strTempに配列c+1, と座標0をstationに挿入して1つ目の駅名を出す。以降iに足す数字を1増やしながら処理をする。
station2(strTemp2(line + 1), 0) '2つ目の駅名を出す。
End If
If line + 2 <= linesta Then
station2(strTemp2(line + 2), 100) '3つ目の駅名を出す。
End If
If line + 3 <= linesta Then
station2(strTemp2(line + 3), 200) '4つ目の駅名を出す。
End If
If line + 4 <= linesta Then
station2(strTemp2(line + 4), 300) '5つ目の駅名を出す。
End If
If line + 5 <= linesta Then
station2(strTemp2(line + 5), 400) '6つ目の駅名を出す。
End If
If line < linesta Then 'aはc以上に大きければcと1を足してcに代入して駅名をボタンを押すごとにずらす
line = line + 1
End Ifix1 = ix1 + 1
If ix1 > UBound(msg1) Then
ix1 = 0
End If
Label2.Text = msg1(ix1)ix2 = ix2 + 1
If ix2 > UBound(msg2) Then
ix2 = 0
End If
Label4.Text = msg2(ix2)ix3 = ix3 + 1
If ix3 > UBound(msg3) Then
ix3 = 0
End If
Label3.Text = msg3(ix3)change += 1
change = IIf(change = con.Length, 0, change)
For m As Integer = 0 To con.Length - 1con(m).ToList().ForEach(Sub(x) x.Visible = False)
If m = change Then con(change).ToList().ForEach(Sub(x) x.Visible = True)
NextobjFile1.Close() 'ファイルを閉じる
objFile2.Close() 'ファイルを閉じる
Timer1.Interval = 5 'タイマーの時間を設定する
Timer1.Start() 'タイマーを開始するEnd Sub
Private Sub station2(stationname As String, pointer As Integer) 'stationイベントを作成して、横の括弧の中にstationnameは文字列型で、pointerは整数型で宣言をして文字を書くところとそれを表示する場所を作る。Dim n As Integer = stationname.Length 'n を整数型で宣言をしてそれと同時に文字数属性のstationnameを代入する。
Dim m As String = "" 'm を文字列型で宣言をしてそれと同時に空白を代入する。
For i = 0 To n - 1 'i が 0 からn – 1の間で繰り返し処理を行う
m = m & stationname.Substring(i, 1) 'mにmと駅名とi文字目を追加する。
Next
Dim stfom As New StringFormat() 'stfomを文字列の書式を設定する方法を指定できるオブジェクトStringFormatで宣言をして配列を初期化する
stfom.FormatFlags = StringFormatFlags.DirectionVertical 'テキスト文字列を縦方向位置合わせして、stfomに書式情報を格納する
fnt = New Font("MS UI Gothic", 20) 'テキストの特定の書式を設定できるクラスFontを初期化して文字スタイルをMS UI Gothicに、大きさを20に設定してfnt に格納する。
g.DrawString(m, fnt, Brushes.Black, pointer, 110, stfom) 'g に宣言しておいたmとfnt、 pointer、 stfomそして 、描画する色を黒にして座標を110に設定して文字列を描画するEnd Sub
Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
'ファイルを指定して読み込むためのオブジェクト
canvas = New Bitmap(PictureBox1.Width, PictureBox1.Height) 'canvas に初期化して高さと幅を設定したピクチャーボックスを格納する。
g = Graphics.FromImage(canvas) 'canvas配列化して、クラスのGraphicsに画像や図形を指定してgに格納する。
g.FillRectangle(Brushes.Orange, 10, 20, 700, 80) '座標を決めて塗りつぶしたオレンジ色の長方形を描画する(塗りたい色,x座標,y座標,幅,高さ)
g.FillEllipse(Brushes.White, 70, 25, 70, 70) '座標をそれぞれ決めて塗りつぶした白い円を6個描画する
g.FillEllipse(Brushes.White, 170, 25, 70, 70)
g.FillEllipse(Brushes.White, 270, 25, 70, 70)
g.FillEllipse(Brushes.White, 370, 25, 70, 70)
g.FillEllipse(Brushes.White, 470, 25, 70, 70)
g.FillEllipse(Brushes.White, 570, 25, 70, 70)
Dim points As Point() = {New Point(710, 100), '三角形を描画する座標を決める
New Point(710, 20),
New Point(790, 60)}
'多角形を描画する
g.FillPolygon(Brushes.Orange, points, FillMode.Alternate) '塗りつぶす色をオレンジに設定する
g.TranslateTransform(190, 0) 'gに座標を 190, 0に指定してオブジェクトを変換する。
' Dim point As Point() = {New Point(-180, 100),
' New Point(-180, 20),
'New Point(-130, 60)}
'多角形を描画する
PictureBox1.Image = canvas 'ピクチャーボックスにcanvasを代入する。
Timer2.Interval = 500 'タイマーの時間を設定する
Timer2.Start() 'タイマーを開始する
End SubPrivate Sub Timer1_Tick(ByVal sender As Object, e As EventArgs) Handles Timer1.Tick
Dim objG As Graphics '描画した文字列を格納する
objG = TextBox5.CreateGraphics() 'textbox5に画像を挿入する
objG.Clear(TextBox5.BackColor) 'objGの描画サーフェイス全体をリセットしてtextbox5の背景色で塗りつぶす
objG.DrawString(TextBox5.Text, TextBox5.Font, New SolidBrush(TextBox5.ForeColor), scloltext, 0) 'textbox5に描画する文字列やフォントや色えお設定する
scloltext -= 1 '文字列が移動する方向を決める
If scloltext > TextBox5.Width Then 'scloltextがtextboxの幅よりも大きい場合以下の処理を実行する
scloltext = 0 'scloltextに0を代入する
End If
objG.Dispose() 'objGを開放する
End Sub
Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
g.TranslateTransform(0, 0) 'gに0, 0を座標にオブジェクトを変換する
Dim points As Point() = {New Point(-180, 100), '三角形を描画する
New Point(-180, 20),
New Point(-130, 60)}
g.FillPolygon(colower, points, FillMode.Alternate) 'gにcolowerを挿入して、閉じたパスの内部を塗りつぶす方法を指定できる列挙型FillModeとそのメンバーで代替の塗りつぶしモードを指定できるAlternateをそれぞれ挿入する。
If colower.Equals(Brushes.Red) Then '今の色が指定した色と等しい場合は違う色に変えるという処理を行う
colower = Brushes.Yellow '等しい場合に塗りつぶす色を黄色に変更
Else
colower = Brushes.Red 'そうでない場合は塗りつぶす色を黄色に変更
End If
Me.Refresh() 'コードが実行されているクラスまたは構造体のクライアント領域を強制的に無効化し、直後にそのコントロール自体とその子コントロールを再描画するようにして配列にする.
End Sub
End Class- 編集済み dumbo1028 2017年12月1日 1:28
すべての返信
-
C# のフォーラムに投稿されてますが、それは間違いで、VB.NET ですよね?
例外の原因は g が null(VB.NET では Nothing)になっているからであろうと思いますが、長いコードをベタっと貼られてその中から g が null になる原因、対処方法を見つけてくれというのは、ちょっと期待しすぎかと。
問題を再現できる必要最低限までコードをどんどん削っていくなどして、切り分けしていただけませんか。その過程で原因が分かって自己解決できるかもしれません。自己解決できなくても、必要最低限まで削ったコードをアップしてもらえれば、詳しく見てくれる人も増えて回答が得やすくなると思います。
ところで、質問者さんが先に立てたスレッドが放置状態です。
「インデックスが配列の境界外です。」の対処法
https://social.msdn.microsoft.com/Forums/sqlserver/ja-JP/0a2cf69f-73cd-4d51-a1d3-441503e8c226?forum=vbgeneralja一つもレスが付かないということならともかく、レスをもらっているなら放置はマナー違反です。きちんと対応してください。
- 編集済み SurferOnWww 2017年11月27日 6:08 追記
-
SurferOnWwwさんが仰られている通り、gがnullになっていることが原因だと思います。
> 「オブジェクト参照がオブジェクト インスタンスに設定されていません。」
上記メッセージからSystem.NullReferenceExceptionが発生していることがわかります。
該当行でブレークし、各値を確認すれば原因についてはすぐにわかるかと思います。
> どう対処すればよいか教えてください
どのように呼ばれても意図したGraphicオブジェトを参照出来るように修正してください。
以下、余計なお世話ですが。。。
ご質問者様の二つの質問どちらも、エラーが発生して困っていますとなっていますが、
単純なエラーですので、調べればすぐに原因は特定出来るものと思います。
今後もプログラムをされていくのであれば、すぐにフォーラムで質問するのではなく、
ご自身で解決する方法も学ばれたほうがよいと思います。
- 編集済み uemu 2017年11月27日 6:24
-
0
vb.netで自作のトレインビジョンを作成しています。1つのCSVファイルから統合した2つのプロジェクトを動かすプログラムを作成しているのですが、下から193行目のg.DrawString(m, fnt, Brushes.Black, pointer, 110, stfom)で「オブジェクト参照がオブジェクト インスタンスに設定されていません。」というエラーが出てしまい困っています。どう対処すればいいのかを教えてください。(エラーが出た部分は太字で表示させてあります)急いでいますのでコードを提示しつつお願いします。
問題のvb.netのコード
Imports System.Drawing '図形や線を描画できる基本的なグラフィックス機能を追加
Imports System.Drawing.Drawing2D '上記コードの2 次元高度な機能Public Class Form1
Private con()() As Control
Private change As Integer
Dim canvas As Bitmap 'canvas を画像とその属性のピクセルデータを扱うクラスBitmapで宣言する
Dim g As Graphics 'g を描画クラスGraphicsで宣言する
Dim colower As Brush = Brushes.Red 'colowerを四角形、楕円、扇形、多角形を塗りつぶすクラスBrushで宣言して同時に塗りつぶしておく最初の色を赤に設定する
Dim fnt As Font 'fntをテキストの特定の書式を定義するクラスFontで宣言する。
Dim line As Integer = 4 'cを整数型Integerで宣言してそれと同時に4を代入する
Public ix1 As Long = 0 'ローカル変数ixをintの倍の8バイトに当たるlong型で宣言をしてそれと同時に0を代入する。
Public ix2 As Long = 0
Public ix3 As Long = 0
Public msg1() As String = {"다음 것", "次は", "つぎは", "Next", "下一个"} 'ローカル変数msgを文字列型の配列入りで宣言をしてそれと同時に表示させたい文字列を代入する。
Public msg2() As String = {"에대한", "行き", "ゆき", "for", "为"}
Public msg3() As String = {"자동차", "号車", "Cars", "汽车"}
Dim scloltext As String
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
con = New Control()() {
New Control() {TextBox5},
New Control() {PictureBox1}}
change = 0
For m As Integer = 0 To con.Length - 1
con(m).ToList().ForEach(Sub(x) x.Visible = False)
If m = change Then con(change).ToList().ForEach(Sub(x) x.Visible = True)Next
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim objFile1 As New System.IO.StreamReader("Z:\traindata\東海道・山陽新幹線.csv", System.Text.Encoding.GetEncoding("shift_jis"))
'ファイルを指定して読み込むためのオブジェクト
Dim strLine1 As String 'ファイルから読み取った全駅名の文字列を格納する
Dim strTemp1() As String 'strLine1からデータを受け取り、配列にする
Dim strData1 As String 'strTemp1の配列したデータを受け取る
Dim Lineno1 As Integer 'CSVファイルから読み込みたい列の値を格納する
Dim linesta As Integer 'aを整数型で宣言をしてそれと同時にstrTempの配列を指定して、文字の最大値を返す。
Dim objFile2 As New System.IO.StreamReader("Z:\traindata\種別等.csv", System.Text.Encoding.GetEncoding("shift_jis"))
'ファイルを指定して読み込むためのオブジェクト
Dim strLine2 As String 'ファイルから読み取った全駅名の文字列を格納する
Dim strTemp2() As String 'strLine2からデータを受け取り、配列にする
Dim strData2 As String 'strTemp2の配列したデータを受け取る
Dim Lineno2 As Integer 'CSVファイルから読み込みたい列の値を格納する
Dim station1 As Integer 'CSVファイルから読み込みたい複数の行の値を格納する
Dim stationlist As String 'strTemp2とstationのファイルから読み込んだ文字列を受け取
Lineno1 = 1 'CSVファイルから読み込みたい列を指定する
strLine1 = objFile1.ReadLine() 'objFile1に1行分の文字を読み込んで配列にして、strLine1に格納する
While (strLine1 <> "") 'strlineが空白""と等しくない限り処理を続ける
strTemp1 = Split(strLine1, ",") 'strLine1とカンマで区切られたファイルの文字列から配列を作成してstrtemp1に格納する
For intCnt = 0 To UBound(strTemp1) 'カウンタintcatが0からstrtemp1の添字の最大値以下(csvファイルに入力された終着駅の行番号)である間,処理を繰り返し行う
strData1 = strData1 + strTemp1(intCnt) 'strData1にstrTemp1の配列カウンタintcatとstrData1を足して代入する
Next
If Lineno1 = 2 Then 'Lineno1に格納したCSVファイル内の空白を除いた文字列から2列目を指定して読み込む
TextBox1.Text = strTemp1(0) '列に続いて文字列から行の番号を指定してその内容の文字をテキストボックスやラベルに入れる(種別を示すTextBox1の内容)
TextBox2.Text = strTemp1(2) '(行き先を示すTextBox2の内容)
Label1.Text = strTemp1(1) '(列車番号を示すLabel1の内容)
ElseIf Lineno1 = 1 Then 'Lineno1に1行目の列を指定して読み込む
TextBox3.Text = strTemp1(8) '(次駅を示すTextBox3の内容)
ElseIf Lineno1 = 65 Then 'Lineno1にCSVファイル上の65行目(この場合、のぞみ2号東京行きの6:08分)の列を指定して読み込む。
Label5.Text = strTemp1(8) '(時刻を示すLabel5の内容)End If
' csvファイルを閉じる
strLine1 = objFile1.ReadLine() 'objFileを読み込んで配列にしてstrLineに格納する
Lineno1 = Lineno1 + 1 ' Lineno と 1を足してLinenoに代入するEnd While
strLine2 = objFile2.ReadLine() 'objFile2に1行分の文字を読み込んで、strLine2に格納する
While (strLine2 <> "") 'strline2が空白""と等しくない限り処理を続ける
strTemp2 = Split(strLine2, ",") 'strLine2とカンマで区切られたファイルの文字列から配列を作成してstrtemp2に格納する
For intCnt = 0 To UBound(strTemp2) 'カウンタintcatが0からstrtemp2の添字の最大値以下である間,処理を繰り返し行う
strData2 = strData2 + strTemp2(intCnt) 'strData2にstrTemp1の配列カウンタintcatとstrData2を足して代入する
Next
If Lineno2 = 2 Then 'Lineno2に格納したCSVファイル内の空白を除いた文字列から2列目を指定して読み込む
TextBox4.Text = strTemp2(0) '列に続いて文字列から行の番号を指定してその内容の文字をテキストボックスやラベルに入れる(号車を示すTextBox4の内容)ElseIf Lineno2 = 1 Then 'Lineno2に格納したCSVファイル内の空白を除いた文字列から1列目を指定して読み込む
stationlist = "" ' stationlistの文字列をリセットして空欄にする
For station1 = 4 To 38 '複数の駅名の行を指定してstationに格納する
stationlist = stationlist + strTemp2(station1) 'stationに格納されている指定された駅名の文字列をstationlistで呼び出す。
Nextstationlist = "停車駅は" + stationlist + "です" '呼び出された駅名の文字列を文章にして表示させる。
TextBox5.Text = stationlist 'TextBox5にstationlistを代入するEnd If
If Lineno2 = 4 Then 'Linenoに4を代入するExit While
End If
strLine2 = objFile2.ReadLine() 'strLine2にobjFile2の配列を読み込む
Lineno2 = Lineno2 + 1 'Lineno2にLineno2と1を足して代入する
End Whilelinesta = UBound(strTemp2)
fnt = New Font("MS UI Gothic", 20) 'テキストの特定の書式を設定できるクラスFontを初期化して文字スタイルをMS UI Gothicに、大きさを20に設定してfnt に格納する。
station2(strTemp2(line), -110) 'stationに配列strTempに配列c, と座標-110を配列にして挿入する
If line + 1 <= linesta Then 'aはc+1より大きければ上記と同じ配列strTempに配列c+1, と座標0をstationに挿入して1つ目の駅名を出す。以降iに足す数字を1増やしながら処理をする。
station2(strTemp2(line + 1), 0) '2つ目の駅名を出す。
End If
If line + 2 <= linesta Then
station2(strTemp2(line + 2), 100) '3つ目の駅名を出す。
End If
If line + 3 <= linesta Then
station2(strTemp2(line + 3), 200) '4つ目の駅名を出す。
End If
If line + 4 <= linesta Then
station2(strTemp2(line + 4), 300) '5つ目の駅名を出す。
End If
If line + 5 <= linesta Then
station2(strTemp2(line + 5), 400) '6つ目の駅名を出す。
End If
If line < linesta Then 'aはc以上に大きければcと1を足してcに代入して駅名をボタンを押すごとにずらす
line = line + 1
End Ifix1 = ix1 + 1
If ix1 > UBound(msg1) Then
ix1 = 0
End If
Label2.Text = msg1(ix1)ix2 = ix2 + 1
If ix2 > UBound(msg2) Then
ix2 = 0
End If
Label4.Text = msg2(ix2)ix3 = ix3 + 1
If ix3 > UBound(msg3) Then
ix3 = 0
End If
Label3.Text = msg3(ix3)change += 1
change = IIf(change = con.Length, 0, change)
For m As Integer = 0 To con.Length - 1con(m).ToList().ForEach(Sub(x) x.Visible = False)
If m = change Then con(change).ToList().ForEach(Sub(x) x.Visible = True)
NextobjFile1.Close() 'ファイルを閉じる
objFile2.Close() 'ファイルを閉じる
Timer1.Interval = 5 'タイマーの時間を設定する
Timer1.Start() 'タイマーを開始するEnd Sub
Private Sub station2(stationname As String, pointer As Integer) 'stationイベントを作成して、横の括弧の中にstationnameは文字列型で、pointerは整数型で宣言をして文字を書くところとそれを表示する場所を作る。Dim n As Integer = stationname.Length 'n を整数型で宣言をしてそれと同時に文字数属性のstationnameを代入する。
Dim m As String = "" 'm を文字列型で宣言をしてそれと同時に空白を代入する。
For i = 0 To n - 1 'i が 0 からn – 1の間で繰り返し処理を行う
m = m & stationname.Substring(i, 1) 'mにmと駅名とi文字目を追加する。
Next
Dim stfom As New StringFormat() 'stfomを文字列の書式を設定する方法を指定できるオブジェクトStringFormatで宣言をして配列を初期化する
stfom.FormatFlags = StringFormatFlags.DirectionVertical 'テキスト文字列を縦方向位置合わせして、stfomに書式情報を格納する
fnt = New Font("MS UI Gothic", 20) 'テキストの特定の書式を設定できるクラスFontを初期化して文字スタイルをMS UI Gothicに、大きさを20に設定してfnt に格納する。
g.DrawString(m, fnt, Brushes.Black, pointer, 110, stfom) 'g に宣言しておいたmとfnt、 pointer、 stfomそして 、描画する色を黒にして座標を110に設定して文字列を描画するEnd Sub
Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
'ファイルを指定して読み込むためのオブジェクト
canvas = New Bitmap(PictureBox1.Width, PictureBox1.Height) 'canvas に初期化して高さと幅を設定したピクチャーボックスを格納する。
g = Graphics.FromImage(canvas) 'canvas配列化して、クラスのGraphicsに画像や図形を指定してgに格納する。
g.FillRectangle(Brushes.Orange, 10, 20, 700, 80) '座標を決めて塗りつぶしたオレンジ色の長方形を描画する(塗りたい色,x座標,y座標,幅,高さ)
g.FillEllipse(Brushes.White, 70, 25, 70, 70) '座標をそれぞれ決めて塗りつぶした白い円を6個描画する
g.FillEllipse(Brushes.White, 170, 25, 70, 70)
g.FillEllipse(Brushes.White, 270, 25, 70, 70)
g.FillEllipse(Brushes.White, 370, 25, 70, 70)
g.FillEllipse(Brushes.White, 470, 25, 70, 70)
g.FillEllipse(Brushes.White, 570, 25, 70, 70)
Dim points As Point() = {New Point(710, 100), '三角形を描画する座標を決める
New Point(710, 20),
New Point(790, 60)}
'多角形を描画する
g.FillPolygon(Brushes.Orange, points, FillMode.Alternate) '塗りつぶす色をオレンジに設定する
g.TranslateTransform(190, 0) 'gに座標を 190, 0に指定してオブジェクトを変換する。
' Dim point As Point() = {New Point(-180, 100),
' New Point(-180, 20),
'New Point(-130, 60)}
'多角形を描画する
PictureBox1.Image = canvas 'ピクチャーボックスにcanvasを代入する。
Timer2.Interval = 500 'タイマーの時間を設定する
Timer2.Start() 'タイマーを開始する
End SubPrivate Sub Timer1_Tick(ByVal sender As Object, e As EventArgs) Handles Timer1.Tick
Dim objG As Graphics '描画した文字列を格納する
objG = TextBox5.CreateGraphics() 'textbox5に画像を挿入する
objG.Clear(TextBox5.BackColor) 'objGの描画サーフェイス全体をリセットしてtextbox5の背景色で塗りつぶす
objG.DrawString(TextBox5.Text, TextBox5.Font, New SolidBrush(TextBox5.ForeColor), scloltext, 0) 'textbox5に描画する文字列やフォントや色えお設定する
scloltext -= 1 '文字列が移動する方向を決める
If scloltext > TextBox5.Width Then 'scloltextがtextboxの幅よりも大きい場合以下の処理を実行する
scloltext = 0 'scloltextに0を代入する
End If
objG.Dispose() 'objGを開放する
End Sub
Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
g.TranslateTransform(0, 0) 'gに0, 0を座標にオブジェクトを変換する
Dim points As Point() = {New Point(-180, 100), '三角形を描画する
New Point(-180, 20),
New Point(-130, 60)}
g.FillPolygon(colower, points, FillMode.Alternate) 'gにcolowerを挿入して、閉じたパスの内部を塗りつぶす方法を指定できる列挙型FillModeとそのメンバーで代替の塗りつぶしモードを指定できるAlternateをそれぞれ挿入する。
If colower.Equals(Brushes.Red) Then '今の色が指定した色と等しい場合は違う色に変えるという処理を行う
colower = Brushes.Yellow '等しい場合に塗りつぶす色を黄色に変更
Else
colower = Brushes.Red 'そうでない場合は塗りつぶす色を黄色に変更
End If
Me.Refresh() 'コードが実行されているクラスまたは構造体のクライアント領域を強制的に無効化し、直後にそのコントロール自体とその子コントロールを再描画するようにして配列にする.
End Sub
End Class- 結合 立花楓Microsoft employee, Moderator 2017年12月4日 4:19 同一内容のスレッドのため
-
> どのインスタンスかを明らかにしてください。
元質問の
>> エラーが出た部分は太字で表示させてあります
>> g.DrawString(m, fnt, Brushes.Black, pointer, 110, stfom)
を見る限りでは、まず g がまずそうです。
g = Graphics.FromImage(canvas)
がセットされているのは、PictureBox1_Click にしかありません。
(1) PictureBox1_Click を実行する前に Button1_Click が呼ばれた場合の動作が考慮されていない。
(2) PictureBox1 をクリックした後で、再度クリックしなおした場合に、以前のインスタンスを Dispose することなく、変数 canvas や g をそのまま上書きしている。また、fnt も Dispose されていないようです。
ローカル変数ならば、Using ブロックを用いて確実に即時処分されるようにしましょう。
フィールド変数にするなら、Form が閉じられた後(たとえば FormClosed など)に Dispose を書きましょう。
これがメインフォームであるというのなら、FormClosed 等に処分コードを書かずともアプリケーション終了によって回収されますが、その場合であっても、Button1 が再クリックされる際に、以前のインスタンスを Dispose するべきかどうかは検討しておいてください。なお、一般的には Brush や Pen なども処分対象です。ただし今回のケースで言うと、colower のインスタンスは共有ブラシ(Brushes.Red) を割り当てているので、こちらは Dispose してはいけません。
-
魔界の仮面弁士さん>
全く同じ内容で以下の 3 つスレッドが立っています。
上の一番目がここなのですが、二番目のスレッドによると、一番目と二番目のスレッドは削除して三番目のスレッドのみ残すそうです。