Link to home
Start Free TrialLog in
Avatar of Clif
ClifFlag for United States of America

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(myPrinter, vbNull, DC_MAXEXTENT, ByVal 0&, ByVal 0&)
    pt = DeviceCapabilities_pt(myPrinter, 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/Properties) to "\\mynetwork2\printer2" works fine.

Any ideas?
Avatar of DarkoLord
DarkoLord
Flag of Slovenia image

Try to get the error with Err.LastDllError after using the CreateDC API

Darko
Avatar of Clif

ASKER

DarkoLord,

Err.LastDllError() returns 0
Avatar of zzzzzooc
zzzzzooc

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.
Avatar of Clif

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?
>>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);
Avatar of Clif

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/Properties
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
Avatar of Clif
Clif
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial