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:

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
WINSPOOLWINSPOOL
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

Windows 10 
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