プリンターのプロパティ画面を表示する方法ですが、プリンタを変更するとプリンタドライバに依存するDEVMODE 構造体部分がメモリ確保されていないためエラーになることがあり
Marshal.AllocCoTaskMemを使った方法に訂正します。
Imports System.Runtime.InteropServices
Public Class Form1
<DllImport("winspool.drv", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function OpenPrinter( _
<MarshalAs(UnmanagedType.LPTStr)> ByVal pPrinterName As String, ByRef hPrinter As IntPtr, ByVal pDefault As IntPtr) As Int32
End Function
<DllImport("winspool.drv", SetLastError:=True)> _
Private Shared Function ClosePrinter(ByVal hPrinter As IntPtr) As Int32
End Function
<DllImport("winspool.drv", SetLastError:=True)> _
Private Shared Function DocumentProperties ( _
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 Int32) As Int32
End Function
Private Const DM_OUT_BUFFER As Short = 2
Private Const DM_IN_PROMPT As Short = 4
Private Const DM_IN_BUFFER As Short = 8
<DllImport("kernel32", SetLastError:=True)> _
Private Shared Function GlobalLock(ByVal hmem As IntPtr) As IntPtr
End Function
<DllImport("kernel32", SetLastError:=True)> _
Private Shared Function GlobalFree(ByVal hmem As IntPtr) As Int32
End Function
<DllImport("kernel32", SetLastError:=True)> _
Private Shared Function GlobalUnlock(ByVal hMem As IntPtr) As Int32
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim printer As New Printing.PrinterSettings
Dim ret As Boolean = ShowPrinterProperty(Me.Handle, printer)
End Sub
Private Function ShowPrinterProperty(ByVal hwnd As IntPtr, ByVal printer As Printing.PrinterSettings) As Boolean
Dim ret As Int32
'プリンタのハンドルを取得する
Dim hPrinter As IntPtr = IntPtr.Zero
ret = OpenPrinter(printer.PrinterName, hPrinter, IntPtr.Zero)
If (ret = 0 OrElse hPrinter = IntPtr.Zero) Then
Return False
End If
Try
'プリンタのDEVMODE構造体のサイズを取得する
Dim iDevModeSize As Integer = DocumentProperties(IntPtr.Zero, hPrinter, printer.PrinterName, IntPtr.Zero, IntPtr.Zero, 0)
'Input用のDEVMODE構造体のハンドルを取得する
Dim hDevModeIn As IntPtr = printer.GetHdevmode()
Dim pDevModeIn As IntPtr = GlobalLock(hDevModeIn)
'OutOut用のDEVMODE構造体のメモリを確保する
Dim pDevModeOut As IntPtr = Marshal.AllocCoTaskMem(iDevModeSize)
Try
'設定画面を開く
ret = DocumentProperties(hwnd, hPrinter, printer.PrinterName, pDevModeOut, pDevModeIn, DM_IN_PROMPT Or DM_IN_BUFFER Or DM_OUT_BUFFER)
If (ret = 1) Then
printer.SetHdevmode(pDevModeOut)
End If
'
Return True
Finally
GlobalUnlock(hDevModeIn)
GlobalFree(hDevModeIn)
Marshal.FreeCoTaskMem(pDevModeOut)
End Try
Finally
ClosePrinter(hPrinter)
End Try
End Function
End Class
0 件のコメント:
コメントを投稿