怎样获得打印机当前状态?

foilsman 2004-06-30 10:45:02
比如什么时候得知打印机服务器的缓冲池已满?
...全文
367 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
programingfans 2004-07-28
  • 打赏
  • 举报
回复
mark
foilsman 2004-07-21
  • 打赏
  • 举报
回复
非常感谢上面各位的热心帮助!
duronshi 2004-07-14
  • 打赏
  • 举报
回复
我想知道暂停打印/恢复打印的指令是什么?想在暂停后显示相应信息后再接着打印
可以吗?小弟先谢了
fenglaile 2004-07-14
  • 打赏
  • 举报
回复
C++代码

BOOL GetJobs(HANDLE hPrinter, /* Handle to the printer. */

JOB_INFO_2 **ppJobInfo, /* Pointer to be filled. */
int *pcJobs, /* Count of jobs filled. */
DWORD *pStatus) /* Print Queue status. */

{

DWORD cByteNeeded,
nReturned,
cByteUsed;
PRINTER_INFO_2 *pPrinterInfo = NULL;
JOB_INFO_2 *pJobStorage=NULL;

/* Get the buffer size needed. */
if (!GetPrinter(hPrinter, 2, NULL, 0, &cByteNeeded))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return FALSE;
}

pPrinterInfo = (PRINTER_INFO_2 *)malloc(cByteNeeded);
if (!(pPrinterInfo))
/* Failure to allocate memory. */
return FALSE;

/* Get the printer information. */
if (!GetPrinter(hPrinter,
2,
(LPSTR)pPrinterInfo,
cByteNeeded,
&cByteUsed))
{
/* Failure to access the printer. */
free(pPrinterInfo);
pPrinterInfo = NULL;
return FALSE;
}

/* Get job storage space. */
if (!EnumJobs(hPrinter,
0,
pPrinterInfo->cJobs,
2,
NULL,
0,
(LPDWORD)&cByteNeeded,
(LPDWORD)&nReturned))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
free(pPrinterInfo);
pPrinterInfo = NULL;
return FALSE;
}
}

pJobStorage = (JOB_INFO_2 *)malloc(cByteNeeded);
if (!pJobStorage)
{
/* Failure to allocate Job storage space. */
free(pPrinterInfo);
pPrinterInfo = NULL;
return FALSE;
}

ZeroMemory(pJobStorage, cByteNeeded);

/* Get the list of jobs. */
if (!EnumJobs(hPrinter,
0,
pPrinterInfo->cJobs,
2,
(LPBYTE)pJobStorage,
cByteNeeded,
(LPDWORD)&cByteUsed,
(LPDWORD)&nReturned))
{
free(pPrinterInfo);
free(pJobStorage);
pJobStorage = NULL;
pPrinterInfo = NULL;
return FALSE;
}

/*
* Return the information.
*/
*pcJobs = nReturned;
*pStatus = pPrinterInfo->Status;
*ppJobInfo = pJobStorage;
free(pPrinterInfo);

return TRUE;

}

BOOL IsPrinterError(HANDLE hPrinter)
{

JOB_INFO_2 *pJobs;
int cJobs,
i;
DWORD dwPrinterStatus;

/*
* Get the state information for the Printer Queue and
* the jobs in the Printer Queue.
*/
if (!GetJobs(hPrinter, &pJobs, &cJobs, &dwPrinterStatus))
return FALSE;

/*
* If the Printer reports an error, believe it.
*/
if (dwPrinterStatus &
(PRINTER_STATUS_ERROR |
PRINTER_STATUS_PAPER_JAM |
PRINTER_STATUS_PAPER_OUT |
PRINTER_STATUS_PAPER_PROBLEM |
PRINTER_STATUS_OUTPUT_BIN_FULL |
PRINTER_STATUS_NOT_AVAILABLE |
PRINTER_STATUS_NO_TONER |
PRINTER_STATUS_OUT_OF_MEMORY |
PRINTER_STATUS_OFFLINE |
PRINTER_STATUS_DOOR_OPEN))
{
free( pJobs );

return TRUE;
}

/*
* Find the Job in the Queue that is printing.
*/
for (i=0; i < cJobs; i++)
{
if (pJobs[i].Status & JOB_STATUS_PRINTING)
{
/*
* If the job is in an error state,
* report an error for the printer.
* Code could be inserted here to
* attempt an interpretation of the
* pStatus member as well.
*/
if (pJobs[i].Status &
(JOB_STATUS_ERROR |
JOB_STATUS_OFFLINE |
JOB_STATUS_PAPEROUT |
JOB_STATUS_BLOCKED_DEVQ))
{
free( pJobs );
return TRUE;
}
}
}

/*
* No error condition.
*/
free( pJobs );
return FALSE;

}
jacket008 2004-07-03
  • 打赏
  • 举报
