高手求救 请问在delphi中如何获取 打印机打印任务完成的标志 急 急 急(100分)

  • 主题发起人 主题发起人 zm790607
  • 开始时间 开始时间
Z

zm790607

Unregistered / Unconfirmed
GUEST, unregistred user!
高手求救 请问在delphi中如何获取 打印机打印任务完成的标志 急 急 急
现在遇到了一个问题,我想通过虚拟打印机转换 文件格式,就是把doc文档打印出来,然后
转换成传真能够识别的格式., 这是两个过程, 目前我已经完成 过程实现的步骤,
这其中存在一个问题 如何获取 打印机 打印任务完成的信号 , 因为有时打印任务比较大
需要等待 虚拟打印完成,才能够进行下一个过程
请高手帮忙啊 如何获取 虚拟打印机 打印任务 完成的信号 谢谢 分数不够可以在加
 
高手进来,帮忙啊 ,这个问题 我考虑需要调用 win32 的函数吧, 希望高手们进来帮忙啊,
我一直在线等待 谢谢!
 
怎么没有人回答呢,那就自己顶, 在线等待啊, 高手帮助啊
 
高手请进啊 ,怎么没有人回答啊 , 难道 搞DELPHI 的高手都转行了啊?
 
怎么会没有人回复呢? 是不是我表述的不明白呢? 还是有其他的方法呢?
 
为什么没有回答呢? 高手在哪里?
 
没做过,帮你顶帖
 
没有人帮忙 ,继续顶啊
 
还是要顶 ,怎么没有人帮忙呢?
 
获取打印机状态
var
pinfo: pPRINTERINFO2;

pprt,a: Cardinal;

b:PDWORD;

begin

b:=allocmem(256);

pinfo:=AllocMem(1000);

if OpenPrinter('HP DJ 200',pprt,nil) then

begin

a:=1000;

if getprinter(pprt,2,pinfo,a,b) then

showmessage(pinfo.pPrinterName+' ststus:'+inttostr(pinfo.Status));

ClosePrinter(pprt);

end;

freemem(b);

freemem(pinfo);

end;

PRINTER_INFO_2.Status :
Windows NT:
PRINTER_STATUS_PAUSED
PRINTER_STATUS_PENDING_DELETION
Windows 95:
PRINTER_STATUS_BUSY
PRINTER_STATUS_DOOR_OPEN
PRINTER_STATUS_ERROR
PRINTER_STATUS_INITIALIZING
PRINTER_STATUS_IO_ACTIVE
PRINTER_STATUS_MANUAL_FEED
PRINTER_STATUS_NO_TONER
PRINTER_STATUS_NOT_AVAILABLE
PRINTER_STATUS_OFFLINE
PRINTER_STATUS_OUT_OF_MEMORY
PRINTER_STATUS_OUTPUT_BIN_FULL
PRINTER_STATUS_PAGE_PUNT
PRINTER_STATUS_PAPER_JAM
PRINTER_STATUS_PAPER_OUT
PRINTER_STATUS_PAPER_PROBLEM
PRINTER_STATUS_PAUSED
PRINTER_STATUS_PENDING_DELETION
PRINTER_STATUS_PRINTING
PRINTER_STATUS_PROCESSING
PRINTER_STATUS_TONER_LOW
PRINTER_STATUS_UNAVAILABLE
PRINTER_STATUS_USER_INTERVENTION
PRINTER_STATUS_WAITING
PRINTER_STATUS_WARMING_UP
 
