Solved

CreateDC Stopped Working

Posted on 2004-09-01
9
845 Views
Last Modified: 2012-06-21
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:
http://www.experts-exchange.com/Programming/Programming_Languages/Visual_Basic/Q_21113934.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?
0
Comment
Question by:Clif
  • 4
  • 2
9 Comments
 
LVL 22

Expert Comment

by:DarkoLord
Comment Utility
Try to get the error with Err.LastDllError after using the CreateDC API

Darko
0
 
LVL 10

Author Comment

by:Clif
Comment Utility
DarkoLord,

Err.LastDllError() returns 0
0
 
LVL 17

Expert Comment

by:zzzzzooc
Comment Utility
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.
0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 10

Author Comment

by:Clif
Comment Utility
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?
0
 
LVL 17

Expert Comment

by:zzzzzooc
Comment Utility
>>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);
0
 
LVL 10

Author Comment

by:Clif
Comment Utility
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."
0
 
LVL 10

Accepted Solution

by:
Clif earned 0 total points
Comment Utility
I fixed this myself.

I removed the lable printer from the Start/Settings/Printer list and reinstalled it and now I am able to print.

But, if I call the code to change the orientation, it will fail again and I must remove and reinstall.
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now