CreateDC / CreateIC Printer Fails on Windows 10 with ERROR_NOT_SUPPORTED

I am trying to call CreateDC to create a printer device context:

 printerDC := CreateDC('WINSPOOL', 'HP DeskJet 930C/932C/935C', nil, nil); 

The code works in Windows 7, but does not work in Windows 10 - it returns null .

I really use a real printer:

enter image description here

What to convey

The MSDN documentation says that if you want to get the printer device context, you must pass WINSPOOL as a driver:

How to: get printer device context

To display a specific printer, you must specify "WINSPOOL" as the device and pass the correct printer name to CreateDC . You can also pass the DEVMODE structure when calling CreateDC if you want to provide device-specific initialization data for the device driver when creating the device context.

The following example shows a CreateDC call in which the WINSPOOL driver is selected, and the printer name is specified by name. C ++

 printerDC = CreateDC( L"WINSPOOL", printerName, NULL, NULL); 

I mention this because there is a lot of code that goes through:

  • empty line
  • Null
  • device name
  • driver name
  • WINSPOOL
  • WINSPOOL

Background

Deep in the Delphi VCL Vcl.Printers there is a call to the Windows CreateIC function. On my Windows 10 desktop, calls fail (it returns NULL , not the actual context of the information).

The CreateIC function CreateIC not document any method of failure. It also does not document that it supports a GetLastError call to get an error. But if I call GetLastError , I get error code 50 :

 ERROR_NOT_SUPPORTED 50 (0x32) The request is not supported. 

Minimum reproducible

I extracted the code from Vcl.Printers.pas and pushed it down to a simple reproducible pattern:

 procedure TForm1.Button1Click(Sender: TObject); var driver, device, output: string; dc: HDC; le: DWORD; begin driver := ''; device := 'Microsoft XPS Document Writer'; output := ''; dc := CreateIC(PChar(driver), PChar(device), PChar(output), nil); if dc = 0 then begin le := GetLastError; raise Exception.CreateFmt('Could not get information context for printer "%s": %s (%d)', [device, SysErrorMessage(le), le]); end; end; 

The code does not work on my Windows 10 desktop, but it works on Windows 7.

And in both cases, I use the same printer:

  • Windows 7

    enter image description here

  • Windows 10 enter image description here

What am I doing wrong?

CreateDC also does not work

CreateIC is just a β€œlite” form of CreateDC (you can use it to get device information, but you cannot draw GDI with it). This also means that CreateDC also does not work on Windows 10:

 procedure TForm1.Button1Click(Sender: TObject); var driver, device: string; dc: HDC; le: DWORD; begin driver := ''; device := 'Microsoft XPS Document Writer'; dc := CreateDC(PChar(driver), PChar(device), nil, nil); if dc = 0 then begin le := GetLastError; raise Exception.CreateFmt('Could not get device context for printer "%s": %s (%d)', [device, SysErrorMessage(le), le]); end; end; 

Some people have suggested duplicating the device name in the driver name:

 CreateDC('Microsoft XPS Document Writer', 'Microsoft XPS Document Writer', nil, nil); 

and I also saw an attempt to place WINSPOOL in the driver name:

 CreateDC('WINSPOOL', 'Microsoft XPS Document Writer', nil, nil); 

All printers

I started this question thinking it was just CreateIC .

  • then I found that CreateDC also fails, so I updated the header
  • then I thought it was because I used the Microsoft XPS Document Writer , so I updated the title
  • then I found all printers in Windows 10, so I updated the header again

This is a natural evolution, as people offer things, and I will learn more about the nature of the problem.

 | Driver | Device | Result | |------------------------------------|---------------------------------|--------| | '' (empty string) | 'Microsoft XPS Document Writer' | Fails | | 'Microsoft XPS Document Writer' | 'Microsoft XPS Document Writer' | Fails | | 'WINSPOOL' | 'Microsoft XPS Document Writer' | Fails | | nil | 'Microsoft XPS Document Writer' | Fails | | 'Microsoft XPS Document Writer v4' | 'Microsoft XPS Document Writer' | Fails | | '' (empty string) | 'HP DeskJet 930C/932C/935C' | Fails | | 'HP DeskJet 930C/932C/935C' | 'HP DeskJet 930C/932C/935C' | Fails | | 'WINSPOOL' | 'HP DeskJet 930C/932C/935C' | Fails | | nil | 'HP DeskJet 930C/932C/935C' | Fails | 

For everyone I know, calling CreateDC to create a display device context also breaks in Windows 10. Like you, I have not tested it.

Reading bonuses

1 not me; Embarcadero

+5
source share

Source: https://habr.com/ru/post/1232879/


All Articles