初次使用 API 函数,是两个获取与指定作业有关的信息的 API 函数,
有很多很多不明白的地方,请指教:
第一个:OpenPrinter //说明:打开指定的打印机,并获取打印机的句柄
LPTSTR pPrinterName, // 要打开的打印机的名字,但名字从哪能获得呢?
LPHANDLE phPrinter, // 用于装载打印机的句柄,我想这要用一个变量装
// 这个句柄吧,回来好用,但这个变量申请什么类型的?
LPPRINTER_DEFAULTS pDefault // 这个结构保存要载入的打印机信息,这个信息用
//什么保存?要申请一个和它一样的结构吗?
取的打印机的句柄后,发现用 GetJob 函数能取得打印任务的信息,我就想取里面的打印
任务是否完成的信息。
GetJob
HANDLE hPrinter, // 打印机句柄,已经获得
DWORD JobId, // 作业编号,这有个问题,这个作业编号的变量是 DWORD类型的,
//但帮助里没找到这个类型,但申请时可以,这是 WORD 类型吗?为
//什么前面要加 D ?
DWORD Level, // 数据类型级别,也是 DWORD
LPBYTE pJob, // 包含JOB_INFO_1 或 JOB_INFO_2结构的缓冲区,结构中包含
//了与打印作业有关的信息,这是关键,但我不知道该怎么做下去,
//我觉得是不是申请个和这个结构相同的结构,然后取的信息
DWORD cbBuf, // pJob缓冲区中的字符数量 这是什么意思?
LPDWORD pcbNeeded // 指向一个Long型变量的指针,该变量用于保存请求的缓冲区长度,或者
//实际读入的字节数量,这个 LPDWORD 又是什么类型的?帮助里面也没有啊
//还有它说“该变量用于保存请求的缓冲区长度”好象是说上面的那个 cbBuf 那个
//参数的,但那个参数不有字符数量了吗?这到底是什么意思?
//那个 pJob 的结构如下:
typedef struct _JOB_INFO_1 { // ji1
DWORD JobId;

LPTSTR pPrinterName;
LPTSTR pMachineName;
LPTSTR pUserName;
LPTSTR pDocument;
LPTSTR pDatatype;
LPTSTR pStatus;
DWORD Status;
//这个里面就装着我要的,在下面
DWORD Priority;
DWORD Position;
DWORD TotalPages;
DWORD PagesPrinted;
SYSTEMTIME Submitted;
} JOB_INFO_1;

//上面的结构的内容怎样才能取出来呢?我老是弄不明白,还有它这个 LPBYTE 类型,是
//什么类型?
这是其中的 status 里面的值
Status
JOB_STATUS_DELETING
JOB_STATUS_ERROR
JOB_STATUS_OFFLINE
JOB_STATUS_PAPEROUT
JOB_STATUS_PAUSED
JOB_STATUS_PRINTED //应该是这个吧,作业状态是:已经打印了
JOB_STATUS_PRINTING
JOB_STATUS_SPOOLING
//这个又怎么才能得到呢?
对这些我简直是一点都不明白,谁好心给我详细说说,我把所有分,都给你,就只有226分了。
这个 API 函数为什么这么复杂? DELPHI 里面有没有包装这两个函数的函数?

chshanghai (2001-10-19 11:30:00)
你不要用api 在delphi 中已封装了一个tprinter类
例:
print:tprinter;
print:=tprinter.create;
print.begin
doc //
print.canvas.textout('123242');
print.enddoc;

xianjun (2001-10-19 11:32:00)
其实这个函数在Delphi中已经封装了,
声明在winspool.pas(D:/Program Files/Borland/Delphi5/Source/Vcl)里面,
Delphi把打印相关的东西封装成TPrinter对象,这个对象在printers.pas
(D:/Program Files/Borland/Delphi5/Source/Vcl)单元里面。
Printers这个单元有很详细的说明,你先看看吧,有什么问题再在这提出来好了。
至于说耐心,我想在这的每一个人都不会缺这个,唯一缺的可能是时间吧,只要有
时间,应该来说都不会有问题的。[:D]

cypl (2001-10-19 11:39:00)
chshanghai:
print:tprinter;
print:=tprinter.create;
print.begin
doc //
print.canvas.textout('123242');
print.enddoc;
你说的这个不好使啊,print.enddoc 后,那个左下脚就出了打印机的小图标,里面有打印
任务,我就想知道那个打印任务打印完成后如何判断啊! enddoc 好象是把打印数据发出后
就结束了,不是有没有打印!
不过也多谢你!
xianjun:
我找找看看,多谢你,但最好有时间帮忙给我解释一下那个 api 函数,我是第一次用,
更想知道怎么用那些奇怪的函数!


卷起千堆雪tyn (2001-10-19 11:42:00)
OpenPrinter
获取指定打印机的句柄
var
hPrinter: THandle;
//获得的打印机句柄
PrtName: String;
//打印机名字
OpenPrinter( PChar( PrtName ) , hPrinter , nil );
GetJob
获取打印作业信息
其实Delphi里已经封装了TPrinter类,你直接uses Printers,就可以调用打印任务了。
begin
Doc;
.....
.....
.....
EndDoc;
给你举一个图象打印的例子:
procedure TForm1.Button1Click(Sender: TObject);
var
ScaleX, ScaleY: Integer;
R: TRect;
begin
Printer.begin
Doc;
// **
with Printerdo
try
ScaleX := GetDeviceCaps(Handle, logPixelsX) div PixelsPerInch;
ScaleY := GetDeviceCaps(Handle, logPixelsY) div PixelsPerInch;
R := Rect(0, 0, Image1.Picture.Width * ScaleX,
Image1.Picture.Height * ScaleY);
Canvas.StretchDraw(R, Image1.Picture.Graphic);
// **
finally
EndDoc;
// **
end;
end;



