如何在Delphi中使用API Winspool.EnumprinterData?

胡itch

有没有人有Winspool.EnumprinterData在Delphi中使用API的经验

我找到了一个C ++演示:https : //s-kita.hatenablog.com/entry/20120227/1330353801

我试图将其隐瞒给Delphi,如下所示:

procedure TForm1.GetPrinterData;
var
 hPrinter  : THandle;
 pInfo:  PPrinterInfo2;
 bytesNeeded: DWORD;
 dwRet : DWORD;
 dwIndex: DWORD;
 pValueName: PWideChar;
 pTagName: PWideChar;
 cbValueName: DWORD;
 pcbValueName : DWORD;
 pType: DWORD;
 pData: PByte;
 cbData: DWORD;
 pcbData: PDWORD;
 i : Integer;
 printername : String;
 dwValueNameSize : DWORD;
 dwDataSize : DWORD;
 begin
   hprinter := GetCurrentPrinterHandle;
   dwRet := EnumPrinterDataw(hprinter,i,nil,0, pcbValueName,pType,nil,0,pcbData);
 end;

问题1:EnumPrinterDataW即使我选择了同一台打印机,结果也不一样,并且经常会出现访问冲突错误。

问题2:API有很多指针类型的变量,下一步应该为一些变量分配内存,但是我不知道该怎么做。例如pData: PByte; Pdata = Allocmem(pcbData^);<====这是很难对我来说,Pdata就是TByte,如何allocmem(pcbData^)TPwidechar如何做到这一点?

这花了我2天的时间来解决,仍然很烂!

雷米·勒博

您的代码中有一些错误:

  • 您不检查是否GetCurrentPrinterHandle()返回有效的打印机句柄。

  • 您没有初始化i变量。你需要通过一个基于0指数EnumPrinterData(),但价值i不确定的

  • 您没有初始化pcbData变量。EnumPrinterData()需要一个指向DWORD变量的指针,该变量将接收写入pData缓冲区的数据大小(pData如果pData为nil,则为所需的缓冲区大小)。但是您pcbData的意思不是有效的DWORD

尝试更多类似这样的方法:

procedure TForm1.GetPrinterData;
var
  hPrinter: THandle;
  dwIndex,
  dwRet,
  dwType,
  dwMaxValueNameSize,
  dwMaxDataSize,
  dwValueNameSize,
  dwDataSize: DWORD;
  pValueName,
  lpData: array of Byte;
  sValueName: UnicodeString; // or WideString in D2007 and earlier
begin
  hPrinter := GetCurrentPrinterHandle;
  if hPrinter = 0 then
    Exit; // or raise an exception

  try
    dwIndex := 0;

    dwRet = EnumPrinterData(hPrinter, dwIndex, nil, 0, dwMaxValueNameSize, dwType, nil, 0, @dwMaxDataSize);
    if dwRet = ERROR_NO_MORE_ITEMS then
      Exit
    else if dwRet <> ERROR_SUCCESS then
      RaiseLastOSError(dwRet);

    SetLength(pValueName, dwMaxValueNameSize);
    SetLength(pData, dwMaxDataSize);

    repeat
      dwValueNameSize := 0;
      dwDataSize := 0;

      dwRet = EnumPrinterData(hPrinter, dwIndex, PWideChar(pValueName), dwMaxValueNameSize, dwValueNameSize, dwType, PByte(pData), dwMaxDataSize, @dwDataSize);
      if dwRet = ERROR_NO_MORE_ITEMS then
        Exit
      else if dwRet <> ERROR_SUCCESS then
        RaiseLasstOSError(dwRet);

      SetLength(sValueName, PWideChar(pValueName), (dwValueNameSize div SizeOf(WideChar)) - 1); // -1 for null terminator

      // use dwType, sValueName, and pData up to dwDataSize bytes, as needed...

      Inc(dwIndex);
    until False;
  finally
    // only if GetCurrentPrinterHandle returns a handle that needs to be closed now...
    ClosePrinter(hPrinter);
  end;
end;

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章