关于的FindNextPrinterChangeNotification使用 ( 积分: 200 )

  • 主题发起人 主题发起人 Supermay
  • 开始时间 开始时间
S

Supermay

Unregistered / Unconfirmed
GUEST, unregistred user!
我想监视打印机的事件
procedure TForm1.Button3Click(Sender: TObject);
Const
TimeOut=1000;
Var
PrinterName:Pchar;
PrinterHandle : THandle;
chgObject:THandle;
pdwChange:DWORD;
LCardinal:Cardinal;
pPrnNotify:PPrinterNotifyOptions;
pPrnNotifyInfo:PPrinterNotifyInfo;
fcnReturn:LongBool;
begin
pdwChange:=PRINTER_CHANGE_ALL;
GetMem(pPrnNotify,SizeOf(TPrinterNotifyOptions));
GetMem(pPrnNotifyInfo,SizeOf(TPrinterNotifyInfo));
PrinterName:=Pchar(Printers.Printer.Printers.Strings[0]);
if OpenPrinter(PrinterName,PrinterHandle,nil) then
begin
chgObject:=FindFirstPrinterChangeNotification(PrinterHandle,pdwChange, 0,pPrnNotify);
if chgObject>0 then
begin
//WaitForSingleObject(chgObject,TimeOut);//这里总是会超时,会释放ChgObject
with pPrnNotify^do
begin
Version := 1;
Flags := PRINTER_NOTIFY_OPTIONS_REFRESH;
Count := 1;
pTypes := nil;
end;
fcnReturn :=FindNextPrinterChangeNotification(chgObject,pdwChange,pPrnNotify,Pointer(pPrnNotifyInfo));
if fcnReturn then
begin
///////////////////////////////////////////////////////////////////////
Case pPrnNotifyInfo^.aData[0].wType of//得不到正确的值, JOB_NOTIFY_TYPE://这里只有这两个值
begin
Self.Memo1.Lines.Add('JOB_NOTIFY_TYPE');
end;
PRINTER_NOTIFY_TYPE:
begin
Self.Memo1.Lines.Add('PRINTER_NOTIFY_TYPE');
end;
end;
//pdwChange总是为0,
//Check pdwChange,PrnNotify,pPrnNotifyInfo
///////////////////////////////////////////////////////////////////
end;
end;
FreePrinterNotifyInfo(pPrnNotifyInfo);
ClosePrinter(PrinterHandle);
end;
end;

如何处理?
 
我想监视打印机的事件
procedure TForm1.Button3Click(Sender: TObject);
Const
TimeOut=1000;
Var
PrinterName:Pchar;
PrinterHandle : THandle;
chgObject:THandle;
pdwChange:DWORD;
LCardinal:Cardinal;
pPrnNotify:PPrinterNotifyOptions;
pPrnNotifyInfo:PPrinterNotifyInfo;
fcnReturn:LongBool;
begin
pdwChange:=PRINTER_CHANGE_ALL;
GetMem(pPrnNotify,SizeOf(TPrinterNotifyOptions));
GetMem(pPrnNotifyInfo,SizeOf(TPrinterNotifyInfo));
PrinterName:=Pchar(Printers.Printer.Printers.Strings[0]);
if OpenPrinter(PrinterName,PrinterHandle,nil) then
begin
chgObject:=FindFirstPrinterChangeNotification(PrinterHandle,pdwChange, 0,pPrnNotify);
if chgObject>0 then
begin
//WaitForSingleObject(chgObject,TimeOut);//这里总是会超时,会释放ChgObject
with pPrnNotify^do
begin
Version := 1;
Flags := PRINTER_NOTIFY_OPTIONS_REFRESH;
Count := 1;
pTypes := nil;
end;
fcnReturn :=FindNextPrinterChangeNotification(chgObject,pdwChange,pPrnNotify,Pointer(pPrnNotifyInfo));
if fcnReturn then
begin
///////////////////////////////////////////////////////////////////////
Case pPrnNotifyInfo^.aData[0].wType of//得不到正确的值, JOB_NOTIFY_TYPE://这里只有这两个值
begin
Self.Memo1.Lines.Add('JOB_NOTIFY_TYPE');
end;
PRINTER_NOTIFY_TYPE:
begin
Self.Memo1.Lines.Add('PRINTER_NOTIFY_TYPE');
end;
end;
//pdwChange总是为0,
//Check pdwChange,PrnNotify,pPrnNotifyInfo
///////////////////////////////////////////////////////////////////
end;
end;
FreePrinterNotifyInfo(pPrnNotifyInfo);
ClosePrinter(PrinterHandle);
end;
end;

