印刷ページの中でフォントを変えるには?

解決


hiroshi  2009-01-05 05:31:44  No: 145596

印刷する場合に途中でフォントやブラシを変更するにはどうしたらよいか教えて下さい。
宛名印刷をVB6で以前作ったのを.NETに書き換えようとしております。
宛先の住所、郵便番号、名前、差出人の住所、差し出し人郵便番号等、
フォントの大きさや位置を1ページの中で変えなければならないのですが、
VB6の場合は、印刷したい文字を
Printer.FontSize=17
Printer.CurrentX=1000
Printer.Print "文字"
の様にすればよかったのですが、
PrintDocumentコントロールを使って印刷をしようとしても
印刷途中でフォントを変更できないような気がするのですが、
どうしたらよいのでしょうか。よろしくお願いします。


Mako-chan  2009-01-06 01:50:12  No: 145597

前回の質問の回答時で、ボタンのクリックイベントでフォントやブラシを指定されていると思いますが、その時に、
「宛先の住所」用のフォント・ブラシ
「郵便番号」用のフォント・ブラシ
・・・
のように設定してはどうでしょうか。


hiroshi  2009-01-06 07:08:19  No: 145598

具体的に説明します
Private b as New SolidBrush(Color,Red)
Private f as New Font("MS 明朝",24,FontStyle.Bold)
の様にブラシとフォントを作っておいて
PrintDocumentコントロールのプロシージャは、
e.Graphics.DrawStrings(MyString,f,b,x,y)  としてあります
この状況で例えばボタンをクリックし
Private Sub Button_Click()
   b.Color=Color.Black:x=100:y=100:PrintDocument1.Print()
   b.Color=Color.Red:x=300:y=300:PrintDocument1.Print()
End Sub
を実行すると
この結果MyStringが別のページに印刷されてしまいます
同じページに書きたいのですが、どうしたらよいのですか?
それともうひとつ、ブラシは変えられるようですが
フォントの変え方を教えて下さい。


魔界の仮面弁士  2009-01-06 07:49:17  No: 145599

> の様にブラシとフォントを作っておいて
作成したオブジェクトは、使用後に必ず「Dispose メソッド」で破棄してください。
破棄しない場合、ガベージコレクトされるまでオブジェクトが解放されないため、リソースを圧迫してしまいます。

> フォントの変え方を教えて下さい。
ん? ブラシと大差ないと思いますけれども。
  f.Dispose()  '以前のフォントを破棄
  f = New Font(〜〜)  '新たなフォントを割り当て
ですよね。

> Private Sub Button_Click()
>    b.Color=Color.Black:x=100:y=100:PrintDocument1.Print()
>    b.Color=Color.Red:x=300:y=300:PrintDocument1.Print()
> End Sub

PrintDocument の Print メソッドは「印刷開始」の指示なので、
一度しか呼びません。

今回指示したいのは、「文字列の描画」の方ですから、2 度呼ぶのは
Graphics.DrawStrings (VB6 でいうところの Printer.Print) の方です。

.NET の PrintPage イベントは、印刷するページ数分だけ発生します。
# 2 ページ以上の印刷をする場合は、PrintPage イベント内で、
# 「まだ次のページの印刷データがあるよ」と教えるために、
#  e.HasMorePage を True に設定します(最終ページでは False にする)

今回の場合、1 ページ内に複数のフォントを使いたいだけなので、
ひとつの PrintPage イベント内にて

  Sub PrintDocument1_PrintPage(…)
    '郵便番号
    e.Graphics.DrawStrings(ZipString, ZipFont, ZipBrush, ZipX, ZipY)
    '住所
    e.Graphics.DrawStrings(AddressString, AddressFont, AddressBrush, AddressX, AddressY)
  End Sub

のように書けば OK です。

ついでに、複数ページへの出力の場合についても。
# VB6 の方が理解が早いようなので、VB6 側の方から話をしていきます。

VB6 の印刷処理(Print オブジェクト)は、イベントを持っていませんよね。
たとえば、3ページ印刷するためのコードとして、

  Sub Command1_Click()
    Printer.Font.Size = 15
    Printer.Print "1ページ目"
    Printer.NewPage

    Printer.Font.Size = 12
    Printer.Print "2ページ目"
    Printer.NewPage

    Printer.Font.Size = 9
    Printer.Print "3ページ目"

    Printer.EndDoc
  End Sub

のような処理があったのであれば、それを見直して、

  Sub Command1_Click()
    Call 印刷処理の1ページ目
    Call 印刷処理の2ページ目
    Call 印刷処理の3ページ目
    Call Printer.EndDoc
  End Sub

あるいは、

  Sub Command1_Click()
    For page = 1 To 3
      Call 印刷処理(page)  '★描画処理の本体★
    Next
    Call Printer.EndDoc()
  End Sub

というコードに置き換えてみてください。

それができれば、修正後のコードを .NET に置き換えるのも容易なハズです。

  '---- .NET 版 ----
  Private currentPageNumber As Integer = 0
  Sub Button1_Click(…)
    currentPageNumber = 0
    PrintDocument1.Print()    '印刷処理を実行
  End Sub

  Sub PrintDocument1_PrintPage(…)
    currentPageNumber += 1

    Call 印刷処理(currentPageNumber)  '★描画処理の本体★

    If currentPageNumber = 3 Then
      e.HasMorePages = False
      currentPageNumber = 0
    Else
      e.HasMorePages = True
    End If
  End Sub