回复
写汇编的方法在2000应该可以的吧!回去调试一下再回来
jacket008 2004-07-03
  • 打赏
  • 举报
回复
我知道了,一定要用汇编才可以,读取打印口的第11根脚是否处于高电平(读取数据状态)就可以了。


zjcsut 2004-07-03
  • 打赏
  • 举报
回复
可以用spcomm控件,直接侦察
dreamertang 2004-07-02
  • 打赏
  • 举报
回复
>>写汇编的方法在2000以上版本好像不幸吧?!

在NT系统下是不行,我试过!

关注,UP!
jacket008 2004-07-02
  • 打赏
  • 举报
回复
>>我也想知道如何实现打印机在不装驱动的程况下,如何检测打印机电源是否打开及是否联机?

继续UP


做过POS系统的,应该有关注过这方面的问题
aiirii 2004-07-02
  • 打赏
  • 举报
回复
>>我也想知道如何实现打印机在不装驱动的程况下,如果检测打印机电源是否打开及是否联机?
沒驅動, 比較麻煩, 我還不知道如何做!
yang_jl 2004-07-01
  • 打赏
  • 举报
回复
写汇编的方法在2000以上版本好像不幸吧?!
我也想知道如何实现打印机在不装驱动的程况下,如果检测打印机电源是否打开及是否联机?
jacket008 2004-07-01
  • 打赏
  • 举报
回复
aiirii(ari-爱的眼睛)

上面方法不知能不能适用pos58
aiirii 2004-06-30
  • 打赏
  • 举报
回复
MPrtInfo. This component let you access to Windows95/98 and NT structures containing virtually any information provided by the system about installed printers and their pending jobs. Structures available are: PRINTER_INFO_1, 2, 3, 4 and 5, DEVMODE, JOB_INFO_1 and 2 (see Win32 online help for details), plus some obvious properties (installed printer names list, selected printer name and index in the list and so on). Methods to pause, resume and clear printers and jobs, some printer configuration dialogs. Events to monitor printer and printer jobs status changes.

http://delphi.icm.edu.pl/ftp/d30free/mprtinfo.zip
aiirii 2004-06-30
  • 打赏
  • 举报
回复
unit PrintStatus;

interface
function PrinterStatus(var aStatus: LongWord; var aNrJobs: Integer): string;

implementation
uses Windows, SysUtils, Printers, WinSpool;

resourcestring
rsNrJobsWaiting = '%0:u document(s) waiting';
rsStatusSep = '; ';

rsStatusIdle = 'Idle';
rsStatusUnknown = 'Unknown';
rsStatusBusy = 'Busy';
rsStatusDoorOpen = 'Door open';
rsStatusError = 'Error';
rsStatusInitializing = 'Initialising';
rsStatusIOActive = 'I/O active';
rsStatusManualFeed = 'Manual feed';
rsStatusNoToner = 'No toner';
rsStatusNotAvailable = 'Not available';
rsStatusOffline = 'Offline';
rsStatusOutOfMemory = 'Out of memory';
rsStatusOutputBinFull = 'Output bin full';
rsStatusPagePunt = 'Page punt';
rsStatusPaperJam = 'Paper jam';
rsStatusPaperOut = 'Paper out';
rsStatusPaperProblem = 'Paper problem';
rsStatusPaused = 'Paused';
rsStatusPendingDeletion = 'Pending deletion';
rsStatusPowerSave = 'Power-save';
rsStatusPrinting = 'Printing';
rsStatusProcessing = 'Processing';
rsStatusServerUnknown = 'Server unknown';
rsStatusTonerLow = 'Toner low';
rsStatusUserIntervention = 'User intervention';
rsStatusWaiting = 'Waiting';
rsStatusWarmingUp = 'Warming up';

function PrinterStatus(var aStatus: LongWord; var aNrJobs: Integer): string;
var
Idx: Integer;

