tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルPrintDocument.QueryPageSettings
記事No8548
投稿日: 2009/01/09(Fri) 16:49
投稿者ひでと
お世話になります。
複数ページの印刷でページ毎の余白を設定したいと、.QueryPageSettings
内で処理を書きました。
印刷はPrintPreviewDialogを表示させ、そこから実行したいと考えています。
問題になったのはPrintPreviewDialogの表示と実際に紙に印刷するときにHardMarginの
関係で位置がずれてしまうことでした。

そこで.BeginPrintの引数eを用いて、.QueryPageSettings内でずれを吸収する処理を
書きました。

PrintPreviewDialogの表示と1回目の印刷はうまくいくのですが、連続して印刷しようと
すると、ずれを吸収する処理があだとなり、逆方向にずれが生じてきます。

.QueryPageSettings内の処理に問題があるようなのですが、
ヘルプの.QueryPageSettingsの説明で
「PageSettings に対する変更は、現在のページにだけ影響を与えます。
ドキュメントの既定のページ設定には影響を与えません。」
を考えると どうにも原因がわかりません。よろしくお願いします。

Public Class Form1
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        With Me.PrintDocument1.DefaultPageSettings.Margins
            .Left = 80
            .Right = 40
            .Top = 40
            .Bottom = 40
        End With
    End Sub
    Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles _
    Button1.Click
        Me.PrintPreviewDialog1.Document = Me.PrintDocument1
        Me.PrintPreviewDialog1.ShowDialog()
    End Sub
    Dim PrintAction As System.Drawing.Printing.PrintAction
    Private Sub PrintDocument1_BeginPrint _
    (ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) _
    Handles PrintDocument1.BeginPrint
        PrintAction = e.PrintAction
    End Sub

    Private Sub PrintDocument1_PrintPage _
    (ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) _
    Handles PrintDocument1.PrintPage
        Dim X As Integer = e.MarginBounds.X
        Dim Y As Integer = e.MarginBounds.Y
        Dim Width As Integer = e.MarginBounds.Width
        Dim Height As Integer = e.MarginBounds.Height

        e.Graphics.DrawRectangle(Pens.Black, e.MarginBounds)
        e.Graphics.DrawLine(Pens.Black, X, Y, X + Width, Y + Height)
        e.Graphics.DrawLine(Pens.Black, X + Width, Y, X, Y + Height)
    End Sub

    Private Sub PrintDocument1_QueryPageSettings _
    (ByVal sender As Object, ByVal e As System.Drawing.Printing.QueryPageSettingsEventArgs) _
    Handles PrintDocument1.QueryPageSettings
'e.PageSettings.Margins をDefaultに戻そうとしてもうまくいかない?
       e.PageSettings.Margins = Me.PrintDocument1.DefaultPageSettings.Margins
        With e.PageSettings
            Select Case PrintAction
                Case Printing.PrintAction.PrintToFile
                    If .HardMarginX < .Margins.Left Then
                    Else
                        .Margins.Left = .HardMarginX
                    End If
                    If .HardMarginX < .Margins.Right Then
                    Else
                        .Margins.Right = .HardMarginX
                    End If
                    If .HardMarginY < .Margins.Top Then
                    Else
                        .Margins.Top = .HardMarginY
                    End If
                    If .HardMarginY < .Margins.Bottom Then
                    Else
                        .Margins.Bottom = .HardMarginY
                    End If
                Case Printing.PrintAction.PrintToPreview
                    If .HardMarginX < .Margins.Left Then
                    Else
                        .Margins.Left = .HardMarginX
                    End If
                    If .HardMarginX < .Margins.Right Then
                    Else
                        .Margins.Right = .HardMarginX
                    End If
                    If .HardMarginY < .Margins.Top Then
                    Else
                        .Margins.Top = .HardMarginY
                    End If
                    If .HardMarginY < .Margins.Bottom Then
                    Else
                        .Margins.Bottom = .HardMarginY
                    End If
                Case Printing.PrintAction.PrintToPrinter
                    If .HardMarginX < .Margins.Left Then
                        .Margins.Left = .Margins.Left - .HardMarginX
                    Else
                        .Margins.Left = 1 * 39.37 / 10
                    End If
                    If .HardMarginX < .Margins.Right Then
                        .Margins.Right = .Margins.Right + .HardMarginX
                    Else
                        .Margins.Right = .HardMarginX * 2 + 1 * 39.37 / 10
                    End If
                    If .HardMarginY < .Margins.Top Then
                        .Margins.Top = .Margins.Top - .HardMarginY
                    Else
                        .Margins.Top = 1 * 39.37 / 10
                    End If
                    If .HardMarginY < .Margins.Bottom Then
                        .Margins.Bottom = .Margins.Bottom + .HardMarginY
                    Else
                        .Margins.Bottom = .HardMarginY * 2 + 1 * 39.37 / 10
                    End If
            End Select
        End With
    End Sub
