如何在Delphi中使用API​​ Winspool.EnumprinterData? [英] How to use API Winspool.EnumprinterData in Delphi?

查看:188
本文介绍了如何在Delphi中使用API​​ Winspool.EnumprinterData?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人在Delphi中使用 Winspool.EnumprinterData API有经验吗?

Does anyone have experience with using the Winspool.EnumprinterData API in Delphi?

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

I found a demo for C++: https://s-kita.hatenablog.com/entry/20120227/1330353801

我尝试将其隐藏到Delphi中,如下所示:

I tried to covert it to Delphi as below:

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 结果不是同样,即使我选择了同一台打印机,它也经常会出现访问冲突错误。

Question 1: EnumPrinterDataW result is not the same, even if I chose the same printer, and it often raises an Access Violation error.

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

Question 2: the API has many pointer type variables, the next step should allocate memory to some variable, but I do not know how to do thqt. For example pData: PByte; Pdata = Allocmem(pcbData^); <==== this is difficult to me, Pdata is TByte, how to allocmem(pcbData^) is TPwidechar how to do this?

这花了我2天的时间来处理,而且还是一团糟!

This has taken me 2 days to deal with, and it is still a mess !!!!

推荐答案

您的代码中存在一些错误:

There are some mistakes in your code:


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

  • you are not checking if GetCurrentPrinterHandle() returns a valid printer handle.

您没有初始化 i 变量。您需要将基于0的索引传递给 EnumPrinterData(),但是 i 的值是不确定的

you are not initializing your i variable. You need to pass a 0-based index to EnumPrinterData(), but the value of i is indeterminate.

您没有初始化 pcbData 变量。 EnumPrinterData()需要一个指向 DWORD 变量的指针,该变量将接收写入<$ c的数据的大小。 $ c> pData 缓冲区(或 pData 缓冲区的所需大小,如果 pData 是零)。但是您的 pcbData 没有指向有效的 DWORD

you are not initializing your pcbData variable. EnumPrinterData() expects a pointer to a DWORD variable that will receive the size of the data written to the pData buffer (or the needed size of the pData buffer if pData is nil). But your pcbData is not pointing to a valid 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;

这篇关于如何在Delphi中使用API​​ Winspool.EnumprinterData?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