打印机 CreateDC/CreateIC 在 Windows 10 上失败并出现 ERROR_NOT_SUPPORTED

问题描述 投票:0回答:1

我正在尝试调用

CreateDC
来创建打印机设备上下文:

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

该代码在 Windows 7 中有效,但在 Windows 10 中失败 - 返回

null

我真的在使用真正的打印机:

要通过什么

MSDN 文档 说,如果您想获取打印机设备上下文,则必须传递

WINSPOOL
作为 驱动程序

如何:检索打印机设备上下文

要渲染到特定打印机,您必须指定“WINSPOOL”作为设备,并将打印机的正确名称传递给 CreateDC。如果您想在创建设备上下文时为设备驱动程序提供特定于设备的初始化数据,您还可以在对 CreateDC 的调用中传递 DEVMODE 结构。

以下示例显示了对 CreateDC 的调用,其中选择了“WINSPOOL”驱动程序并按名称指定了打印机名称。 C++

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

我提到它,因为有很多代码可以通过:

  • 空字符串
  • 设备名称
  • 司机姓名
  • winspool
  • WINSPOOL

背景

Vcl.Printers
的Delphi VCL框架深处是对Windows函数
CreateIC
的调用。在我的 Windows 10 桌面上,调用失败(返回 NULL 而不是有效的 信息上下文)。

CreateIC
函数没有记录任何可能失败的方式。它也没有记录它支持调用
GetLastError
来获取错误。但如果我打电话
GetLastError
我会收到错误代码 50:

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

最小可重复性

我从 Vcl.Printers.pas 中提取了代码,并将其归结为一个简单的可重现示例:

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;    

代码在我的 Windows 10 桌面上失败,但在 Windows 7 上运行。

在这两种情况下我都使用同一台打印机:

  • Windows 7

  • Windows 10

1做错了什么?

CreateDC也失败

CreateIC
只是 CreateDC
“轻量级”
形式(您可以使用它来获取有关设备的信息,但不能用它绘制 GDI)。这也意味着
CreateDC
在 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;    

有些人建议将设备名称复制到驱动程序名称中: CreateDC('Microsoft XPS Document Writer', 'Microsoft XPS Document Writer', nil, nil);

并且我也看到尝试将

WINSPOOL放在驱动程序名称中:

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

都是打印机

我开始提出这个问题时认为这只是

CreateIC


然后我发现

CreateDC
    也失败了,所以我更新了标题
  • 然后我以为是因为我碰巧使用了
    Microsoft XPS Document Writer
  • ,所以我更新了标题
  • 然后我发现都是Windows 10上的打印机,所以我又更新了标题
  • 这是人们提出建议的自然演变,我发现了更多关于问题本质的信息。
| 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 |

据我所知,调用
CreateDC
创建

display

 设备上下文在 Windows 10 中也被破坏。和你一样,我没有测试过它。
奖励阅读

QC127390:所选打印机不支持操作
  • Win2K8R2 上随机出现“所选打印机无效”错误
  • MSDN 论坛:XPS 和 StartDoc
  • GDI绘图和打印
  • Windows Server 200x 上打印机驱动程序的 CreateDC() 问题
  • 从 Windows 服务打印
  • MSDN:如何:检索打印机设备上下文
  • 1
不是我;内河码头

这个问题你解决了吗?我也有类似的问题。
winapi printing windows-10
1个回答
-1
投票
与您不同,我

可以

成功为打印机

CreateDC - 但仅限本地打印机(不像您质疑无法为any打印机创建DC)。如果打印机是远程的,则 CreateDC 失败。 任何人有任何想法,我们将不胜感激。

谢谢,

—伊恩

© www.soinside.com 2019 - 2024. All rights reserved.