■XP PageSetUpDialog
■Vista PageSetUpDialog
■対応策
自作のページ設定画面を作成します。
プロパティボタンクリックで、PageSetUpDialogのプリンタ設定ボタンで開く「プリンタのプロパティ画面」を表示します。
プリンターのプロパティ画面を表示する方法ですが、プリンタを変更するとプリンタドライバに依存するDEVMODE 構造体部分がメモリ確保されていないためエラーになることがあり
Marshal.AllocCoTaskMemを使った方法を使用します。
コードはこちら .NET プリンターのプロパティ画面を表示するには
コード
Imports System.Runtime.InteropServices
Public Class frmPrinterSetting
Private _printer As System.Drawing.Printing.PrinterSettings
#Region "API定義"
' API 定義
Private Declare Auto Function OpenPrinter Lib "winspool.drv" ( _
<MarshalAs(UnmanagedType.LPTStr)> ByVal pPrinterName As String, _
ByRef phPrinter As IntPtr, _
ByVal pDefault As IntPtr) As Int32
Private Declare Auto Function DocumentProperties Lib "winspool.drv" ( _
ByVal hwnd As IntPtr, _
ByVal hPrinter As IntPtr, _
<MarshalAs(UnmanagedType.LPTStr)> ByVal pDeviceName As String, _
ByVal pDevModeOut As IntPtr, _
ByVal pDevModeIn As IntPtr, _
ByVal fMode As Integer) As Int32
Private Declare Auto Function ClosePrinter Lib "winspool.drv" (ByVal hPrinter As IntPtr) As Int32
Private Declare Auto Function GlobalLock Lib "kernel32" (ByVal hmem As IntPtr) As IntPtr
Private Declare Auto Function GlobalFree Lib "kernel32" (ByVal hmem As IntPtr) As Int32
Private Declare Auto Function GlobalUnlock Lib "kernel32" (ByVal hMem As IntPtr) As Int32
Private Const DM_OUT_BUFFER As Short = 2
Private Const DM_IN_PROMPT As Short = 4
Private Const DM_IN_BUFFER As Short = 8
#End Region
Public Sub New()
' この呼び出しは、Windows フォーム デザイナで必要です。
InitializeComponent()
' InitializeComponent() 呼び出しの後で初期化を追加します。
Call Initialize()
End Sub
Private Sub Initialize()
Me._printer = New System.Drawing.Printing.PrinterSettings
'プリンターコンボボックスのデータを設定します。
Me.cboPrinterName.BeginUpdate()
For Each printerNm As String In Drawing.Printing.PrinterSettings.InstalledPrinters
Me.cboPrinterName.Items.Add(printerNm)
Next
Me.cboPrinterName.EndUpdate()
Call ToControl()
End Sub
Private Sub cboPrinterName_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles cboPrinterName.SelectedIndexChanged
Me._printer.PrinterName = Me.cboPrinterName.SelectedItem.ToString
'用紙サイズコンボボックスのデータを設定します。
Me.cboPaperSize.BeginUpdate()
Me.cboPaperSize.DisplayMember = "PaperName"
For Each paperSize As System.Drawing.Printing.PaperSize In Me._printer.PaperSizes
Me.cboPaperSize.Items.Add(paperSize)
Next
Me.cboPaperSize.EndUpdate()
End Sub
Private Sub rdoPrintPage_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles rdoSomePages.CheckedChanged, rdoAllPages.CheckedChanged
Dim rdo As RadioButton = CType(sender, RadioButton)
If Not rdo.Checked Then
Return
End If
If Me.rdoAllPages.Equals(rdo) Then
Me.txtFromPage.Enabled = False
Me.txtToPage.Enabled = False
ElseIf Me.rdoSomePages.Equals(rdo) Then
Me.txtFromPage.Enabled = True
Me.txtToPage.Enabled = True
End If
End Sub
Private Sub btnSetting_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles btnSetting.Click
'コントロールの値をPrinterSettingsに設定します。
Call ToPrinter()
Dim hDevModeIn As IntPtr = Me._printer.GetHdevmode
Dim hDevModeOut As IntPtr = Me._printer.GetHdevmode
Dim pDevModeIn As IntPtr = GlobalLock(hDevModeIn)
Dim pDevModeOut As IntPtr = GlobalLock(hDevModeOut)
Dim hPrinter As IntPtr
OpenPrinter(Me._printer.PrinterName, hPrinter, IntPtr.Zero)
Dim rc As Integer = DocumentProperties(Me.Handle, hPrinter, Me._printer.PrinterName, pDevModeOut, pDevModeIn, DM_IN_PROMPT Or DM_IN_BUFFER Or DM_OUT_BUFFER)
If rc = 1 Then
Me._printer = New System.Drawing.Printing.PrinterSettings
Me._printer.PrinterName = Me.cboPrinterName.SelectedItem.ToString
Me._printer.SetHdevmode(pDevModeOut)
'PrinterSettings値をコントロールに設定します。
Call ToControl()
End If
GlobalUnlock(hDevModeIn)
GlobalUnlock(hDevModeOut)
GlobalFree(hDevModeIn)
GlobalFree(hDevModeOut)
ClosePrinter(hPrinter)
End Sub
Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles btnCancel.Click
Me.Close()
End Sub
Private Sub btnPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles btnPrint.Click
'印刷処理
End Sub
Private Sub ToPrinter()
If Not Me._printer.PrinterName.Equals(Me.cboPrinterName.SelectedItem.ToString) Then
Me._printer.PrinterName = cboPrinterName.SelectedItem.ToString
End If
Me._printer.DefaultPageSettings.PaperSize = CType(Me.cboPaperSize.SelectedItem, System.Drawing.Printing.PaperSize)
If Me.rdoAllPages.Checked Then
Me._printer.PrintRange = Printing.PrintRange.AllPages
ElseIf Me.rdoSomePages.Checked Then
Me._printer.PrintRange = Printing.PrintRange.SomePages
Me._printer.FromPage = CInt(Me.txtFromPage.Text)
Me._printer.ToPage = CInt(Me.txtToPage.Text)
End If
Me._printer.DefaultPageSettings.Landscape = Me.rdoHorizontal.Checked
Me._printer.Copies = CShort(Me.nudCopies.Value)
End Sub
Private Sub ToControl()
Me.cboPrinterName.SelectedItem = Me._printer.PrinterName
Me.cboPaperSize.Text = Me._printer.DefaultPageSettings.PaperSize.PaperName
If Me._printer.PrintRange = Printing.PrintRange.AllPages Then
Me.rdoAllPages.Checked = True
ElseIf Me._printer.PrintRange = Printing.PrintRange.SomePages Then
Me.rdoSomePages.Checked = True
Me.txtFromPage.Text = Me._printer.FromPage.ToString
Me.txtToPage.Text = Me._printer.ToPage.ToString
End If
If Me._printer.DefaultPageSettings.Landscape Then
Me.rdoHorizontal.Checked = True
Else
Me.rdoVertical.Checked = True
End If
Me.nudCopies.Value = Me._printer.Copies
End Sub
End Class
Public Class frmPrinterSetting
Private _printer As System.Drawing.Printing.PrinterSettings
#Region "API定義"
' API 定義
Private Declare Auto Function OpenPrinter Lib "winspool.drv" ( _
<MarshalAs(UnmanagedType.LPTStr)> ByVal pPrinterName As String, _
ByRef phPrinter As IntPtr, _
ByVal pDefault As IntPtr) As Int32
Private Declare Auto Function DocumentProperties Lib "winspool.drv" ( _
ByVal hwnd As IntPtr, _
ByVal hPrinter As IntPtr, _
<MarshalAs(UnmanagedType.LPTStr)> ByVal pDeviceName As String, _
ByVal pDevModeOut As IntPtr, _
ByVal pDevModeIn As IntPtr, _
ByVal fMode As Integer) As Int32
Private Declare Auto Function ClosePrinter Lib "winspool.drv" (ByVal hPrinter As IntPtr) As Int32
Private Declare Auto Function GlobalLock Lib "kernel32" (ByVal hmem As IntPtr) As IntPtr
Private Declare Auto Function GlobalFree Lib "kernel32" (ByVal hmem As IntPtr) As Int32
Private Declare Auto Function GlobalUnlock Lib "kernel32" (ByVal hMem As IntPtr) As Int32
Private Const DM_OUT_BUFFER As Short = 2
Private Const DM_IN_PROMPT As Short = 4
Private Const DM_IN_BUFFER As Short = 8
#End Region
Public Sub New()
' この呼び出しは、Windows フォーム デザイナで必要です。
InitializeComponent()
' InitializeComponent() 呼び出しの後で初期化を追加します。
Call Initialize()
End Sub
Private Sub Initialize()
Me._printer = New System.Drawing.Printing.PrinterSettings
'プリンターコンボボックスのデータを設定します。
Me.cboPrinterName.BeginUpdate()
For Each printerNm As String In Drawing.Printing.PrinterSettings.InstalledPrinters
Me.cboPrinterName.Items.Add(printerNm)
Next
Me.cboPrinterName.EndUpdate()
Call ToControl()
End Sub
Private Sub cboPrinterName_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles cboPrinterName.SelectedIndexChanged
Me._printer.PrinterName = Me.cboPrinterName.SelectedItem.ToString
'用紙サイズコンボボックスのデータを設定します。
Me.cboPaperSize.BeginUpdate()
Me.cboPaperSize.DisplayMember = "PaperName"
For Each paperSize As System.Drawing.Printing.PaperSize In Me._printer.PaperSizes
Me.cboPaperSize.Items.Add(paperSize)
Next
Me.cboPaperSize.EndUpdate()
End Sub
Private Sub rdoPrintPage_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles rdoSomePages.CheckedChanged, rdoAllPages.CheckedChanged
Dim rdo As RadioButton = CType(sender, RadioButton)
If Not rdo.Checked Then
Return
End If
If Me.rdoAllPages.Equals(rdo) Then
Me.txtFromPage.Enabled = False
Me.txtToPage.Enabled = False
ElseIf Me.rdoSomePages.Equals(rdo) Then
Me.txtFromPage.Enabled = True
Me.txtToPage.Enabled = True
End If
End Sub
Private Sub btnSetting_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles btnSetting.Click
'コントロールの値をPrinterSettingsに設定します。
Call ToPrinter()
Dim hDevModeIn As IntPtr = Me._printer.GetHdevmode
Dim hDevModeOut As IntPtr = Me._printer.GetHdevmode
Dim pDevModeIn As IntPtr = GlobalLock(hDevModeIn)
Dim pDevModeOut As IntPtr = GlobalLock(hDevModeOut)
Dim hPrinter As IntPtr
OpenPrinter(Me._printer.PrinterName, hPrinter, IntPtr.Zero)
Dim rc As Integer = DocumentProperties(Me.Handle, hPrinter, Me._printer.PrinterName, pDevModeOut, pDevModeIn, DM_IN_PROMPT Or DM_IN_BUFFER Or DM_OUT_BUFFER)
If rc = 1 Then
Me._printer = New System.Drawing.Printing.PrinterSettings
Me._printer.PrinterName = Me.cboPrinterName.SelectedItem.ToString
Me._printer.SetHdevmode(pDevModeOut)
'PrinterSettings値をコントロールに設定します。
Call ToControl()
End If
GlobalUnlock(hDevModeIn)
GlobalUnlock(hDevModeOut)
GlobalFree(hDevModeIn)
GlobalFree(hDevModeOut)
ClosePrinter(hPrinter)
End Sub
Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles btnCancel.Click
Me.Close()
End Sub
Private Sub btnPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles btnPrint.Click
'印刷処理
End Sub
Private Sub ToPrinter()
If Not Me._printer.PrinterName.Equals(Me.cboPrinterName.SelectedItem.ToString) Then
Me._printer.PrinterName = cboPrinterName.SelectedItem.ToString
End If
Me._printer.DefaultPageSettings.PaperSize = CType(Me.cboPaperSize.SelectedItem, System.Drawing.Printing.PaperSize)
If Me.rdoAllPages.Checked Then
Me._printer.PrintRange = Printing.PrintRange.AllPages
ElseIf Me.rdoSomePages.Checked Then
Me._printer.PrintRange = Printing.PrintRange.SomePages
Me._printer.FromPage = CInt(Me.txtFromPage.Text)
Me._printer.ToPage = CInt(Me.txtToPage.Text)
End If
Me._printer.DefaultPageSettings.Landscape = Me.rdoHorizontal.Checked
Me._printer.Copies = CShort(Me.nudCopies.Value)
End Sub
Private Sub ToControl()
Me.cboPrinterName.SelectedItem = Me._printer.PrinterName
Me.cboPaperSize.Text = Me._printer.DefaultPageSettings.PaperSize.PaperName
If Me._printer.PrintRange = Printing.PrintRange.AllPages Then
Me.rdoAllPages.Checked = True
ElseIf Me._printer.PrintRange = Printing.PrintRange.SomePages Then
Me.rdoSomePages.Checked = True
Me.txtFromPage.Text = Me._printer.FromPage.ToString
Me.txtToPage.Text = Me._printer.ToPage.ToString
End If
If Me._printer.DefaultPageSettings.Landscape Then
Me.rdoHorizontal.Checked = True
Else
Me.rdoVertical.Checked = True
End If
Me.nudCopies.Value = Me._printer.Copies
End Sub
End Class
2 件のコメント:
非常に古いOSですが、このヒントはまだ役に立ちます。ありがとう
初心者のための良い情報、また続きます.. ドライバープリンターを見つける
コメントを投稿