Re: How to OPEN native PRINTER DIALOG -- Please HELP !!



Hi,

<pamelafluente@xxxxxxxxx> wrote in message
news:1130805112.344751.181390@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
> Dear Burt,
>
> I have tried your code (on XP). Actually it is quite complete. You
> have practically
> done the all job. I also appreciated your correction about setting
> the printer name.
> You are really an angel!
>
> I have not tried yet to print because now its night here and I am
> not at my office,
> but the printer properties dialog pops up fine. In case of problems
> I will tell you.
>
> If I may, I would need some further info for some refinements.
> I am loading the printer names in a combo (or perhaps I will use a
> treeview):
> with something like:
>
> -------------------------------------
> Private Sub YourPrinterSettingsDialog_Load(ByVal sender...) Handles
> MyBase.Load
>
> Dim PrinterNames As New ArrayList
> For Each PrinterName As String In
> PrinterSettings.InstalledPrinters
> Try
> PrinterNames.Add(PrinterName)
> Catch
> End Try
> Next PrinterName
> Me.ComboBoxPrinterNames.Items.AddRange(PrinterNames.ToArray)
>
> End Sub
> ------------------------------------
>
> I need to recognize: 1. the Default Printer, 2. Network printers, to
> change the appearance
> of their icons. So, I guess, I need 2 boolean functions:
>
> function IsDefaulPrinter(PrinterName as string) as boolean
> function IsNetworkPrinter(PrinterName as string) as boolean
> (others assumed local, I guess)

I understand you want to customize the PrintDialog, is there anything in
particular that you want to change or add, it is possible to create your
own, but it will involve a lot of pinvoke.

About default and network printers, it's not that simple, if you want to do
this for all printers then you need to think about speed. You can use the
native function EnumPrinters(see MSDN) but it gets complicated because a
different level is needed for wxp/2000 or w9x/me.

The example shows you how you can do it using 2 additional classes:
PrinterInfo (name, isdefault, isnetwork)
PrinterApi (thin wrapper around w32 native Printer Functions)

YourPrintDialog.vb
------------------
Public Class YourPrintDialog
' ....
Private Sub LoadPrinters()
ComboBoxPrinterNames.Clear()

For Each pi As PrinterInfo In PrinterInfo.InstalledPrinters
Console.WriteLine("Name={0} Def={1} Network={2}", _
pi.Name, pi.IsDefault, pi.IsNetwork)

ComboBoxPrinterNames.Items.Add(pi.Name)
If (pi.IsDefault) Then ComboBoxPrinterNames.Text = pi.Name
Next
End Sub
' ....
End Class


PrinterInfo.vb
--------------
Public Class PrinterInfo

Public Name As String
Public IsDefault As Boolean
Public IsNetwork As Boolean

Public Shared ReadOnly Property InstalledPrinters() As PrinterInfo()
Get
Dim infos As New ArrayList
If (Environment.OSVersion.Platform = PlatformID.Win32NT) Then
' window xp,2000
Dim DefName As String = PrinterApi.GetDefPrinter()

For Each pi4 As PrinterApi.PRINTER_INFO_4 In _
PrinterApi.EnumInfo4( _
PrinterApi.PRINTER_ENUM_LOCAL Or _
PrinterApi.PRINTER_ENUM_CONNECTIONS)

Dim pi As New PrinterInfo
pi.Name = pi4.PrinterName
pi.IsDefault = Equals(pi4.PrinterName, DefName)
pi.IsNetwork = (pi4.Attributes And
PrinterApi.PRINTER_ATTRIBUTE_NETWORK) > 0
infos.Add(pi)
Next
Else
' windows 95,98,me
For Each pi5 As PrinterApi.PRINTER_INFO_5 In _
PrinterApi.EnumInfo5(PrinterApi.PRINTER_ENUM_LOCAL)
Dim pi As New PrinterInfo
pi.Name = pi5.PrinterName
pi.IsDefault = (pi5.Attributes And
PrinterApi.PRINTER_ATTRIBUTE_DEFAULT) > 0
pi.IsNetwork = (pi5.Attributes And
PrinterApi.PRINTER_ATTRIBUTE_NETWORK) > 0
infos.Add(pi)
Next
End If
Return infos.ToArray(GetType(PrinterInfo))
End Get
End Property
End Class


PrinterApi.vb
--------------
Imports System.Runtime.InteropServices
Imports System.Text

Public Class PrinterApi