hiroshi  2009-01-06 20:58:39  No: 145600

魔界の仮面弁士さん、本当にありがとうございます。
下記のようにして、目的は達成できましたが、御説明にありました
f.Dispose()  と  f = New Font(〜〜)  をどこでやるのかがわかりません。

ブラシとフォントの定義は
Private AddressFont as New Font("MS 明朝",24,FontStyle.Bold)
Private ZipFont as New Font("MS 明朝",15,FontStyle.Bold)
Private AddressBrsh as New SolidBrush(Color,Red)
Private ZipBrush as New SolidBrush(Color,Red)

PrintDocumentコントロールの記述は、
Sub PrintDocument1_PrintPage(…)
    '郵便番号
    e.Graphics.DrawStrings(ZipString, ZipFont, ZipBrush, ZipX, ZipY)
    '住所
    e.Graphics.DrawStrings(AddressString, AddressFont, AddressBrush, AddressX, AddressY)
  End Sub

ボタンをクリックし
Private Sub Button_Click()
   AddressBrsh.Color=Color.Black
   PrintDocument1.Print()
End Sub

以上で目的は達成できました。上の例はブラシを変更した場合ですが、
当面の目的のためには必要ないのですが、
フォントを変える又は、フォントを新しく作って
Sub PrintDocument1_PrintPage(…)に渡す様な事はできないのですか?
又、オブジェクトのDispose()をこの流れの中でどこでやればよいのでしょうか?
宜しくお願いします。


特攻隊長まるるう  2009-01-07 00:50:43  No: 145601

> ブラシとフォントの定義は
で変数の宣言とインスタンスの生成(New)を一度にやっちゃってますね。
このままの形でフォームが生きている間、ずっと AddressFont と ZipFont
を覚えておくなら、Dispose はフォームを閉じる時でしょうか。

[前スレ]
http://madia.world.coocan.jp/cgi-bin/vbnet/wwwlng.cgi?print+200901/09010002.txt
>案4 であれば、たとえば
>  Private b As Brush
>  Private f As Font
もともと前スレに書いてある通り New はしてません。
フォントとして使用するのは f 1つだけです。
それを
>  f.Dispose()  '以前のフォントを破棄
>  f = New Font(〜〜)  '新たなフォントを割り当て
と、書いてある通りのことをしてください。

フォントの処理だけ対応すれば
  Sub PrintDocument1_PrintPage(…)
    f = New Font("MS 明朝",15,FontStyle.Bold) ' ZipFontを割り当て
    '郵便番号
    e.Graphics.DrawStrings(ZipString, f, ZipBrush, ZipX, ZipY)
    f.Dispose()  '以前のフォントを破棄
    f = New Font("MS 明朝",24,FontStyle.Bold)  'AddressFontを割り当て
    '住所
    e.Graphics.DrawStrings(AddressString, f, AddressBrush, AddressX, AddressY)
    f.Dispose()  '以前のフォントを破棄
  End Sub


魔界の仮面弁士  2009-01-07 01:34:21  No: 145602

主要な箇所は、特攻隊長まるるうさんが回答しておられるので、
別の部分について回答。

> Private AddressFont as New Font("MS 明朝",24,FontStyle.Bold)
"MS 明朝" ではなく、
"MS 明朝" のハズですよ。

> Private AddressBrsh as New SolidBrush(Color,Red)
> Private Sub Button_Click()
>   AddressBrsh.Color=Color.Black
>   PrintDocument1.Print()
> End Sub
> 上の例はブラシを変更した場合ですが、
この場合、ブラシは変更されていません。
ブラシの色(AddressBrsh.Color)が変わっただけで、
ブラシ(AddressBrsh)自体は同一のインスタンスのままです。

# 赤ペンキの付いたブラシを手放して、黒ペンキの付いたブラシに持ち換えたのではなく、
# 赤ペンキの付いたブラシに対して、黒いペンキを付け直しただけ…。

> フォントを変える又は、フォントを新しく作って
ブラシの Color は後から変更できますが、フォントの Name や Size は
後から変更できるようにはなっていないので、別なフォントを使いたい場合は、
新たなフォント インスタンスを生成しなおす必要があります。

なお、特攻隊長まるるうさんのコードに関して補足すると、
この場合はフォントを PrintPage イベント内で作成/破棄しているため、
変数 f はフィールドには持たず、ローカル変数にした方が良いでしょう。

  Sub PrintDocument1_PrintPage(…)
    Using f As New Font("MS 明朝",15,FontStyle.Bold)
      e.Graphics.DrawStrings(ZipString, f, ZipBrush, ZipX, ZipY)
    End Using
    Using f As New Font("MS 明朝",24,FontStyle.Bold)
      e.Graphics.DrawStrings(AddressString, f, AddressBrush, AddressX, AddressY)
    End Using
  End Sub


hiroshi  2009-01-07 04:34:13  No: 145603

特攻隊長まるるうさん、魔界の仮面弁士さん、お世話になりました。
今までも何回か質問させてもらい、其の都度丁寧なご指導を頂き、
本当に助かります。

今後ともよろしくお願いします。


※返信する前に利用規約をご確認ください。




  


  このエントリーをはてなブックマークに追加