Clif
asked on
CreateDC Stopped Working
All of a sudden CreateDC stopped working for one particular printer.
I am printing through the API.
My code looks something like this:
'----- Code snippet -----
Private Declare Function CreateDC Lib "gdi32" Alias "CreateDCA" _
(ByVal lpDriverName As String, _
ByVal lpDeviceName As String, _
ByVal lpOutput As Long, _
ByVal lpInitData As Long) As Long
Private Declare Function DeviceCapabilities Lib "winspool.drv" Alias "DeviceCapabilitiesA" _
(ByVal lpDeviceName As String, _
ByVal lpPort As String, _
ByVal iIndex As Long, _
lpOutput As Any, _
lpDevMode As Any) As Long
Private Declare Function DeviceCapabilities_pt Lib "winspool.drv" Alias "DeviceCapabilitiesA" _
(ByVal lpDeviceName As String, _
ByVal lpPort As String, _
ByVal iIndex As Long, _
lpOutput As Any, _
lpDevMode As Any) As Points
Private Const DC_MAXEXTENT = 5
Private Type Points
x As Integer
y As Integer
End Type
Private Sub Command1_Click()
Dim result As Long 'Return value for calling API functions
Dim hPrintDc As Long 'Handle to printer dc
Dim nPPIx As Integer
Dim nPPIy As Integer
Dim myPrinter As String
myPrinter = "\\mynetwork2\printer2"
Dim pt As Points
result = DeviceCapabilities(myPrint er, vbNull, DC_MAXEXTENT, ByVal 0&, ByVal 0&)
pt = DeviceCapabilities_pt(myPr inter, vbNull, DC_MAXEXTENT, ByVal 0&, ByVal 0&)
nPPIx = (pt.x / 6) * 2
nPPIy = (pt.y / 4) * 2
hPrintDc = CreateDC("WINSPOOL", myPrinter, 0, 0)
'
'
'
End Sub
'----- End code snippet -----
If I change myPrinter to "\\mynetwork1\printer1" it works fine.
"\\mynetwork1\printer1" is an HP LaserJet
"\\mynetwork2\printer2" is an Zebra label printer
It worked up until yesterday afternoon. I had been trying to change the printer orientation and was using the HP for testing.
(The code to change orientation can be found here:
https://www.experts-exchange.com/questions/21113934/API-Printing-Orientation.html)
Once it started working on the HP, I switched over the \\mynetwork2\printer2 and got nothing from the label printer.
I single stepped though the code and CreateDC returns 0. The API call GetLastError() returns 0.
I removed the code to change the orientation but still get nothing.
I've rebooted my machine and the label printer, still nothing.
Printing to "\\mynetwork1\printer1" works fine.
Printing a test page (through Windows 2000's Settings/Printers/Properti es) to "\\mynetwork2\printer2" works fine.
Any ideas?
I am printing through the API.
My code looks something like this:
'----- Code snippet -----
Private Declare Function CreateDC Lib "gdi32" Alias "CreateDCA" _
(ByVal lpDriverName As String, _
ByVal lpDeviceName As String, _
ByVal lpOutput As Long, _
ByVal lpInitData As Long) As Long
Private Declare Function DeviceCapabilities Lib "winspool.drv" Alias "DeviceCapabilitiesA" _
(ByVal lpDeviceName As String, _
ByVal lpPort As String, _
ByVal iIndex As Long, _
lpOutput As Any, _
lpDevMode As Any) As Long
Private Declare Function DeviceCapabilities_pt Lib "winspool.drv" Alias "DeviceCapabilitiesA" _
(ByVal lpDeviceName As String, _
ByVal lpPort As String, _
ByVal iIndex As Long, _
lpOutput As Any, _
lpDevMode As Any) As Points
Private Const DC_MAXEXTENT = 5
Private Type Points
x As Integer
y As Integer
End Type
Private Sub Command1_Click()
Dim result As Long 'Return value for calling API functions
Dim hPrintDc As Long 'Handle to printer dc
Dim nPPIx As Integer
Dim nPPIy As Integer
Dim myPrinter As String
myPrinter = "\\mynetwork2\printer2"
Dim pt As Points
result = DeviceCapabilities(myPrint
pt = DeviceCapabilities_pt(myPr
nPPIx = (pt.x / 6) * 2
nPPIy = (pt.y / 4) * 2
hPrintDc = CreateDC("WINSPOOL", myPrinter, 0, 0)
'
'
'
End Sub
'----- End code snippet -----
If I change myPrinter to "\\mynetwork1\printer1" it works fine.
"\\mynetwork1\printer1" is an HP LaserJet
"\\mynetwork2\printer2" is an Zebra label printer
It worked up until yesterday afternoon. I had been trying to change the printer orientation and was using the HP for testing.
(The code to change orientation can be found here:
https://www.experts-exchange.com/questions/21113934/API-Printing-Orientation.html)
Once it started working on the HP, I switched over the \\mynetwork2\printer2 and got nothing from the label printer.
I single stepped though the code and CreateDC returns 0. The API call GetLastError() returns 0.
I removed the code to change the orientation but still get nothing.
I've rebooted my machine and the label printer, still nothing.
Printing to "\\mynetwork1\printer1" works fine.
Printing a test page (through Windows 2000's Settings/Printers/Properti
Any ideas?
ASKER
DarkoLord,
Err.LastDllError() returns 0
Err.LastDllError() returns 0
I don't have a printer on this PC so I can't test so..
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_27uc.asp
You'll need to verify that the driver, printer device and ports are correct. You may also have to set the printer device to the default to print.
Information for CreateDC for printer-output:
· lpszDriver
Applications written for earlier versions of Windows used this parameter to specify the filename (without extension) of the device driver.
Windows 95: In Win32-based applications, this parameter is ignored and should be NULL, with one exception: You may obtain a display device context by specifying the null-terminated string “DISPLAY”. If this parameter is “DISPLAY”, all other parameters must be NULL.
Windows NT: Points to a null-terminated character string that specifies either “DISPLAY” for a display driver, or the name of a printer driver, which is usually “WINSPOOL”.
· lpszDevice
Points to a null-terminated character string that specifies the name of the specific output device being used, as shown by the Print Manager (for example, “Epson FX-80”). It is not the printer model name. The lpszDevice parameter must be used.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_27uc.asp
You'll need to verify that the driver, printer device and ports are correct. You may also have to set the printer device to the default to print.
Information for CreateDC for printer-output:
· lpszDriver
Applications written for earlier versions of Windows used this parameter to specify the filename (without extension) of the device driver.
Windows 95: In Win32-based applications, this parameter is ignored and should be NULL, with one exception: You may obtain a display device context by specifying the null-terminated string “DISPLAY”. If this parameter is “DISPLAY”, all other parameters must be NULL.
Windows NT: Points to a null-terminated character string that specifies either “DISPLAY” for a display driver, or the name of a printer driver, which is usually “WINSPOOL”.
· lpszDevice
Points to a null-terminated character string that specifies the name of the specific output device being used, as shown by the Print Manager (for example, “Epson FX-80”). It is not the printer model name. The lpszDevice parameter must be used.
ASKER
zzzzzooc,
I looked at the link and used GetPrinter to acquire the driver name to use in CreateDC() instead of "WINSPOOL"
It still doesn't work.
Amazingly enough, GetPrinter() requires a handle which is gotten from OpenPrinter(), which did work.
Curiouser and curiouser.
Why would OpenPrinter() work but CreateDC() not work? Why would CreateDC() work at one time but stop working? And finally why, when CreateDC() fails, it doesn't throw a retrievable error?
I looked at the link and used GetPrinter to acquire the driver name to use in CreateDC() instead of "WINSPOOL"
It still doesn't work.
Amazingly enough, GetPrinter() requires a handle which is gotten from OpenPrinter(), which did work.
Curiouser and curiouser.
Why would OpenPrinter() work but CreateDC() not work? Why would CreateDC() work at one time but stop working? And finally why, when CreateDC() fails, it doesn't throw a retrievable error?
>>Why would CreateDC() work at one time but stop working?
You could originally print with the Label Printer using your method? From your post, it seems you mean it worked for one printer but not the other.
>>And finally why, when CreateDC() fails, it doesn't throw a retrievable error?
As mentioned on the link provided:
"When using this method, you must specify a valid printer, driver, and port. If they are invalid, the APIs do not fail but the result is not defined."
I'm not too familiar with Print API so I can't give any certain answers. If OpenPrinter() works with the printer's device-name, you may want to "stick" to using "winspool" as the driver unless your Label Printer comes with it's own unique driver(s). You may also want to specify a port for the printer and try setting it as default.
CreateDC(szDriver, szPrinter, szPort, NULL);
You could originally print with the Label Printer using your method? From your post, it seems you mean it worked for one printer but not the other.
>>And finally why, when CreateDC() fails, it doesn't throw a retrievable error?
As mentioned on the link provided:
"When using this method, you must specify a valid printer, driver, and port. If they are invalid, the APIs do not fail but the result is not defined."
I'm not too familiar with Print API so I can't give any certain answers. If OpenPrinter() works with the printer's device-name, you may want to "stick" to using "winspool" as the driver unless your Label Printer comes with it's own unique driver(s). You may also want to specify a port for the printer and try setting it as default.
CreateDC(szDriver, szPrinter, szPort, NULL);
ASKER
zzzzzooc,
Sorry, I thought I had been more clear.
Here is the sequence of events:
1. The code worked on the label printer but the output was in the wrong orientation for my needs
2. I received code to change the orientation of a print out.
3. For testing (to save labels) I tested the orientation code on the HP printer.
4. Once I was satisfied that the orientation code worked, I switched back to the label printer.
5. At this point, the label printer no longer printed from my code.
6. Believing it may have been something in the orientation code, I removed that part, effectively putting the code back to what it was when it worked.
7. The label printer still did not print from my code.
8. I rebooted my machine and the printer.
9. The label printer still did not print from my code.
10. I tried a test print from Settings/Printers/Properti es
11. The test label printed fine.
12. Tried my code again.
13. The label printer still did not print from my code.
And here we are.
According to all information I have found on using CreateDC(), you are not allowed to put any value in the third parameter (lpszOutput) when working with 32-bit code. To quote Microsoft:
"This parameter is ignored and should be set to NULL. It is provided only for compatibility with 16-bit Windows."
Sorry, I thought I had been more clear.
Here is the sequence of events:
1. The code worked on the label printer but the output was in the wrong orientation for my needs
2. I received code to change the orientation of a print out.
3. For testing (to save labels) I tested the orientation code on the HP printer.
4. Once I was satisfied that the orientation code worked, I switched back to the label printer.
5. At this point, the label printer no longer printed from my code.
6. Believing it may have been something in the orientation code, I removed that part, effectively putting the code back to what it was when it worked.
7. The label printer still did not print from my code.
8. I rebooted my machine and the printer.
9. The label printer still did not print from my code.
10. I tried a test print from Settings/Printers/Properti
11. The test label printed fine.
12. Tried my code again.
13. The label printer still did not print from my code.
And here we are.
According to all information I have found on using CreateDC(), you are not allowed to put any value in the third parameter (lpszOutput) when working with 32-bit code. To quote Microsoft:
"This parameter is ignored and should be set to NULL. It is provided only for compatibility with 16-bit Windows."
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Darko