Private Declare Auto Function EnumPrinters Lib "winspool.drv" ( _
ByVal flags As Int32, ByVal name As String, ByVal level As Int32, _
ByVal pPrinterEnum As IntPtr, ByVal cbBuf As Int32, _
ByRef pcbNeeded As Int32, ByRef pcReturned As Int32) As Int32

Private Declare Auto Function GetDefaultPrinter Lib "winspool.drv" ( _
ByVal szBuffer As StringBuilder, _
ByRef cchBuffer As Int32) As Int32

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Public Class PRINTER_INFO_4
Public PrinterName As String
Public ServerName As String
Public Attributes As Integer
End Class

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Public Class PRINTER_INFO_5
Public PrinterName As String
Public PortName As String
Public Attributes As Integer
Public DeviceNotSelectedTimeout As Integer
Public TransmissionRetryTimeout As Integer
End Class

Public Const PRINTER_ATTRIBUTE_NETWORK As Int32 = &H10
Public Const PRINTER_ENUM_CONNECTIONS As Int32 = &H4
Public Const PRINTER_ENUM_LOCAL As Int32 = &H2
Public Const PRINTER_ATTRIBUTE_DEFAULT As Int32 = &H4

Public Shared Function GetDefPrinter() As String
Dim sbName As New StringBuilder(32)
GetDefaultPrinter( sbName, 32 )
return sbName.ToString()

End Function

Public Shared Function EnumInfo4(ByVal Flags As Int32) As PRINTER_INFO_4()
' level 4 enum
Return DirectCast( _
EnumInfo(4, Flags, GetType(PRINTER_INFO_4)), _
PRINTER_INFO_4())

End Function

Public Shared Function EnumInfo5(ByVal Flags As Int32) As PRINTER_INFO_5()
' level 5 enum
Return DirectCast( _
EnumInfo(5, Flags, GetType(PRINTER_INFO_5)), _
PRINTER_INFO_5())

End Function

Private Shared Function EnumInfo(ByVal Level As Int32, _
ByVal Flags As Int32, ByVal InfoType As Type) As Object()

Dim cbNeeded As Int32, cReturned As Int32
Dim pBuffer As IntPtr, pBuf As IntPtr
Dim pi As Object
Dim infos As New ArrayList

' enumerate printers
EnumPrinters(Flags, Nothing, Level, IntPtr.Zero, 0, cbNeeded, cReturned)
pBuffer = Marshal.AllocHGlobal(cbNeeded)

EnumPrinters(Flags, Nothing, Level, pBuffer, cbNeeded, cbNeeded,
cReturned)

pBuf = pBuffer
For i As Int32 = 0 To cReturned - 1
pi = Marshal.PtrToStructure(pBuf, InfoType)
infos.Add(pi)

pBuf = New IntPtr(pBuf.ToInt64() + Marshal.SizeOf(InfoType))
Next
Marshal.FreeHGlobal(pBuffer)
Return infos.ToArray(InfoType)

End Function
End Class

HTH,
Greetings




>
> Do you know how to make these functions?
> Any suggestion is very welcome. Thanks,
>
> -Pamela
>


.



Relevant Pages

  • Re: MapiSendMail and web browser
    ... Public Shared Function SendMail(ByVal strAttachmentFileName As String, ... Dim winhandle As IntPtr = New IntPtr ... Public Class MapiMessage ...
    (microsoft.public.win32.programmer.messaging)
  • Load registry hive (AdjustTokenPrivileges error)
    ... Public PrivilegeCount As Int32 ... Public Function RegLoadKey(ByVal hKey As Int32, ... String, ByVal lpFile As String) As Int32 ... Dim strKeyName As String ...
    (microsoft.public.vb.winapi)
  • Load registry hive (AdjustTokenPrivileges error)
    ... Public PrivilegeCount As Int32 ... Public Function RegLoadKey(ByVal hKey As Int32, ... String, ByVal lpFile As String) As Int32 ... Dim strKeyName As String ...
    (microsoft.public.dotnet.languages.vb)
  • Re: thrown exception in Marshal.PtrToStructure
    ... "Bill McCarthy" wrote: ... Public Const PRINTER_ENUM_SHARED As Int32 = 20 ... Dim pDescription As String ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Migrating from VB6 and Printer object
    ... You can use the GetPrinter API call to get all the information (such as Port name) - e.g. ... ByRef phPrinter As Int32, _ ... Public pServerName As String ... Dim dmOut As New DEVMODE ...
    (microsoft.public.dotnet.languages.vb)

Loading