End Class

[ツリー表示へ]
タイトル自己レスです
記事No8564
投稿日: 2009/01/13(Tue) 09:12
投稿者ひでと
System.Drawing.Printing.QueryPageSettingsEventArgs) _
>     Handles PrintDocument1.QueryPageSettings
>  'e.PageSettings.Margins をDefaultに戻そうとしてもうまくいかない?
>        e.PageSettings.Margins = Me.PrintDocument1.DefaultPageSettings.Margins
        e.PageSettings.Margins = sender.DefaultPageSettings.Margins

のようにしたらできました。
QueryPageSettings 内ではPrintDocument.DefaultPageSettings.Margins自体が
一時的にe.PageSettings.Margins に変更されているのでしょうか?
senderにて 取得できたのが?でありますが、とりあえず、目的が達したのでよいとします。

失礼いたしました。

[ツリー表示へ]
タイトルRe: 自己レスです
記事No8565
投稿日: 2009/01/13(Tue) 09:32
投稿者ひでと
すいません。ダメでした。
この例ではうまく出来たような気がしたのですが、実際の
複数ページの印刷ではずれがでました。
ひきつづきアドバイスお願いします。

[ツリー表示へ]
タイトルRe^2: 自己レスです
記事No8566
投稿日: 2009/01/13(Tue) 09:59
投稿者ひでと
複数ページ印刷テスト用の処理をつくりました。
ここの処理でもう1週間程悩んでいます。紙も100枚ちかく・・・。
なにとぞ、ご助言をお願いします。

Public Class Form1
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        With Me.PrintDocument1.DefaultPageSettings.Margins
            .Left = 80
            .Right = 40
            .Top = 40
            .Bottom = 40
        End With
    End Sub

    Dim Max As Integer

    Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles _
    Button1.Click
        Me.PrintPreviewDialog1.Document = Me.PrintDocument1
        Me.PrintPreviewDialog1.ShowDialog()
    End Sub

    Dim PrintAction As System.Drawing.Printing.PrintAction

    Private Sub PrintDocument1_BeginPrint _
    (ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) _
    Handles PrintDocument1.BeginPrint
        PrintAction = e.PrintAction
        Max = 3
    End Sub

    Private Sub PrintDocument1_PrintPage _
    (ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) _
    Handles PrintDocument1.PrintPage
        Dim X As Integer = e.MarginBounds.X
        Dim Y As Integer = e.MarginBounds.Y
        Dim Width As Integer = e.MarginBounds.Width
        Dim Height As Integer = e.MarginBounds.Height

        e.Graphics.DrawRectangle(Pens.Black, e.MarginBounds)
        e.Graphics.DrawLine(Pens.Black, X, Y, X + Width, Y + Height)
        e.Graphics.DrawLine(Pens.Black, X + Width, Y, X, Y + Height)
        Max = Max - 1
        If Max > 0 Then
            e.HasMorePages = True
        Else
            e.HasMorePages = False
        End If
    End Sub

    Private Sub PrintDocument1_QueryPageSettings _
    (ByVal sender As Object, ByVal e As System.Drawing.Printing.QueryPageSettingsEventArgs) _
    Handles PrintDocument1.QueryPageSettings
        'e.PageSettings.Margins をDefaultに戻そうとしてもうまくいかない?
        e.PageSettings.Margins = Me.PrintDocument1.DefaultPageSettings.Margins
        With e.PageSettings
            Select Case PrintAction
                Case Printing.PrintAction.PrintToFile
                    If .HardMarginX < .Margins.Left Then
                    Else
                        .Margins.Left = .HardMarginX
                    End If
                    If .HardMarginX < .Margins.Right Then
                    Else
                        .Margins.Right = .HardMarginX
                    End If
                    If .HardMarginY < .Margins.Top Then
                    Else
                        .Margins.Top = .HardMarginY
                    End If
                    If .HardMarginY < .Margins.Bottom Then
                    Else
                        .Margins.Bottom = .HardMarginY
                    End If
                Case Printing.PrintAction.PrintToPreview
                    If .HardMarginX < .Margins.Left Then
                    Else
                        .Margins.Left = .HardMarginX
                    End If
                    If .HardMarginX < .Margins.Right Then
                    Else
                        .Margins.Right = .HardMarginX
                    End If
                    If .HardMarginY < .Margins.Top Then
                    Else
                        .Margins.Top = .HardMarginY
                    End If
                    If .HardMarginY < .Margins.Bottom Then
                    Else
                        .Margins.Bottom = .HardMarginY
                    End If
                Case Printing.PrintAction.PrintToPrinter
                    If .HardMarginX < .Margins.Left Then
                        .Margins.Left = .Margins.Left - .HardMarginX
                    Else
                        .Margins.Left = 1 * 39.37 / 10
                    End If
                    If .HardMarginX < .Margins.Right Then
                        .Margins.Right = .Margins.Right + .HardMarginX
                    Else
                        .Margins.Right = .HardMarginX * 2 + 1 * 39.37 / 10
                    End If
                    If .HardMarginY < .Margins.Top Then
                        .Margins.Top = .Margins.Top - .HardMarginY
                    Else
                        .Margins.Top = 1 * 39.37 / 10
                    End If
                    If .HardMarginY < .Margins.Bottom Then
                        .Margins.Bottom = .Margins.Bottom + .HardMarginY
                    Else
                        .Margins.Bottom = .HardMarginY * 2 + 1 * 39.37 / 10
                    End If
            End Select
        End With
    End Sub

