有没有人有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] 删除。
我来说两句