在线程中操作打印机(200分)

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

shade

Unregistered / Unconfirmed
GUEST, unregistred user!
我想在一个线程中进行打印,但是一但我在线程中利用Openprinter获取了打印机句柄,
在其他线程或主进程中就不能再调用openprinter了,所有的调用都会失败,返回错误
是非法的参数,但如果线程没有启动就不会有问题。
代码如下:
线程:
procedure TJobthread.Execute;
var
hPrinter : THandle;
iError:Dword;
begin
if not WinSpool.OpenPrinter('HP LaserJet 4VC', hPrinter, nil) then
begin
iError:=GetLasterror;
if ERROR_ACCESS_DENIED=iError then
raise exception.Create(' ERROR_ACCESS_DENIED')
else
raise exception.Create(SysErrorMessage(iError));
end;
try
While truedo
begin

//some code use printer such as StartDoc

if Terminated then
Break;
end //while
finally
ClosePrinter(hPrinter);
end;
end;

主进程中:
procedure TfrmMain.Button3Click(Sender: TObject);
var
i:integer;
hPrinter : THandle;
iError:Dword;
b:boolean;
sName:string;
begin
if not WinSpool.OpenPrinter('HP LaserJet 4VC', hPrinter, nil) then
begin
iError:=GetLasterror;
if ERROR_ACCESS_DENIED=iError then
raise exception.Create(' ERROR_ACCESS_DENIED')
else
raise exception.Create(SysErrorMessage(iError));
end;

end;

 
使用同步方法试试.
打印对象好象是非线程安全的.
 
这好象就是所谓的资源互斥的问题吧?
因为打印机是独占设备,不能同时有多个进程使用它,所以你应当建立一个信号量,
当一个进程要使用打印机时,先检测它,如滑设置,就设置该信号量,然后在使用打印机
使用结束后再释放该信号量。设置信号量时还要考虑临界区问题。
 
但是我打开另一台打印机一样会出错;
主进程中该为:
procedure TfrmMain.Button3Click(Sender: TObject);
var
i:integer;
hPrinter : THandle;
iError:Dword;
b:boolean;
sName:string;
begin
if not WinSpool.OpenPrinter('Epson LQ-1600K', hPrinter, nil) then
begin
iError:=GetLasterror;
if ERROR_ACCESS_DENIED=iError then
raise exception.Create(' ERROR_ACCESS_DENIED')
else
raise exception.Create(SysErrorMessage(iError));
end;
end;
这时两个进程访问的并不是同一个资源;
如果在同一进程中同时访问两台打印机并不会有错;
 
你那个winspool是如何声明的?有没有考虑到它在使用中的互斥或同步问题
 
winspool是delphi中用于操作打印机API函数的单元,不是一个类,openprinter是直接调用
WIN32的API函数,我这个程序只是为了后台操作监控打印机,一个线程操作一个打印机,
但一旦在线程中循环调用操作打印机的API如GetPrinter等,在其他线程(包括主线程)调用
Openprinter打开其它打印机就会出错,大家可以写一个简单的程序实验一下。
 
没有人知道吗
 
请发个例子吧.
 
后退
顶部