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

如何在Delphi中使用API Winspool.EnumprinterData?,api,delphi,Api,Delphi,有没有人有在Delphi中使用Winspool.EnumprinterDataAPI的经验 我找到了一个C++的演示: 我试图将其隐藏到Delphi,如下所示: procedure TForm1.GetPrinterData; var hPrinter : THandle; pInfo: PPrinterInfo2; bytesNeeded: DWORD; dwRet : DWORD; dwIndex: DWORD; pValueName: PWideChar; pTagNa

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

我找到了一个C++的演示:

我试图将其隐藏到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有很多指针类型的变量,下一步应该为一些变量分配内存,但我不知道如何做thqt。例如
pData:PByte;Pdata=Allocmem(pcbData^)您的代码中有一些错误:

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

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

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

尝试类似以下内容:

程序TForm1.GetPrinterData;
变量
hPrinter:THandle;
德温德克斯,
德布雷特,
dwType,
dwMaxValueNameSize,
dwMaxDataSize,
dwValueNameSize,
dwDataSize:DWORD;
pValueName,
lpData:字节数组;
sValueName:UnicodeString;//或D2007及更早版本中的宽字符串
开始
HPPrinter:=GetCurrentPrinterHandle;
如果hPrinter=0,则
退出;//或者提出一个例外
尝试
dwIndex:=0;
dwRet=EnumPrinterData(hPrinter,dwIndex,nil,0,dwMaxValueNameSize,dwType,nil,0,@dwMaxDataSize);
如果dwRet=错误\u无\u更多\u项,则
出口
否则,如果dwRet错误\u成功,则
RAISELASTERROR(dwRet);
SetLength(pValueName,dwMaxValueNameSize);
SetLength(pData、dwMaxDataSize);
重复
dwValueNameSize:=0;
dwDataSize:=0;
dwRet=EnumPrinterData(hPrinter、dwIndex、PWideChar(pValueName)、dwMaxValueNameSize、dwValueNameSize、dwType、PByte(pData)、dwMaxDataSize、@dwDataSize);
如果dwRet=错误\u无\u更多\u项,则
出口
否则,如果dwRet错误\u成功,则
RaiseLasstOSError(dwRet);
SetLength(sValueName,PWideChar(pValueName),(dwValueNameSize div SizeOf(WideChar))-1);//-1表示空终止符
//根据需要使用dwType、sValueName和pData,最多可使用dwDataSize字节。。。
公司(dwIndex),;
直到错误;
最后
//仅当GetCurrentPrinterHandle返回需要立即关闭的句柄时。。。
闭式打印机(hPrinter);
结束;
结束;

感谢您的大力帮助! 但是有更多的问题,需要你的帮助。(对不起,我英语不好)

问题1。在你的回答中: SetLength(sValueName,PWideChar(pValueName),(dwValueNameSize div SizeOf(WideChar))-1);//-1表示空终止符

I dont understnt this SetLength format.....and complier raise an Error :
[DCC Error] Unit1.pas(111): E2008 Incompatible types
问题2。如何获得价值: sValueName-->ValueName:字节数组,如何从字节数组中获取字符串值


对不起,我的能力很差。我真的没有指针类型的数据,需要更多的研究

嗨,雷米·勒博:我应该在你的答案中添加一条评论。没有添加新答案,我的坏!!!