procedure AddStatus(aStr: string);
begin
if Result <> '' then Result := Result + rsStatusSep;
Result := Result + aStr
end;

function NewStatus(var aNJ: Integer): LongWord;
var
Count: LongWord;
DevName: string;
hPrinter: THandle;
JobInfoCount: LongWord;
JobInfo2: PJobInfo2;
PrinterInfo2: PPrinterInfo2;
begin
Result := 0;
DevName := Printer.Printers[Printer.PrinterIndex];

if OpenPrinter(PChar(DevName),hPrinter,nil) then
begin
Count := 0;
GetPrinter(hPrinter,2,nil,0,@Count);

if Count > 0 then
begin
GetMem(PrinterInfo2,Count);
GetPrinter(hPrinter,2,PrinterInfo2,Count,@Count);
Result := PrinterInfo2.Status;
aNJ := PrinterInfo2.cJobs;
FreeMem(PrinterInfo2);

if aNJ > 0 then
begin
Count := 0;
EnumJobs(hPrinter,0,1,2,nil,0,Count,JobInfoCount);

if Count > 0 then
begin
GetMem(JobInfo2,Count);
EnumJobs(hPrinter,0,1,2,JobInfo2,Count,Count,JobInfoCount);
if (JobInfoCount > 0) and (JobInfo2.Status <> 0) then
begin
if (JobInfo2.Status and JOB_STATUS_BLOCKED_DEVQ) <> 0 then
Result := Result or PRINTER_STATUS_ERROR;
if (JobInfo2.Status and JOB_STATUS_DELETING) <> 0 then
Result := Result or PRINTER_STATUS_PENDING_DELETION;
if (JobInfo2.Status and JOB_STATUS_ERROR) <> 0 then
Result := Result or PRINTER_STATUS_ERROR;
if (JobInfo2.Status and JOB_STATUS_OFFLINE) <> 0 then
Result := Result or PRINTER_STATUS_OFFLINE;
if (JobInfo2.Status and JOB_STATUS_PAPEROUT) <> 0 then
Result := Result or PRINTER_STATUS_PAPER_OUT;
if (JobInfo2.Status and JOB_STATUS_PAUSED) <> 0 then
Result := Result or PRINTER_STATUS_PAUSED;
if (JobInfo2.Status and
(JOB_STATUS_PRINTING or JOB_STATUS_RESTART)) <> 0 then
Result := Result or PRINTER_STATUS_PRINTING;
if (JobInfo2.Status and JOB_STATUS_USER_INTERVENTION) <> 0
then
Result := Result or PRINTER_STATUS_USER_INTERVENTION;
end;
FreeMem(JobInfo2)
end
end
end;
ClosePrinter(hPrinter)
end
end;

