プリンターのプロパティ画面を表示する方法ですが、プリンタを変更するとプリンタドライバに依存する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 件のコメント:
コメントを投稿