cypl (2001-10-19 11:45:00)
还是不明白

j_shen2000 (2001-10-19 11:52:00)
winspool里已经封装了这两个函数,我先按你的要求试写一个例子,晚点给你。

xianjun (2001-10-19 12:03:00)
你看看那个单元的SetToDefaultPrinter过程就知道了,
LPTSTR pPrinterName, 是从系统的打印机列表中用API:EnumPrinters取得的
phPrinter就是打印机的Handle, 是OpenPrinter根据你传入的名称返回的
LPPRINTER_DEFAULTS pDefault保存了打印机的一些默认设置,你传入nil就行了。
DWORD JobId: DWORD是WINDOWS的一个数据类型,相当于DELPHI的LongWord,当然
DELPHI中也声明了DWORD这个类型,不过是DWORD = LongWord;
...
其实这个真的挺复杂,如果你是用来作打印任务的话,最好别直接用API,用TPrinter
对象就可以了,一切都已经为你做好。而且TPrinter还带有详细的帮助。

huntaway (2001-10-19 12:12:00)
所谓的DWORD就是Double Word的意思,Word你应该知道吧,16位的无符号整数,因此
DWORD就是32位的无符号整数了,跟UINT是一样的。对于以LP开头的所有类型,都是指针。
Delphi对这些指针一般有如下规定,在作为参数的时候,LPTSTR就是PChar,其余的都是
以var的形式传递。对于放在某些结构里(例如你的JOB_INFO_1)的指针,就是用指针。至
于是什么类型的指针,看具体类型而言,也可以一律用PChar。
其实,在使用WinAPI的时候,有一个适用于大多数函数的规律,如果MSDN中说某个函数
在xxxx.lib中,那么Delphi中如果不在Windows.dcu中声明,就会在xxxx.dcu中声明。
会有对应的xxxx.dcu,在uses中添加xxxx即可。函数名是相同的,然后你可以利用Delphi的
自动完成提示功能,让它显示所有参数的类型。那个已经翻译成Delphi的类型了。
另外说一些WinAPI的普遍调用规律吧,WinAPI总是将某些返回值放在缓冲区中。正如
Delphi中使用了var的参数一样。不过WinAPI需要你自己分配内存,因此你需要告诉它你分
配了多少内存。但是某些时候你不知道WinAPI究竟需要多少内存,这时它通常会提供一个指
针类型的参数,当你分配的内存不够的时候,它会在这个参数里返回所需要的内存。
你所需要的函数在WinSpool.dcu中有声明,所有要用到的结构也都定义了,不过那些结构
的名字和MSDN中不一样。多利用一下Delphi的提示功能,可以免去你很多麻烦。

j_shen2000 (2001-10-19 13:23:00)
OK,花了俺午休的时间,给你作了一个简单的例子,留下MAIL给你发过去。

cypl (2001-10-19 15:04:00)
都是好人啊,多谢多谢,
j_shen2000:真是好人中的好人啊,不过信箱坏了,你就贴出来吧!

