Global Printers Settings are changed with DocumentProperties
For example, this test gets the default paper size (DM_PAPERSIZE) for the selected printer and changes it on Button click
You can also change the orientation with DM_ORIENTATION (DMORIENT_PORTRAIT = 1 and DMORIENT_LANDSCAPE = 2)
Add 2 ComboBoxes and 1 Button for the Button click =>
Imports System.Drawing.Printing
Imports System.Runtime.InteropServices
Public Class Form1
<DllImport("Winspool.drv", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function DeviceCapabilities(lpDeviceName As String, lpPort As String, iIndex As Integer, lpOutput As IntPtr, lpDevMode As IntPtr) As Integer
End Function
<DllImport("Winspool.drv", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function OpenPrinter(pPrinterName As String, ByRef hPrinter As IntPtr, ByRef pDefault As PRINTER_DEFAULTS) As Boolean
End Function
<DllImport("Winspool.drv", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function ClosePrinter(hPrinter As IntPtr) As Boolean
End Function
<DllImport("Winspool.drv", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function GetPrinter(hPrinter As IntPtr, Level As Integer, pPrinter As IntPtr, cbBuf As Integer, ByRef pcbNeeded As Integer) As Boolean
End Function
<DllImport("Winspool.drv", SetLastError:=True, CharSet:=CharSet.Unicode)>
Private Shared Function SetPrinter(hPrinter As IntPtr, Level As Integer, pPrinter As IntPtr, Command As Integer) As Boolean
End Function
Public Const ERROR_INSUFFICIENT_BUFFER = 122
<StructLayout(LayoutKind.Sequential)>
Public Structure PRINTER_INFO_2
<MarshalAs(UnmanagedType.LPTStr)> Public pServerName As String
<MarshalAs(UnmanagedType.LPTStr)> Public pPrinterName As String
<MarshalAs(UnmanagedType.LPTStr)> Public pShareName As String
<MarshalAs(UnmanagedType.LPTStr)> Public pPortName As String
<MarshalAs(UnmanagedType.LPTStr)> Public pDriverName As String
<MarshalAs(UnmanagedType.LPTStr)> Public pComment As String
<MarshalAs(UnmanagedType.LPTStr)> Public pLocation As String
Public pDevMode As IntPtr
<MarshalAs(UnmanagedType.LPTStr)> Public pSepFile As String
<MarshalAs(UnmanagedType.LPTStr)> Public pPrintProcessor As String
<MarshalAs(UnmanagedType.LPTStr)> Public pDatatype As String
<MarshalAs(UnmanagedType.LPTStr)> Public pParameters As String
Public pSecurityDescriptor As IntPtr
Public Attributes As Integer
Public Priority As Integer
Public DefaultPriority As Integer
Public StartTime As Integer
Public UntilTime As Integer
Public Status As Integer
Public cJobs As Integer
Public AveragePPM As Integer
End Structure
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
Public Structure DEVMODE
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)> Public pDeviceName As String
Public dmSpecVersion As Short
Public dmDriverVersion As Short
Public dmSize As Short
Public dmDriverExtra As Short
Public dmFields As Integer
Public dmOrientation As Short
Public dmPaperSize As Short
Public dmPaperLength As Short
Public dmPaperWidth As Short
Public dmScale As Short
Public dmCopies As Short
Public dmDefaultSource As Short
Public dmPrintQuality As Short
Public dmColor As Short
Public dmDuplex As Short
Public dmYResolution As Short
Public dmTTOption As Short
Public dmCollate As Short
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)> Public dmFormName As String
Public dmUnusedPadding As Short
Public dmBitsPerPel As Integer
Public dmPelsWidth As Integer
Public dmPelsHeight As Integer
Public dmNup As Integer
Public dmDisplayFrequency As Integer
Public dmICMMethod As Integer
Public dmICMIntent As Integer
Public dmMediaType As Integer
Public dmDitherType As Integer
Public dmReserved1 As Integer
Public dmReserved2 As Integer
Public dmPanningWidth As Integer
Public dmPanningHeight As Integer
End Structure
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure PRINTER_DEFAULTS
Public pDatatype As IntPtr
Public pDevMode As IntPtr
Public DesiredAccess As Integer
End Structure
Dim STANDARD_RIGHTS_REQUIRED As Integer = &HF0000
Dim PRINTER_ACCESS_ADMINISTER As Integer = &H4
Dim PRINTER_ACCESS_USE As Integer = &H8
Dim PRINTER_ALL_ACCESS As Integer = (STANDARD_RIGHTS_REQUIRED Or (PRINTER_ACCESS_ADMINISTER Or PRINTER_ACCESS_USE))
Public Const DC_PAPERS = 2
Public Const DC_PAPERSIZE = 3
Public Const DC_PAPERNAMES = 16
Public Const DC_BINNAMES = 12
Public Const DC_BINS = 6
Public Const DEFAULT_VALUES = 0
Public Const DM_ORIENTATION = &H1
Public Const DM_PAPERSIZE = &H2
<DllImport("Winspool.drv", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function DocumentProperties(hwnd As IntPtr, hPrinter As IntPtr, pDeviceName As String, pDevModeOutput As IntPtr, pDevModeInput As IntPtr, fMode As Integer) As Integer
End Function
Public Const DM_UPDATE = 1
Public Const DM_COPY = 2
Public Const DM_PROMPT = 4
Public Const DM_MODIFY = 8
Public Const DM_IN_BUFFER = DM_MODIFY
Public Const DM_IN_PROMPT = DM_PROMPT
Public Const DM_OUT_BUFFER = DM_COPY
Public Const DM_OUT_DEFAULT = DM_UPDATE
Public Const HWND_BROADCAST As Integer = (&HFFFF)
Public Const WM_DEVMODECHANGE As Integer = &H1B
Public Const SMTO_NORMAL As Integer = &H0
Public Const SMTO_BLOCK As Integer = &H1
Public Const SMTO_ABORTIFHUNG As Integer = &H2
Public Const SMTO_NOTIMEOUTIFNOTHUNG As Integer = &H8
Public Const SMTO_ERRORONEXIT As Integer = &H20
<DllImport("User32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function SendMessageTimeout(hWnd As IntPtr, Msg As Integer, wParam As IntPtr, lParam As String, fuFlags As UInteger, uTimeout As UInteger, lpdwResult As IntPtr) As IntPtr
End Function
Private WithEvents PrintDocument1 As PrintDocument = New PrintDocument
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For i As Integer = 0 To PrinterSettings.InstalledPrinters.Count - 1
ComboBox1.Items.Add(PrinterSettings.InstalledPrinters(i).ToString)
If PrintDocument1.PrinterSettings.PrinterName = PrinterSettings.InstalledPrinters(i).ToString Then
ComboBox1.SelectedIndex = i
End If
Next
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
Cursor = Cursors.WaitCursor
With PrintDocument1
.PrinterSettings.PrinterName = PrinterSettings.InstalledPrinters(ComboBox1.SelectedIndex)
If ComboBox2.Items.Count > 0 Then ComboBox2.Items.Clear()
Dim hPrinter As IntPtr
Dim pDefaults As New PRINTER_DEFAULTS()
Dim sPrinterName = PrinterSettings.InstalledPrinters(ComboBox1.SelectedIndex)
Dim sPrinterPort As String = Nothing
Dim nPrinterPaperSize As Integer = 0
pDefaults.DesiredAccess = PRINTER_ACCESS_USE
Dim bResult As Boolean = OpenPrinter(sPrinterName, hPrinter, pDefaults)
If (bResult = True) Then
Dim nBytesNeeded As Integer = -1
Dim nSize As Integer = -1
Dim pPrinterInfo As IntPtr = IntPtr.Zero
GetPrinter(hPrinter, 2, IntPtr.Zero, 0, nBytesNeeded)
pPrinterInfo = Marshal.AllocHGlobal(nBytesNeeded)
nSize = nBytesNeeded
If (Not GetPrinter(hPrinter, 2, pPrinterInfo, nSize, nBytesNeeded)) Then
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error())
End If
Dim PrinterInfo As PRINTER_INFO_2 = CType(Marshal.PtrToStructure(pPrinterInfo, GetType(PRINTER_INFO_2)), PRINTER_INFO_2)
sPrinterPort = PrinterInfo.pPortName
Dim pDevMode As IntPtr = PrinterInfo.pDevMode
Dim DevMode As DEVMODE = CType(Marshal.PtrToStructure(pDevMode, GetType(DEVMODE)), DEVMODE)
nPrinterPaperSize = DevMode.dmPaperSize
Marshal.FreeHGlobal(pPrinterInfo)
ClosePrinter(hPrinter)
End If
Dim nNumber As Integer
nNumber = DeviceCapabilities(sPrinterName, sPrinterPort, DC_PAPERNAMES, IntPtr.Zero, IntPtr.Zero)
Dim nStringSize As Integer = Marshal.SystemDefaultCharSize * 64
Dim pNamesBuffer As IntPtr = Marshal.AllocHGlobal(nStringSize * nNumber)
nNumber = DeviceCapabilities(sPrinterName, sPrinterPort, DC_PAPERNAMES, pNamesBuffer, IntPtr.Zero)
nNumber = DeviceCapabilities(sPrinterName, sPrinterPort, DC_PAPERS, IntPtr.Zero, IntPtr.Zero)
Dim pPapersBuffer As IntPtr = Marshal.AllocHGlobal(2 * nNumber)
nNumber = DeviceCapabilities(sPrinterName, sPrinterPort, DC_PAPERS, pPapersBuffer, IntPtr.Zero)
For nCurrent = 0 To nNumber - 1
Dim sName As String = Marshal.PtrToStringAuto(CType((CType(pNamesBuffer, Long) + (nStringSize * nCurrent)), IntPtr), 64)
Dim nIndex As Integer = sName.IndexOf(vbNullChar)
If (nIndex > -1) Then
sName = sName.Substring(0, nIndex)
Dim nPaper As Short = Marshal.ReadInt16(((pPapersBuffer + nCurrent * 2)))
Dim item As ComboboxItem = New ComboboxItem()
item.PaperName = sName
item.PaperSize = nPaper
ComboBox2.Items.Add(item)
If (nPaper = nPrinterPaperSize) Then
ComboBox2.SelectedIndex = nCurrent
End If
End If
Next
Marshal.FreeHGlobal(pNamesBuffer)
Marshal.FreeHGlobal(pPapersBuffer)
End With
Cursor = Cursors.Default
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim hPrinter As IntPtr
Dim pDefaults As New PRINTER_DEFAULTS()
Dim sPrinterName = PrinterSettings.InstalledPrinters(ComboBox1.SelectedIndex)
Dim bResult As Boolean = OpenPrinter(sPrinterName, hPrinter, pDefaults)
If (bResult = True) Then
Dim nBytesNeeded As Integer = -1
Dim nSize As Integer = -1
Dim pPrinterInfo As IntPtr = IntPtr.Zero
GetPrinter(hPrinter, 2, IntPtr.Zero, 0, nBytesNeeded)
pPrinterInfo = Marshal.AllocHGlobal(nBytesNeeded)
nSize = nBytesNeeded
If (Not GetPrinter(hPrinter, 2, pPrinterInfo, nSize, nBytesNeeded)) Then
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error())
End If
Dim PrinterInfo As PRINTER_INFO_2 = CType(Marshal.PtrToStructure(pPrinterInfo, GetType(PRINTER_INFO_2)), PRINTER_INFO_2)
Dim pDevMode As IntPtr = PrinterInfo.pDevMode
Dim DevMode As DEVMODE = CType(Marshal.PtrToStructure(pDevMode, GetType(DEVMODE)), DEVMODE)
DevMode.dmFields = DM_PAPERSIZE
DevMode.dmPaperSize = TryCast(ComboBox2.SelectedItem, ComboboxItem).PaperSize
Marshal.StructureToPtr(DevMode, pDevMode, False)
Marshal.StructureToPtr(PrinterInfo, pPrinterInfo, False)
Dim nReturn = DocumentProperties(IntPtr.Zero, hPrinter, sPrinterName, pDevMode, pDevMode, DM_IN_BUFFER Or DM_OUT_BUFFER)
nReturn = Convert.ToInt32(SetPrinter(hPrinter, 2, pPrinterInfo, 2))
SendMessageTimeout(New IntPtr(HWND_BROADCAST), WM_DEVMODECHANGE, IntPtr.Zero, sPrinterName, SMTO_NORMAL, 1000, IntPtr.Zero)
Marshal.FreeHGlobal(pPrinterInfo)
ClosePrinter(hPrinter)
End If
End Sub
Public Class ComboboxItem
Public Property PaperName As String
Public Property PaperSize As Short
Public Overrides Function ToString() As String
Return PaperName
End Function
End Class
End Class