End Class

[ツリー表示へ]
タイトルRe^3: 自己レスです
記事No8567
投稿日: 2009/01/13(Tue) 11:12
投稿者花ちゃん
[F8] で実行して、どこで値が変化するのか調べれば済む事では。

[ツリー表示へ]
タイトルRe^4: 自己レスです
記事No8568
投稿日: 2009/01/13(Tue) 11:43
投稿者魔界の仮面弁士
> [F8] で実行して、どこで値が変化するのか調べれば済む事では。
…F11 では無く?

キーボード ショートカットで解説するのは、混乱の元かと思いますよ。
オプション設定次第では、好きなキーを割り当てられるわけですし、
初期設定のキーにしても、キーボード マップ スキーム に依存しますから。


たとえば Visual Studio 2005 の場合、以下のように割り当てられていますが、
花ちゃんさんは、どの機能の呼び出しを意図しておられたのでしょうか?


★[F8] に割り当てられている機能の初期配置★
"Visual Studio 6" スキーム … [編集]-[次の場所へ移動]
"Visual Basic 6"  スキーム … [デバッグ]-[ステップ イン]
"Visual C++ 6"    スキーム … [編集]-[次の場所へ移動]
"Visual C++ 2"    スキーム … [デバッグ]-[ステップ イン]
"Visual C# 2005"  スキーム … [編集]-[次の場所へ移動]


★[デバッグ]-[ステップ イン] に割り当てられるキーの初期配置★
"Visual Studio 6" スキーム … 『F11』
"Visual Basic 6"  スキーム … 『F11』または『F8』
"Visual C++ 6"    スキーム … 『F11』
"Visual C++ 2"    スキーム … 『F8』
"Visual C# 2005"  スキーム … 『F11』


★[編集]-[次の場所へ移動] に割り当てられるキーの初期配置★
"Visual Studio 6" スキーム … 『F12』または『F8』
"Visual Basic 6"  スキーム … 割り当て無し
"Visual C++ 6"    スキーム … 『F4』または『F8』
"Visual C++ 2"    スキーム … 『F4』
"Visual C# 2005"  スキーム … 『F8』

[ツリー表示へ]
タイトルRe^5: 自己レスです
記事No8569
投稿日: 2009/01/13(Tue) 12:20
投稿者花ちゃん
> …F11 では無く?
F8 と F11 は同じ動作ではないのでしょうか?

> たとえば Visual Studio 2005 の場合、以下のように割り当てられていますが、
> 花ちゃんさんは、どの機能の呼び出しを意図しておられたのでしょうか?

下記での F8 キー単独での動作です。
http://msdn.microsoft.com/ja-jp/vstudio/dd183139.aspx

ステップ イン F8 または F11  一度に 1 ステートメントずつコードを実行し、
                メソッド呼び出しがある場合はその中に入ります。

Visual Studio 2005 Express Edition なら下記の F8 です。 http://hanatyan.sakura.ne.jp/samplepic/vbf8.gif

[ツリー表示へ]
タイトル本題からは外れますが
記事No8570
投稿日: 2009/01/13(Tue) 13:26
投稿者魔界の仮面弁士
> > …F11 では無く?
> F8 と F11 は同じ動作ではないのでしょうか?

ある程度限定された環境においては、同じ動作でしょうが、
必ずしも一般的であるとは言えないと思います。