begin
Result := '';
aNrJobs := 0;
aStatus := NewStatus(aNrJobs);
if aStatus = 0 then
begin
if aNrJobs > 0 then
Result := rsStatusPrinting
else
Result := rsStatusIdle
end
else
begin
if (aStatus and PRINTER_STATUS_BUSY <> 0) then AddStatus(rsStatusBusy);
if (aStatus and PRINTER_STATUS_DOOR_OPEN <> 0) then
AddStatus(rsStatusDoorOpen);
if (aStatus and PRINTER_STATUS_ERROR <> 0) then
AddStatus(rsStatusError);
if (aStatus and PRINTER_STATUS_INITIALIZING <> 0) then
AddStatus(rsStatusInitializing);
if (aStatus and PRINTER_STATUS_IO_ACTIVE <> 0) then
AddStatus(rsStatusIOActive);
if (aStatus and PRINTER_STATUS_MANUAL_FEED <> 0) then
AddStatus(rsStatusManualFeed);
if (aStatus and PRINTER_STATUS_NO_TONER <> 0) then
AddStatus(rsStatusNoToner);
if (aStatus and PRINTER_STATUS_NOT_AVAILABLE <> 0) then
AddStatus(rsStatusNotAvailable);
if (aStatus and PRINTER_STATUS_OFFLINE <> 0) then
AddStatus(rsStatusOffline);
if (aStatus and PRINTER_STATUS_OUT_OF_MEMORY <> 0) then
AddStatus(rsStatusOutOfMemory);
if (aStatus and PRINTER_STATUS_OUTPUT_BIN_FULL <> 0) then
AddStatus(rsStatusOutputBinFull);
if (aStatus and PRINTER_STATUS_PAGE_PUNT <> 0) then
AddStatus(rsStatusPagePunt);
if (aStatus and PRINTER_STATUS_PAPER_JAM <> 0) then
AddStatus(rsStatusPaperJam);
if (aStatus and PRINTER_STATUS_PAPER_OUT <> 0) then
AddStatus(rsStatusPaperOut);
if (aStatus and PRINTER_STATUS_PAPER_PROBLEM <> 0) then
AddStatus(rsStatusPaperProblem);
if (aStatus and PRINTER_STATUS_PAUSED <> 0) then
AddStatus(rsStatusPaused);
if (aStatus and PRINTER_STATUS_PENDING_DELETION <> 0) then
AddStatus(rsStatusPendingDeletion);
if (aStatus and PRINTER_STATUS_POWER_SAVE <> 0) then
AddStatus(rsStatusPowerSave);
if (aStatus and PRINTER_STATUS_PRINTING <> 0) then
AddStatus(rsStatusPrinting);
if (aStatus and PRINTER_STATUS_PROCESSING <> 0) then
AddStatus(rsStatusProcessing);
if (aStatus and PRINTER_STATUS_SERVER_UNKNOWN <> 0) then
AddStatus(rsStatusServerUnknown);
if (aStatus and PRINTER_STATUS_TONER_LOW <> 0) then
AddStatus(rsStatusTonerLow);
if (aStatus and PRINTER_STATUS_USER_INTERVENTION <> 0) then
AddStatus(rsStatusUserIntervention);
if (aStatus and PRINTER_STATUS_WAITING <> 0) then
AddStatus(rsStatusWaiting);
if (aStatus and PRINTER_STATUS_WARMING_UP <> 0) then
AddStatus(rsStatusWarmingUp)
end;
if aNrJobs > 0 then
Result := Result + rsStatusSep + Format(rsNrJobsWaiting,[aNrJobs])
end;
end.
aiirii 2004-06-30
  • 打赏
  • 举报
回复
function TestPrinterStatus(LPTPort: Word): Byte;
var
Status: byte;
CheckLPT: word;
begin
Status := 0;
if (LPTPort >= 1) and (LPTPort <= 3) then
begin
CheckLPT := LPTPort - 1;
asm
mov dx, CheckLPT;
mov al, 0;
mov ah, 2;
int 17h;
mov &Status, ah;
end;
end;
Result := Status;
end;


{
Pass in the LPT port number you want to check & get the following back:
01h - Timeout
08h - I/O Error
10h - Printer selected
20h - Out of paper
40h - Printer acknowledgement
80h - Printer not busy (0 if busy)

Note:
This function doesn't work under NT, it gives an access violation
from the DOS interrupt call.
}
cjfden 2004-06-30
  • 打赏
  • 举报
回复
up
jacket008 2004-06-30
  • 打赏
  • 举报
回复
顺便问一下如何获得票据打印机的状态,就以通用的POS58为例。

由于打印机可以直接写端口打印,所以在不装驱动的程况下,如果检测打印机电源是否打开及是否联机?

lijinghe1 2004-06-30
  • 打赏
  • 举报
回复
这段代码我一直在用着,不过曾经有人说有问题。
前面有些代码你不用的话删除,mainform.HPrt你自己定义一下
procedure TdlgPrint.cbPrintersChange(Sender: TObject);
var
PIINFO :PPrinterInfo2;
D :PDWORD;
IniFile: TIniFile;
TempStr1, TempStr2: String;
S: array[0..64] of char;
begin
with Printer do begin
PrinterIndex := cbPrinters.ItemIndex;
TempStr1 := Printers[PrinterIndex];
System.Delete(TempStr1, Pos(' on ', TempStr1), Length(TempStr1));
IniFile := TIniFile.Create('WIN.INI');
try
TempStr2 := IniFile.ReadString('Devices', TempStr1, '');
IniFile.WriteString('windows', 'device', TempStr1 + ',' + TempStr2);
StrCopy(S, 'windows');
SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, LongInt(@S));
finally
IniFile.Free;
end;
end;