j_shen2000 (2001-10-19 15:43:00)
首先,我没有用GETJOB,而是用了ENUMJOBS,不是因为GETJOB不能用而是因为,GETJOB
中的JOBID必须是ADDJOB生成的作业句柄,而ENUMJOBS中的JOBID是作业的INDEX,不过功能
差不多,后者可能更完善,因为它能捕作所有在打印机管理中的作业目前的运行情况。
函数说明你可以看MSDN,测试时,找一个大文件,要不停的按按钮,或者你放到线程或者
放个TIMER来扫描,呵,偷了一个懒:)。
USE winspool,printers;
procedure TForm1.Button2Click(Sender: TObject);
var
MyPrinter,MyHandle : THandle;
MyDevModeOut,MyDevModeIn : pDevmode;
MyDevice,MyDriver,MyPort: array [0..255] of Char;
jb:job_info_1A;
pn,pr:dword;
s:string;
begin
{ set Printer index to the default printer }
Printer().PrinterIndex := -1;
{ get our printer properties }
Printer().GetPrinter(MyDevice,MyDriver,MyPort,MyHandle);
{ OpenPrinter WIN32 API call returns hPrinter to us }
if OpenPrinter(@MyDevice, MyPrinter, nil) then
begin
If EnumJobs(myprinter,0,1,1,@Jb,SizeOf(job_info_1A)+128,pn,pr) then
//0代表第一个作业(GETJOB中必须是作业句柄),
//1代表所要列举的作业总数为1,即只找第一个。
//1代表LEVEL为1,对应job_info_1结构。
begin
If jb.JobId>0 then
begin
case jb.Status of
JOB_STATUS_DELETING:showmessage('JOB_STATUS_DELETING');
JOB_STATUS_ERROR:showmessage('JOB_STATUS_ERROR');
JOB_STATUS_OFFLINE:showmessage('JOB_STATUS_OFFLINE');
JOB_STATUS_PAPEROUT:showmessage('JOB_STATUS_PAPEROUT');
JOB_STATUS_PAUSED:showmessage('JOB_STATUS_PAUSED');
JOB_STATUS_PRINTED:showmessage('JOB_STATUS_PRINTED');
JOB_STATUS_PRINTING:showmessage('JOB_STATUS_PRINTING');
JOB_STATUS_SPOOLING:showmessage('JOB_STATUS_SPOOLING');
else
showmessage('print end or no print');
end;
end;
End
else
ShowMessage(SysErrorMessage(GetLastError));
end;
end;
 
to dey-999, aizhuzhu
先谢谢楼上的二位老兄啊, 我由于在赶项目,今天才看到这个留言,不过还是有很多不明白的地方 ,请二位 帮我解释一下 , 我现在的任务就是当打印机 打印作业时 获取 右下角出现的打印 图标 消失的时间 ,即 打印完成时间
希望没有看到此帖的各位朋友也能够帮忙,谢谢啊
 
寻求帮助啊,希望各位高手们能够进来帮忙啊
 
真对不起各位,没有分数了,只能在这里提问了,我现在想通过点击按钮启动一个tif文件,我该怎么做呢? 希望各位高手帮助啊
 
在delphi 中通过点击按钮 启动 tif文件的方法,希望大家帮忙啊
 
看来只有 有分才能够得到 答案了, /可是我确实没有了
大家能不能帮我想想办法啊?
 
这个问题怎么没有朋友理呢? 我想尽了办法,还是没有解决啊
请朋友们帮忙啊
 
自己继续顶啊, 高手帮忙啊
 
ShellExecute
 
查看打印机任务数,函数返回0就应该是打印完毕
uses Printers, WinSpool;
.......................
function TForm1.getjob(): integer;
var
Needed, Returned: DWORD;
i, Count: integer;
tbt: byte;
pNeeded: PDword;
P2: PJobInfo1;
PPI: pPRINTERINFO2;
Printer: TPrinter;
Device, Driver, Port: array[0..255] of Char;
PPr, DevMode: Cardinal;
hPrinter: THandle;
begin
result := 0;
Printer := TPrinter.Create;
//创建Printer对象
try
Printer.GetPrinter(Device, Driver, Port, DevMode);
//取得打印机的名称,驱动程序,端口号
if not OpenPrinter(@device, hPrinter, nil) then
//取得打印机的句柄
begin
ShowMessage('OpenPrinter' + SysErrorMessage(GetLastError));
//Exit;
end;
PNeeded := AllocMem(8024);
//分配内存空间
P2 := AllocMem(8048);
PPI := AllocMem(8048);
//接受打印机信息结构
if not GetPrinter(hPrinter, 2, PPI, 8048, PNeeded) then
//取得打印机队列中的任务数
begin
ShowMessage('GetPrinter' + SysErrorMessage(GetLastError));
end;
//取得打印机状态
if Enumjobs(hPrinter, 0, 1, 2, p2, 8048, Needed, Returned) then
begin
if P2.JobId = 0 then
result := 0;
if P2.JobId > 0 then
begin
result := PPI.cJobs;
end
end
else
ShowMessage('Enumjobs' + SysErrorMessage(GetLastError));
//关闭打印机,释放内存空间
finally
FreeMem(PNeeded);
FreeMem(p2);
FreeMem(PPI);
Printer.Free;
ClosePrinter(hPrinter);
end;
end;
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部