使用ERROR_NOT_SUPPORTED

时间:2015-10-04 03:08:27

标签: winapi printing windows-10

我正在尝试拨打 CreateDC 来创建打印机设备上下文:

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

该代码适用于Windows 7,但在Windows 10中失败 - 返回null

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

enter image description here

传递什么

MSDN documentation表示如果您想获得打印机设备上下文,则必须将 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

    enter image description here

  • Windows 10 enter image description here

1 做错了什么?

CreateDC也失败

CreateIC只是"轻量级" 形式的CreateDC(您可以使用它来获取有关设备的信息,但您可以&#39} ;用它绘制GDI)。这也意味着{10}在Windows 10上也失败了:

CreateDC

Some people设备名称suggested duplicating添加到驱动程序名称中:

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;    

并且我在驱动程序名称中also seen try placing CreateDC('Microsoft XPS Document Writer', 'Microsoft XPS Document Writer', nil, nil);

WINSPOOL

它是所有打印机

我开始提出这个问题,认为它只是 CreateDC('WINSPOOL', 'Microsoft XPS Document Writer', nil, nil);

  • 然后我发现CreateIC也失败了,所以我更新了标题
  • 然后我认为这是因为我碰巧使用 Microsoft XPS Document Writer ,所以我更新了标题
  • 然后我发现它是Windows 10上的所有打印机,所以我再次更新了标题

这是人们提出建议的自然演变,我发现了更多关于问题本质的内容。

CreateDC

据我所知,在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 | 来创建显示设备上下文。就像你一样,我还没有测试过它。

奖金阅读

1 不是我; Embarcadero的

0 个答案:

没有答案