如何处理?
 
向前进向前进……
 
我用的是D5,不知道D6中WinSpool文件是否有什么改变,
可以看一下WinSpool文件中对此函数的声明
这个函数的声明看上去和APIHelp中的声明有些差异
function FindNextPrinterChangeNotification(hChange: THandle;
var pdwChange: DWORD;
pvReserved: Pointer;
var ppPrinterNotifyInfo: Pointer): BOOL;
stdcall;
pdwChange 是DWORD 不是PDWORD这是第一个,最后一个参数 ppPrinterNotifyInfo
得搞个Pointer类型的变量
 
对不起,搞错了pdwChange
其实每一个参数我都知类型,但还是不行
 
最后一个参数得传个地址,不能用Nil这个改了么?
 
procedure TForm1.Button1Click(Sender: TObject);
Const
TimeOut=100;
Var
PrinterName:Pchar;
PrinterHandle : THandle;
chgObject:THandle;
pdwChange:DWORD;
//pPrnNotify:Phandle;
//pPrnNotifyInfo:Pointer;
pPrnNotify:PPrinterNotifyOptions;
pPrnNotifyInfo:PPrinterNotifyInfo;
fcnReturn:LongBool;
begin
pdwChange:=0;
//改成下面 ××××××××××××××××
//pPrnNotifyInfo:=nil ;
//pPrnNotify:=nil;
FillChar(pPrnNotify, SizeOf(pPrnNotify), 0);
FillChar(pPrnNotifyInfo, SizeOf(pPrnNotifyInfo), 0);
with pPrnNotifydo
begin
Version := 2;
Flags := PRINTER_NOTIFY_OPTIONS_REFRESH;
Count := 1;
pTypes := nil;
end;
//××××××××××××××××
PrinterName:=Pchar(Printers.Printer.Printers.Strings[0]);
if OpenPrinter(PrinterName,PrinterHandle,nil) then
begin
chgObject:=FindFirstPrinterChangeNotification(PrinterHandle,PRINTER_CHANGE_ALL, 0,Pointer(pPrnNotifyInfo));
WaitForSingleObject(chgObject,TimeOut);
//FreePrinterNotifyInfo(pPrnNotifyInfo);
pPrnNotify
fcnReturn :=FindNextPrinterChangeNotification(chgObject,pdwChange,@pPrnNotify,Pointer(pPrnNotifyInfo));
if Not fcnReturn then
begin

end;
end;

end;
 
procedure TForm1.Button1Click(Sender: TObject);
Const
TimeOut=100;
Var
PrinterName:Pchar;
PrinterHandle : THandle;
chgObject:THandle;
pdwChange:DWORD;
//pPrnNotify:Phandle;
//pPrnNotifyInfo:Pointer;
pPrnNotify:TPrinterNotifyOptions;
//PPrinterNotifyOptions改成TPrinterNotifyOptions
pPrnNotifyInfo:PPrinterNotifyInfo;
fcnReturn:LongBool;
begin
pdwChange:=0;
//改成下面 ××××××××××××××××
//pPrnNotifyInfo:=nil ;
//pPrnNotify:=nil;
FillChar(pPrnNotify, SizeOf(pPrnNotify), 0);
GetMem(pPrnNotifyInfo,SizeOf(TPrinterNotifyInfo));
with pPrnNotifydo
begin
Version := 2;
Flags := PRINTER_NOTIFY_OPTIONS_REFRESH;
Count := 1;
pTypes := nil;
end;
//××××××××××××××××
PrinterName:=Pchar(Printers.Printer.Printers.Strings[0]);
if OpenPrinter(PrinterName,PrinterHandle,nil) then
begin
chgObject:=FindFirstPrinterChangeNotification(PrinterHandle,PRINTER_CHANGE_ALL, 0,@pPrnNotify);
//改成pPrnNotify
WaitForSingleObject(chgObject,TimeOut);
//FreePrinterNotifyInfo(pPrnNotifyInfo);
fcnReturn :=FindNextPrinterChangeNotification(chgObject,pdwChange,@pPrnNotify,Pointer(pPrnNotifyInfo));
if Not fcnReturn then
begin

end;
end;

end;
 
FindNextPrinterChangeNotification总是不能用
改用WaitForPrinterChange就OK
OpenPrinter
WaitForPrinterChange
EnumJobs
ClosePrinter
不过我是用多线程,甚至写LOG文件也是用线程,
为每一台打印机生成一个独立线程
 
OK了
写成类Socket Server的形式
 
后退
顶部