改ページ への返答
投稿で使用できる特殊コードの説明。(別タブで開きます。)
以下の返答は逆順(新しい順)に並んでいます。
投稿者 shu  (社会人)
投稿日時
2012/2/7 16:16:50
PrintDocument1.Print()
をする前に描画ページ毎のデータに分割する必要があります。
分割したデータはPrivate変数にでも設定しておくと良いと思います。
この場合、行毎にした方が良いかもしれません。
ページ描画をしながら次のデータを描画するとそのページ内に収まらない
状態になるか分割したデータが最後までいったらループを終了して
データが最後までいっていたらe.HasMorePages = FalseをFalse、最後まで
いっていなかったらe.HasMorePages = Trueとするとよいと思います。
なお分割したデータの位置を記憶するのにもPrivate変数があると便利です。
PrintDocumentを使ったコーディングをする場合、PrintDocumentからの派生クラス
またはPrintDocumentをメンバに持つクラスを別に作成された方が処理が分かりやすく
なると思います。
をする前に描画ページ毎のデータに分割する必要があります。
分割したデータはPrivate変数にでも設定しておくと良いと思います。
この場合、行毎にした方が良いかもしれません。
ページ描画をしながら次のデータを描画するとそのページ内に収まらない
状態になるか分割したデータが最後までいったらループを終了して
データが最後までいっていたらe.HasMorePages = FalseをFalse、最後まで
いっていなかったらe.HasMorePages = Trueとするとよいと思います。
なお分割したデータの位置を記憶するのにもPrivate変数があると便利です。
PrintDocumentを使ったコーディングをする場合、PrintDocumentからの派生クラス
またはPrintDocumentをメンバに持つクラスを別に作成された方が処理が分かりやすく
なると思います。
投稿者 うさぎ  (学生)
投稿日時
2012/2/7 14:55:53
いつもお世話になっています。VB2005を勉強中のものです。
只今印刷について勉強しています。
文字の大きさ行数をコンボボックスで指定し、リッチテキストボックスに文章を書き込めば内容を繁栄するメモ帳みたいなものをつくりたいのですが、リッチテキストボックスに入れた内容がコンボボックスで指定した行数をこえた場合改ページしたいのですがどうしたらいいのかわかりません。
よろしくお願いします。
いまできているコード
Public Class Form1
Dim currentpage As Integer
Private flg As Boolean = False
Dim bityouseisita As Integer = 0
Dim bityouseimigi As Integer
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Combohaba.Items.Add("22")
Combohaba.Items.Add("27")
Combohaba.Items.Add("38")
Combohaba.Items.Add("44")
Combokazu.Items.Add("5")
Combokazu.Items.Add("10")
Combokazu.Items.Add("20")
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
PrintDocument1.Print()
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
PrintPreviewDialog1.ShowDialog()
End Sub
Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim g As Graphics = e.Graphics
Dim okisa As Single
If Combohaba.SelectedIndex = 0 Then
okisa = 14
ElseIf Combohaba.SelectedIndex = 1 Then
okisa = 17
ElseIf Combohaba.SelectedIndex = 2 Then
okisa = 24
ElseIf Combohaba.SelectedIndex = 3 Then
okisa = 28
End If
'フォントスタイル
Dim ItemFont As Font = New Drawing.Font("MS Pゴシック", okisa, FontStyle.Bold)
Dim haba As String = 0 '行幅
Dim kazu As String = 0 '行数
Dim waku As Integer = 0 '全体の枠の大きさ
haba = Combohaba.SelectedItem
kazu = Combokazu.SelectedItem
waku = haba * kazu '全体の枠=行数*行幅
'**************************
' 改行
'**************************
Dim a As String = "" '文字の幅
Dim tasugyou As Integer = 0 '次の行へ
For moji As Integer = 0 To RichTextBox1.Text.Length - 1 'リッチテキストのなかの文字全部
a &= RichTextBox1.Text(moji) 'リッチテキストのなかの文字一つ一つaという変数に入れる
If RichTextBox1.Text(moji) = ControlChars.Lf Then '改行させれれば書き込み
e.Graphics.DrawString(a, ItemFont, Brushes.Black, 30, 340 + bityouseisita + (tasugyou * haba))
a = ""
tasugyou += 1
End If
Dim sTest As Single = g.MeasureString(a, ItemFont).Width
If sTest > 760 Then 'aの文字幅が印刷ページの横幅よりもおおきくなったら書き込み改行
e.Graphics.DrawString(a, ItemFont, Brushes.Black, 30, 340 + bityouseisita + (tasugyou * haba))
a = ""
tasugyou += 1
End If
Next
'行幅、行数を指定して印刷内容に反映
haba = Combohaba.SelectedItem
kazu = Combokazu.SelectedItem
Dim n As Integer
Dim gyousuu As Integer = 340 + haba '指定された幅を足し行間とする
'Dim sotowaku As Integer
For n = 0 To kazu '指定されたkazuの行数繰り返し線を引く
If n = 0 Then
gyousuu = 340 + haba - haba
e.Graphics.DrawLine(New Pen(Color.Black), 20, gyousuu, 810, gyousuu)
Else
gyousuu = gyousuu + haba
e.Graphics.DrawLine(New Pen(Color.Black), 20, gyousuu, 810, gyousuu)
End If
Next
e.HasMorePages = False
End Sub
End Class
只今印刷について勉強しています。
文字の大きさ行数をコンボボックスで指定し、リッチテキストボックスに文章を書き込めば内容を繁栄するメモ帳みたいなものをつくりたいのですが、リッチテキストボックスに入れた内容がコンボボックスで指定した行数をこえた場合改ページしたいのですがどうしたらいいのかわかりません。
よろしくお願いします。
いまできているコード
Public Class Form1
Dim currentpage As Integer
Private flg As Boolean = False
Dim bityouseisita As Integer = 0
Dim bityouseimigi As Integer
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Combohaba.Items.Add("22")
Combohaba.Items.Add("27")
Combohaba.Items.Add("38")
Combohaba.Items.Add("44")
Combokazu.Items.Add("5")
Combokazu.Items.Add("10")
Combokazu.Items.Add("20")
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
PrintDocument1.Print()
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
PrintPreviewDialog1.ShowDialog()
End Sub
Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim g As Graphics = e.Graphics
Dim okisa As Single
If Combohaba.SelectedIndex = 0 Then
okisa = 14
ElseIf Combohaba.SelectedIndex = 1 Then
okisa = 17
ElseIf Combohaba.SelectedIndex = 2 Then
okisa = 24
ElseIf Combohaba.SelectedIndex = 3 Then
okisa = 28
End If
'フォントスタイル
Dim ItemFont As Font = New Drawing.Font("MS Pゴシック", okisa, FontStyle.Bold)
Dim haba As String = 0 '行幅
Dim kazu As String = 0 '行数
Dim waku As Integer = 0 '全体の枠の大きさ
haba = Combohaba.SelectedItem
kazu = Combokazu.SelectedItem
waku = haba * kazu '全体の枠=行数*行幅
'**************************
' 改行
'**************************
Dim a As String = "" '文字の幅
Dim tasugyou As Integer = 0 '次の行へ
For moji As Integer = 0 To RichTextBox1.Text.Length - 1 'リッチテキストのなかの文字全部
a &= RichTextBox1.Text(moji) 'リッチテキストのなかの文字一つ一つaという変数に入れる
If RichTextBox1.Text(moji) = ControlChars.Lf Then '改行させれれば書き込み
e.Graphics.DrawString(a, ItemFont, Brushes.Black, 30, 340 + bityouseisita + (tasugyou * haba))
a = ""
tasugyou += 1
End If
Dim sTest As Single = g.MeasureString(a, ItemFont).Width
If sTest > 760 Then 'aの文字幅が印刷ページの横幅よりもおおきくなったら書き込み改行
e.Graphics.DrawString(a, ItemFont, Brushes.Black, 30, 340 + bityouseisita + (tasugyou * haba))
a = ""
tasugyou += 1
End If
Next
'行幅、行数を指定して印刷内容に反映
haba = Combohaba.SelectedItem
kazu = Combokazu.SelectedItem
Dim n As Integer
Dim gyousuu As Integer = 340 + haba '指定された幅を足し行間とする
'Dim sotowaku As Integer
For n = 0 To kazu '指定されたkazuの行数繰り返し線を引く
If n = 0 Then
gyousuu = 340 + haba - haba
e.Graphics.DrawLine(New Pen(Color.Black), 20, gyousuu, 810, gyousuu)
Else
gyousuu = gyousuu + haba
e.Graphics.DrawLine(New Pen(Color.Black), 20, gyousuu, 810, gyousuu)
End If
Next
e.HasMorePages = False
End Sub
End Class
VB.NET では何故か無くなっているのですよね…。
VB.NET で、RichTextBox の内容を(書式付きで)印刷する方法が
以下に掲載されています。一応参考までに。
http://support.microsoft.com/kb/811401
> コンボボックスで指定した行数をこえた場合
この判定そのものは行えるのですよね?
改ページ位置の判定は、PrintPage イベントの中で行っても構いませんし、
印刷前にあらかじめ算出しておいても構わないと思いますが、事前に判定しておく場合は、
テキストデータを行単位に分割しておくと、印刷時に扱いやすいかも知れませんね。
> 改ページしたいのですが
PrintPage イベントを抜ける際に、「e.HasMorePages = True」にしておいてください。
そうすれば、次のページの印刷のために、もう一度 PrintPage イベントが呼び出されます。
(e.HasMorePages = False を指定するのは、最後のページを印刷し終わったときだけです)
結果として、PrintPage イベントは複数回呼ばれることになるため、
現在どのページを印刷しているのかは、Private 変数などで自己管理します。
(たとえば、Private currentPage As Integer など)
また、再度印刷したときのために、現在ページ位置をリセットできるよう、
BeginPrint/EndPrint イベントも利用してください。
以下、参考資料として:
[複数ページの印刷]
http://rucio.cloudapp.net/ThreadDetail.aspx?ThreadId=2220
[RichTextBoxの内容をA4の部分的範囲に印刷]
http://rucio.cloudapp.net/ThreadDetail.aspx?ThreadId=9730
[PrintPreviewDialogの印刷ボタンを使用不可にしたい。]
http://rucio.cloudapp.net/ThreadDetail.aspx?ThreadId=9987
--- 以下は、質問の本題とは関係ないところですが ---
> Dim g As Graphics = e.Graphics
変数 g を使って
「Dim sTest As Single = g.MeasureString(a, ItemFont).Width」
のように処理している場所もあれば、
「e.Graphics.DrawString(a, ItemFont, Brushes.Black, 30, 340 + bityouseisita + (tasugyou * haba))」
のように、e.Graphics を直接指定している個所もありますね。
今のままでも問題はありませんが、どちらかの表記に統一しておいた方がスマートかと。
> Dim ItemFont As Font = New Drawing.Font("MS Pゴシック", okisa, FontStyle.Bold)
上記の宣言は、下記のように記述する必要があります。
フォント名は、全角/半角や空白指定なども含めて正確に指定する必要があります。
今回の場合は、"MS Pゴシック" ではなく "MS Pゴシック" と指定せねばなりません。
(もしくは、英語名である "MS PGothic" でも良いですが)
フォント名が間違っていても動作はしますが、同じフォントが見つからない場合には
代替フォント(たとえば "Microsoft Sans Serif" など)に置き換えられてしまい、
正しく描画できない可能性があります。
また、印刷用に Font を New する場合は、Using ステートメントを利用するようにしましょう。
Using では都合が悪い場合には、最後に Dispose メソッドで破棄するようにします。
http://msdn.microsoft.com/ja-jp/library/system.drawing.font.dispose%28vs.80%29.aspx
> For moji As Integer = 0 To RichTextBox1.Text.Length - 1 'リッチテキストのなかの文字全部
個人的には
RichTextBox1.Text.Length
よりも
RichTextBox1.TextLength
を使う事をおすすめしておきます。意味は一緒なのですけれどね。
http://rucio.cloudapp.net/ThreadDetail.aspx?ThreadId=9187
なお提示のサンプルだと、禁則処理や複合文字などの考慮が抜けているため、
たとえば文末に「ガ」や「ですが、」などの文章が来た場合において、位置によっては
濁点や句読点が次の行頭に送られてしまい、不自然な文章になってしまう点が
少し気になりました。あえてそうしているのであれば構わないのですけれども。
> e.Graphics.DrawLine(New Pen(Color.Black), 20, gyousuu, 810, gyousuu)
Font 同様、Pen や Brush も破棄すべきオブジェクトなので、この場合は、 のように記述するか、または New せずに のように、出来合いのPenを利用するようにします。
ただし、Pens や Brushes の Shared ReadOnly なプロパティ群を使って描画する場合は、
それらの Pen や Brush を破棄しないように注意してください。
(Brushes.Black 等は自分で生成したものではないため、システム側に管理を任せた方が安全です)