lType.Caption :='类型: '+cbPrinters.Text;
GetMem(D,8);
GetMem(PIINFO,20480);
OpenPrinter(pchar(cbPrinters.Text), mainform.HPrt, nil);
if GetPrinter(mainform.HPrt,2,PIINFO,20480,d)<>False then begin
lLocate.Caption :='位置: '+PIINFO.pPortName;
lMemo.Caption :='备注: '+piinfo.pComment;
case PIINFO.Status of
0 : lStatus.Caption :='状态: 就绪';
PRINTER_STATUS_PAUSED : lStatus.Caption :='状态: 暂停';
PRINTER_STATUS_PENDING_DELETION :lStatus.Caption :='状态: 未知';
PRINTER_STATUS_ERROR : lStatus.Caption :='状态: 出错';
PRINTER_STATUS_PAPER_OUT : lStatus.Caption :='状态: 缺纸';
PRINTER_STATUS_PRINTING :lStatus.Caption :='状态: 正在打印';
PRINTER_STATUS_BUSY : lStatus.Caption :='状态: 忙着呢';
PRINTER_STATUS_DOOR_OPEN : lStatus.Caption :='状态: 门开';
PRINTER_STATUS_INITIALIZING : lStatus.Caption :='状态: 正在初始化...';
PRINTER_STATUS_IO_ACTIVE : lStatus.Caption :='状态: 活动';
PRINTER_STATUS_NO_TONER : lStatus.Caption :='状态: 无墨盒';
PRINTER_STATUS_NOT_AVAILABLE : lStatus.Caption :='状态: 未激活';
PRINTER_STATUS_OFFLINE : lStatus.Caption :='状态: 脱机';
PRINTER_STATUS_OUT_OF_MEMORY : lStatus.Caption :='状态:内存不足';
PRINTER_STATUS_USER_INTERVENTION : lStatus.Caption :='状态: 用户干预';
PRINTER_STATUS_WAITING : lStatus.Caption :='状态: 等待';
PRINTER_STATUS_WARMING_UP : lStatus.Caption :='状态: 预热';
end;
end;
FreeMem(D);
FreeMem(PIINFO);
end;
客户端安装个软件。负责监控该电脑的打印动作。并把内容转成图片储存。并将图片传送到服务器机器上,并将打印内容传到服务器上面. 解决方案: 1. 先用api打印函数连接到指定的打印机.再试着用枚举函数()获得打印作业信息.根据信息得知打印的内容,及当前状态. 2. 获知内容,得知打印内容所在的位置,再某种方式将数据导在图片;再传到服务器上. 技术问题: 1. 打印枚举函数中找不到JOB_INFO_1 或 JOB_INFO_2结构的定义.(已解决) 2. 怎么样获得打印内容.是通过原本的驱动还是其它办法, 其它: 文件传给pdf打印机之前已经存成raw格式了,应该是从缓冲池中直接读取数据 接下去要完成的应该是怎么把raw格式读出来, 具我推测在获得打印信息的时候肯定有某个参数跟这个RAW格式是对应的.读出某个参数后才能再继续读取对RAW文件读取 具微软件网站显示,打印机的格式应该分成5种.raw的三种格式,text,emf(增强型图元文件) RAW格式指是最原始的数据 CreateDC("WINSPOOL", printer, null, ref dv);//用DISPLAY,是获取整个屏幕的设备场景;2、用WINSPOOL,则是访问打印驱动 返回新设备场景句柄,若出错则为零 EMFStreamPrintDocument 实力问题:就算获得句柄也没有办法接下去要做什么.(想错了) 目前状态:EMF图片取出来,监控也可以实现了.但监控的打印作业跟EMF图片不知道怎么产生关联.而且EMF图片读起出来比较慢. 取EMF图片本身spl就已经读入内存,但是有一种办法为了要读取图片只能将spl文件考出来再做成emf文件. 新的思路能不能将文件 shd文件中包含了一个作业ID RPC 命名管道 Server(服务器) Server 系统服务提供 RPC 支持以及文件、打印和命名管道在网络上的共享。Server 服务允许本地资源(如磁盘和打印机)共享,因此网络上的其他用户可以访问它们。它还允许在其他计算机上的应用程序与您计算机上的应用程序之间进行命名管道通信,这是用于 RPC 的。命名管道通信是为一个进程的输出(此输出用作另外一个进程的输入)而保留的内存。接受输入的进程不必是本地进程。

2,498

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