-
Jun 18th, 2018, 04:56 PM
#1
Thread Starter
Hyperactive Member
How to get the printer name selected in the common dialog?
I want to get printer name selected in the common dialog.
For example, I show printer dialog like following code.
Code:
CommonDialog1.Flags = cdlPDReturnDC + cdlPDNoPageNums
CommonDialog1.PrinterDefault = False
CommonDialog1.Flags = 0
CommonDialog1.Orientation = cdlPortrait
CommonDialog1.CancelError = True
CommonDialog1.FontSize = 14
CommonDialog1.FontName = "Tahoma"
CommonDialog1.ShowPrinter
I want to get printer name selected in the common dialog.
How to get it?
-
Jun 18th, 2018, 05:13 PM
#2
Re: How to get the printer name selected in the common dialog?
VB6 basically just uses the default printer. There are ways you can change this default printer, but that's always what it's using.
Here's some code to get the name of the default printer, which is basically what you're asking for:
Code:
Option Explicit
'
Private Declare Function GetDefaultPrinterAPI Lib "winspool.drv" Alias "GetDefaultPrinterA" (ByVal sPrinterName As String, lPrinterNameBufferSize As Long) As Long
Private Sub Form_Load()
MsgBox GetDefaultPrinter
End Sub
Public Function GetDefaultPrinter() As String
GetDefaultPrinter = Space$(255)
GetDefaultPrinterAPI ByVal GetDefaultPrinter, 255
GetDefaultPrinter = RTrimNull(GetDefaultPrinter)
End Function
Public Function RTrimNull(s As String) As String
Dim i As Integer
i = InStr(s, vbNullChar)
If i Then
RTrimNull = Left$(s, i - 1)
Else
RTrimNull = s
End If
End Function
Enjoy,
Elroy
p.s. I just threw it all into Form1 to test it.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Jun 18th, 2018, 06:11 PM
#3
Thread Starter
Hyperactive Member
Re: How to get the printer name selected in the common dialog?
Actually I wanted to get the printer selected in the CommonDialog.
If I run the code, GetDefaultPrinter returns system default printer, not the printer selected in the CommonDialog.
In the screen capture, system default printer is "Bullzip PDF Printer".
I selected "Microsoft XPS Document" in the CommonDialog, but GetDefaultPrinter() returns "Bullzip PDF Printer", not "Microsoft XPS Document".
-
Jun 19th, 2018, 04:57 AM
#4
Re: How to get the printer name selected in the common dialog?
microsoft has another printer dialog, that you can download and use, that will return the printer selected in the dialog
unfortunately, on checking the link before posting, the link to that appears to have gone dead
from memory, i think the file was called printdlg.dll
there are some example here on the use of it
i do my best to test code works before i post it, but sometimes am unable to do so for some reason, and usually say so if this is the case.
Note code snippets posted are just that and do not include error handling that is required in real world applications, but avoid On Error Resume Next
dim all variables as required as often i have done so elsewhere in my code but only posted the relevant part
come back and mark your original post as resolved if your problem is fixed
pete
-
Jun 19th, 2018, 07:42 AM
#5
Re: How to get the printer name selected in the common dialog?
Hmmm, if you want it as it's clicked, you'd almost certainly have to use an API call to bring up the dialog, rather than the CommonDialog control.
Once doing it with the API, you may be able to set a callback procedure and monitor which printer is being clicked. And that's one of those UDTs (that's fed into the API) that's got some funky padding issues. In other words, it doesn't play well with VB6's UDT padding, so you have to do it with Byte array and some CopyMemory.
I don't have anything obvious in my toolbox to give you the printer that's clicked as it's clicked, but I suspect there may be something in the CodeBank. If it were me, I'd try searching around there, or possibly using Google with "site:vbforums.com" as part of the search.
Good Luck,
Elroy
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Jun 19th, 2018, 09:15 AM
#6
Re: How to get the printer name selected in the common dialog?
WOW, I thought I'd play around a bit with the lpfnPrintHook address and PD_ENABLEPRINTHOOK flag, but code that worked on Win7 doesn't seem to work on Win10 (1803). Specifically, I'm talking about the code in this post.
I even tried commenting out the call to lpfnSetupHook (along with the PD_ENABLESETUPHOOK flag), and it still crashed. Apparently Win10 no longer likes these CallBacks.
Given that, I guess the only robust solution to this is to subclass the Print dialog form with another thread (probably another process). And even then, you've got some work to figure out which printer is highlighted.
Good Luck,
Elroy
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Jun 19th, 2018, 10:54 AM
#7
Hyperactive Member
Re: How to get the printer name selected in the common dialog?
why carn't you just set the default printer in code with API , then show dialog which will have the correct printer set.
then once printed, put default printer back to the original. Thats what i do
-
Jun 19th, 2018, 11:02 AM
#8
Re: How to get the printer name selected in the common dialog?
k_zeon, How do you know which printer the user is going to select when shown the dialog so that you can preset it as the default?
I have seven selections on the printer dialog. I can't know ahead of time which device the users is going to select.
-
Jun 19th, 2018, 11:16 AM
#9
Thread Starter
Hyperactive Member
Re: How to get the printer name selected in the common dialog?
What is the API for default printer setting?
Last edited by jdy0803; Jun 19th, 2018 at 11:19 AM.
-
Jun 19th, 2018, 03:58 PM
#10
Re: How to get the printer name selected in the common dialog?
Here's code I've used virtually forever (and is extremely well exercised) for setting the default printer:
Code:
Option Explicit
'
Private Declare Function GetProfileString Lib "kernel32" Alias "GetProfileStringA" (ByVal lpAppName As String, ByVal lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long) As Long
Private Declare Function WriteProfileString Lib "kernel32" Alias "WriteProfileStringA" (ByVal lpszSection As String, ByVal lpszKeyName As String, ByVal lpszString As String) As Long
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
'
Private Const HWND_BROADCAST = &HFFFF
Private Const WM_WININICHANGE = &H1A
'
Public Function SetPrinterAsDefault(ByVal DeviceName As String) As Boolean
Dim Buffer As String
Dim r As Long
Dim sPrinterDevName As String
Dim DriverName As String
Dim PrinterPort As String
Dim DeviceLine As String
Dim l As Long
Dim iDriver As Integer
Dim iPort As Integer
'
' Set up for changing the default.
Buffer = Space(8192)
r = GetProfileString("windows", "Device", vbNullString, Buffer, Len(Buffer))
If r <> 0 Then
' Remove the wasted space
Buffer = Mid(Buffer, 1, r)
' Store the current default printer before we change it
sPrinterDevName = Mid(Buffer, 1, InStr(Buffer, ",") - 1)
' m_sPrevPrinterDriver = Mid(Buffer, InStr(Buffer, ",") + 1, InStrRev(Buffer, ",") - InStr(Buffer, ",") - 1)
' m_sPrevPrinterPort = Mid(Buffer, InStrRev(Buffer, ",") + 1)
End If
'
' If its not currently set as the default then set it...
If sPrinterDevName <> DeviceName Then
Buffer = Space(1024)
r = GetProfileString("PrinterPorts", DeviceName, vbNullString, Buffer, Len(Buffer))
'
' Parse the driver name and port name out of the buffer
DriverName = vbNullString
PrinterPort = vbNullString
' The driver name is first in the string terminated by a comma
iDriver = InStr(Buffer, ",")
If iDriver > 0 Then
' Strip out the driver name
DriverName = Left(Buffer, iDriver - 1)
' The port name is the second entry after the driver name separated by commas.
iPort = InStr(iDriver + 1, Buffer, ",")
If iPort > 0 Then
'Strip out the port name
PrinterPort = Mid(Buffer, iDriver + 1, iPort - iDriver - 1)
End If
End If
'
If DriverName <> vbNullString And PrinterPort <> vbNullString Then
DeviceLine = DeviceName & "," & DriverName & "," & PrinterPort
' Store the new printer information in the [WINDOWS] section of the WIN.INI file for the DEVICE= item
r = WriteProfileString("windows", "Device", DeviceLine)
If r Then
'Cause all applications to reload the INI file:
l = SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, "windows")
SetPrinterAsDefault = True
Else
SetPrinterAsDefault = False
End If
Else
SetPrinterAsDefault = False
End If
Else
SetPrinterAsDefault = True
End If
End Function
Enjoy,
Elroy
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Jun 19th, 2018, 04:23 PM
#11
Re: How to get the printer name selected in the common dialog?
there is also setdefaultprinter API
i do my best to test code works before i post it, but sometimes am unable to do so for some reason, and usually say so if this is the case.
Note code snippets posted are just that and do not include error handling that is required in real world applications, but avoid On Error Resume Next
dim all variables as required as often i have done so elsewhere in my code but only posted the relevant part
come back and mark your original post as resolved if your problem is fixed
pete
-
Jun 19th, 2018, 05:20 PM
#12
Re: How to get the printer name selected in the common dialog?
Some changes have been made to spooled printing in desktop Windows, starting in Windows 10 1511 or so. I don't know of any authoritative list of the changes, but they include things like "Let Windows manage my default printer."
How to set a default printer in Windows 10
-
Jun 19th, 2018, 07:47 PM
#13
Re: How to get the printer name selected in the common dialog?
Originally Posted by dilettante
Some changes have been made to spooled printing in desktop Windows, starting in Windows 10 1511 or so. I don't know of any authoritative list of the changes, but they include things like "Let Windows manage my default printer."
How to set a default printer in Windows 10
Yeah, I haven't heard any complaints with my software, and I know that people change printers within it all the time (which executes the code in post #10). And my users are slowly moving to Windows 10, with quite a few on it now.
However, I also haul my Windows 10 laptop all over the place, plugging in various printers at various user sites. The new Windows 10 printer management is pretty nice. Apparently, it poles the printers to see which one is available, and makes a recommendation based on availability. I like it, and it seems to be very backwards-compatible. So all is good.
Y'all Take Care,
Elroy
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Jun 19th, 2018, 09:47 PM
#14
Re: How to get the printer name selected in the common dialog?
To answer the original question, I thought the dialog changed the current default so you could just get the name from the Printer object?
If not, you can look at something like Krool's CommonDialog module, which does the (very complicated) work of retrieving the name from the PrintDlg API, which is better than the control anyway.
-
Jun 19th, 2018, 10:39 PM
#15
Re: How to get the printer name selected in the common dialog?
From this project, download the zip file at the end of the first post, but you only need to use cCDlg.cls that is in the "others" folder.
It is a CommonDialog replacement that has a property to retrieve what printer was selected. The property name is DeviceName.
Sample code:
Code:
Dim d As New CDlg
d.ShowPrinter
If Not d.Cancelled Then
MsgBox d.DeviceName
End If
-
Jun 20th, 2018, 08:49 AM
#16
Re: How to get the printer name selected in the common dialog?
Originally Posted by fafalone
To answer the original question, I thought the dialog changed the current default so you could just get the name from the Printer object?
If not, you can look at something like Krool's CommonDialog module, which does the (very complicated) work of retrieving the name from the PrintDlg API, which is better than the control anyway.
Hi fafalone,
That's what I also originally thought. However, I progressed to the idea that he wanted the printer name as it was clicked but not necessarily double-clicked (i.e., selected) in the common dialog. The only way to do that was with the API callback, but I couldn't get that working under Windows 10.
All The Best,
Elroy
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Jun 20th, 2018, 11:00 AM
#17
Re: How to get the printer name selected in the common dialog?
Originally Posted by Elroy
Hi fafalone,
That's what I also originally thought. However, I progressed to the idea that he wanted the printer name as it was clicked but not necessarily double-clicked (i.e., selected) in the common dialog. The only way to do that was with the API callback, but I couldn't get that working under Windows 10.
All The Best,
Elroy
In my CommonControls CommonDialog is a property called 'HookEvents'. If true, you may declare WithEvents with the class to read the messages.
-
Jun 20th, 2018, 09:13 PM
#18
Re: How to get the printer name selected in the common dialog?
Does it work on Win10? This seems to a running theme lately, Win10 is breaking APIs.
-
Jun 21st, 2018, 01:17 AM
#19
Re: How to get the printer name selected in the common dialog?
I don't think Windows 10 is "breaking APIs" so much as it is breaking code hacks. We see a lot of people proudly using Windows wrong here, then crying when reliance on quirks fall apart on them.
If you want long term stability you need to stick to documented operation as closely as possible. That can still change but it changes far less often than undocumented behaviors do.
Either way crying and kicking helps nobody. Windows 10 is not going away and is not going to stop evolving.
-
Jun 21st, 2018, 07:24 AM
#20
Re: How to get the printer name selected in the common dialog?
*shakes head in puzzlement*
Dil, I'm not sure I saw anyone crying and kicking. And I think we're all acutely aware that Win10 isn't going anywhere. But the code in this post seemed to work fine prior to Win10, and now it just freezes my system immediately after the first CallBack message box is clicked.
The last system I thoroughly checked it on was Win7-64-bit. I've still got that machine. It would take a bit to power it up, but I'm willing to do that if need be to get this sorted.
Best Regards,
Elroy
EDIT1: Well, "freezes my system" isn't quite right. But it does freeze that copy of VB6.
Last edited by Elroy; Jun 21st, 2018 at 07:30 AM.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Jun 21st, 2018, 11:18 AM
#21
Re: How to get the printer name selected in the common dialog?
Elroy, does my CommonDialog freeze on your copy on win10?
-
Jun 21st, 2018, 12:57 PM
#22
Re: How to get the printer name selected in the common dialog?
Let me try it. I assume you're just talking about the rolled-up OCX. That's what I'll try first, as it's easiest.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Jun 21st, 2018, 01:11 PM
#23
Re: How to get the printer name selected in the common dialog?
Hmmm, ok, I'm confused. Krool, where is your CommonDialog? I downloaded your OCX (found here), unzipped it, threw it into SysWOW64, and registered it with RegSvr32.
Then, I started a new project and added it through Components, but I don't see the CommonDialog. Here's a screenshot of my Toolbox after your OCX has been added:
I hovered over each new control, and none of them seem to be a CommonDialog.
I'll try it now from your demo project.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Jun 21st, 2018, 01:38 PM
#24
Re: How to get the printer name selected in the common dialog?
Hmmm, ok, it seems to be working in your demo project. It wasn't a UC, but I found it anyway. I'm assuming we're talking about your CommonDialog.cls class.
To test it, I first put this at the top of your MainForm:
Code:
Dim WithEvents cd As CommonDialog
And then, I put a new button on that form (Command5), and put this in it:
Code:
Private Sub Command5_Click()
Set cd = New CommonDialog
cd.HookEvents = True
cd.ShowPrinter
End Sub
I also placed this in that MainForm code:
Code:
Private Sub cd_InitDialog(ByVal Action As Integer, ByVal hDlg As Long)
Debug.Print "InitDialog"
End Sub
It did fire that cd_InitDialog event when Command5 was clicked.
To further test, I looked at your ShowPrinter() code within CommonDialog.cls, and saw where you were setting the callback. You seemed to use the same callback for both the SetupHook and the PrintHook (ComCtlsCdlPDCallbackProc), so I went there. To further test, I just placed the following at the top of that callback procedure:
Code:
Debug.Print "Callback ";
Interestingly, it streamed that "Callback " string in my Immediate Window, so all seems to be good.
I glanced at your setup of the PRINTDLG UDT. I checked the way you use Len(PDLG), and it correctly reports 66 bytes. I also noticed you're doing something fancy with Word Endianness. I didn't study it in detail so I'm not sure what that's about. But I'm thinking that has more to do with the funky way VB6 pads UDTs and your work-around.
Obviously it works, so my CopyMemory approach is apparently doing something wrong. I'll study it more a bit later.
Elroy
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Jun 21st, 2018, 02:35 PM
#25
Re: How to get the printer name selected in the common dialog?
Problem here is the uneven (5) integers in a row and then Longs. That's why Len() instead of LenB() must be used. (2 bytes overhang)
But thats not enough to just report the necessary length of the struct.
The actual struct needs to represent this quirk to not confuse VB6, that's why the fancy word splits are in the Struct.
Most APIs also consider such padding so VB6's LenB() is most of time accurate but obviously not for this one.
Last edited by Krool; Jun 21st, 2018 at 10:53 PM.
Reason: Typo
-
Jun 21st, 2018, 03:22 PM
#26
Re: How to get the printer name selected in the common dialog?
Originally Posted by Krool
Problem here is the uneven (5) integers in a row and then Longs. That's why Len() instead of LenB() must be used. (2 bit overhang)
But thats not enough to just report the necessary length of the struct.
The actual struct needs to represent this quirk to not confuse VB6, that's why the fancy word splits are in the Struct.
Most APIs also consider such padding so VB6's LenB() is most of time accurate but obviously not for this one.
Yeah, I thought I had done it correctly with a Byte array (and some CopyMemory), but apparently I need to take another look. I've got some other stuff going on, so I'll have to look at it later.
Take Care,
Elroy
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|