先述のような理由により、そもそもショートカットキー前提に
話をすべきでは無いと考えます。

そしてもし、ショートカットキーを使って説明するのであれば、
より一般的な割り当てを提示した方が、誤解が少ないでしょう。


たとえば、初回起動時の設定画面において、ある 3 人がそれぞれ
 A さん…『全般的な開発設定』(VB / C# の両方を同じぐらい使う)
 B さん…『Visual Basic 開発設定』(旧 VB6 ユーザー)
 C さん…『Visual C# 開発設定』(C# メイン/たまに VB)
を選んでいたとします。

F11 を提示すれば、どのユーザーにとっても [ステップ イン] となりますが、
F8 を提示してしまうと、B さんにしか意図が伝わらない可能性があります。

[ツリー表示へ]
タイトルRe^4: 自己レスです
記事No8571
投稿日: 2009/01/13(Tue) 15:58
投稿者ひでと
> [F8] で実行して、どこで値が変化するのか調べれば済む事では。

実験します。まず e.PageSettings.Margins にQueryPageSettings内で
初期化をしない場合の処理として(1)をレム文にした場合

    Private Sub PrintDocument1_QueryPageSettings _
    (ByVal sender As Object, ByVal e As System.Drawing.Printing.QueryPageSettingsEventArgs) _
    Handles PrintDocument1.QueryPageSettings
        Debug.Print(Me.PrintDocument1.DefaultPageSettings.Margins.Left)
        'e.PageSettings.Margins をDefaultに戻そうとしてもうまくいかない?
(1)      'e.PageSettings.Margins = Me.PrintDocument1.DefaultPageSettings.Margins
    省略
        End With
        Debug.Print(Me.PrintDocument1.DefaultPageSettings.Margins.Left)
    End Sub

にて実験します。
1-1 PrintPreviewDialog.Showだけした場合
Me.PrintDocument1.DefaultPageSettings.Margins.Leftの値は全て80で設定値のままです。
1-2 PrintPreviewDialogの印刷ボタンを押した場合
Me.PrintDocument1.DefaultPageSettings.Margins.Leftの値は全て80で設定値のままです。
ただし 実際の印刷はずれています。

この結果からQueryPageSettings内では PrintDocument.DefaultPageSettings.Margins
の値は変化していないと考えられます。そこで(1)を実行文に変えて
(2)       e.PageSettings.Margins = Me.PrintDocument1.DefaultPageSettings.Margins
で実験してみます。

2-1 PrintPreviewDialog.Showだけした場合
Me.PrintDocument1.DefaultPageSettings.Margins.Leftの値は全て80で設定値のままです。
2-2 PrintPreviewDialogの印刷ボタンを押した場合
Debug.Printの値は
80,60,60,40,40,20と変化します。

考察

テスト用の処理の中でDefaultPageSettingsに値を設定しているのは
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        With Me.PrintDocument1.DefaultPageSettings.Margins
            .Left = 80
            .Right = 40
            .Top = 40
            .Bottom = 40
        End With
    End Sub
の処理だけです。他の処理ではMe.PrintDocument1.DefaultPageSettings.Margins=
などの処理はやっていないはずです。

したがっってQueryPageSettings内のe.PageSettingsの値を変更するとDefaultPageSettings
が変わってしまって、(1)の結果と「PageSettings に対する変更は、
現在のページにだけ影響を与えます。
ドキュメントの既定のページ設定には影響を与えません。」という説明に矛盾
するような気がするのですが?
テストの仕方がいけないのかも知れないのですが、どうにも理解できません。
かさねて、ご指導お願いします。

[ツリー表示へ]
タイトルRe^5: 自己レスです
記事No8572
投稿日: 2009/01/13(Tue) 16:25
投稿者ひでと
また 次の実験として e.PageSettings.Marginsに着目すると

    Private Sub PrintDocument1_QueryPageSettings _
    (ByVal sender As Object, ByVal e As System.Drawing.Printing.QueryPageSettingsEventArgs) _
    Handles PrintDocument1.QueryPageSettings
        'Debug.Print(Me.PrintDocument1.DefaultPageSettings.Margins.Left)
        Debug.Print(e.PageSettings.Margins.Left)
        'e.PageSettings.Margins をDefaultに戻そうとしてもうまくいかない?
        'e.PageSettings.Margins = Me.PrintDocument1.DefaultPageSettings.Margins


のようにe.PageSettings.Margins.Leftの変化は
80,60,40のように変化しているため、QueryPageSettingsが呼び出されるとき
前回のeの値が引き継がれていることも、推定できるかと思います。

[ツリー表示へ]