HANDLE FindFirstPrinterChangeNotification( HANDLE hPrinter, DWORD Flags, DWORD Options, LPPRINTER_NOTIFY_OPTIONS PrinterNotifyOptions):
FlagsとPrinterNotifyOptionsは、どちらか、または両方設定できる。
この関数の詳しい説明については、SDKのドキュメントか、後述に記したサンプルを参照。
引数の意味は、以下の通り。
| hPrinter | 監視を行うプリンタまたはプリントサーバのハンドル |
| Flags | どのようなイベントを監視するかを指定するフラグ |
| Options | 0でなければならない。 |
| PrinterNotifyOptions | どのような情報を取得するかを指定する構造体のデータへのポインタ。なお、このデータで指定した情報が変更されると、変更通知イベントが発生する。 |
戻り値は、変更通知オブジェクトのハンドルである。
void DoPrtNotify()
{
HANDLE hPrinter = INVALID_HANDLE_VALUE;
HANDLE hNotify;
BOOL b;
PRINTER_NOTIFY_INFO *p;
DWORD i;
char *pBuf;
DWORD *adwData;
PRINTER_NOTIFY_OPTIONS no;
PRINTER_NOTIFY_OPTIONS_TYPE not[2];
WORD pnf[100], jnf[100];
DWORD ChangeReason;
no.Version = 2;
no.Count = 2;
no.pTypes = not;
i = 0;
pnf[i++] = PRINTER_NOTIFY_FIELD_SERVER_NAME;
pnf[i++] = PRINTER_NOTIFY_FIELD_PRINTER_NAME;
pnf[i++] = PRINTER_NOTIFY_FIELD_SHARE_NAME;
pnf[i++] = PRINTER_NOTIFY_FIELD_PORT_NAME;
pnf[i++] = PRINTER_NOTIFY_FIELD_DRIVER_NAME;
pnf[i++] = PRINTER_NOTIFY_FIELD_COMMENT;
pnf[i++] = PRINTER_NOTIFY_FIELD_LOCATION;
pnf[i++] = PRINTER_NOTIFY_FIELD_SEPFILE;
pnf[i++] = PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR;
pnf[i++] = PRINTER_NOTIFY_FIELD_PARAMETERS;
pnf[i++] = PRINTER_NOTIFY_FIELD_DATATYPE;
pnf[i++] = PRINTER_NOTIFY_FIELD_ATTRIBUTES;
pnf[i++] = PRINTER_NOTIFY_FIELD_PRIORITY;
pnf[i++] = PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY;
pnf[i++] = PRINTER_NOTIFY_FIELD_START_TIME;
pnf[i++] = PRINTER_NOTIFY_FIELD_UNTIL_TIME;
pnf[i++] = PRINTER_NOTIFY_FIELD_STATUS_STRING;
pnf[i++] = PRINTER_NOTIFY_FIELD_CJOBS;
pnf[i++] = PRINTER_NOTIFY_FIELD_AVERAGE_PPM;
pnf[i++] = PRINTER_NOTIFY_FIELD_TOTAL_PAGES;
pnf[i++] = PRINTER_NOTIFY_FIELD_PAGES_PRINTED;
pnf[i++] = PRINTER_NOTIFY_FIELD_TOTAL_BYTES;
pnf[i++] = PRINTER_NOTIFY_FIELD_BYTES_PRINTED;
not[0].Type = PRINTER_NOTIFY_TYPE;
not[0].Count = i;
not[0].pFields = pnf;
i=0;
jnf[i++] = JOB_NOTIFY_FIELD_PRINTER_NAME;
jnf[i++] = JOB_NOTIFY_FIELD_MACHINE_NAME;
jnf[i++] = JOB_NOTIFY_FIELD_PORT_NAME;
jnf[i++] = JOB_NOTIFY_FIELD_USER_NAME;
jnf[i++] = JOB_NOTIFY_FIELD_NOTIFY_NAME;
jnf[i++] = JOB_NOTIFY_FIELD_DATATYPE;
jnf[i++] = JOB_NOTIFY_FIELD_PRINT_PROCESSOR;
jnf[i++] = JOB_NOTIFY_FIELD_PARAMETERS;
jnf[i++] = JOB_NOTIFY_FIELD_DRIVER_NAME;
jnf[i++] = JOB_NOTIFY_FIELD_STATUS_STRING;
jnf[i++] = JOB_NOTIFY_FIELD_DOCUMENT;
jnf[i++] = JOB_NOTIFY_FIELD_PRIORITY;
jnf[i++] = JOB_NOTIFY_FIELD_POSITION;
jnf[i++] = JOB_NOTIFY_FIELD_START_TIME;
jnf[i++] = JOB_NOTIFY_FIELD_UNTIL_TIME;
jnf[i++] = JOB_NOTIFY_FIELD_TIME;
jnf[i++] = JOB_NOTIFY_FIELD_TOTAL_PAGES;
jnf[i++] = JOB_NOTIFY_FIELD_PAGES_PRINTED;
jnf[i++] = JOB_NOTIFY_FIELD_TOTAL_BYTES;
jnf[i++] = JOB_NOTIFY_FIELD_BYTES_PRINTED;
not[1].Type = JOB_NOTIFY_TYPE;
not[1].Count = 20;
not[1].pFields = jnf;
b = OpenPrinter(
"\\\\ringo\\ringoprt",
&hPrinter,
NULL);
if(!b) {
printf("printer can not open(%d)\n", GetLastError());
return;
}
hNotify = FindFirstPrinterChangeNotification(
hPrinter,
PRINTER_CHANGE_ALL,
0,
&no);
if(hNotify == INVALID_HANDLE_VALUE) {
printf("find first fail(%d)\n", GetLastError());
ClosePrinter(hPrinter);
return;
}
for(;;) {
WaitForSingleObject(hNotify, INFINITE);
no.Flags = 0;
b = FindNextPrinterChangeNotification(
hNotify,
&ChangeReason,
&no,
&p);
if(!b) printf("find next error(%d)\n", GetLastError());
printf("\nイベント発生...\n");
printf("\t通知理由: ");
if(ChangeReason & PRINTER_CHANGE_ADD_PRINTER) printf("プリンタ追加 ");
if(ChangeReason & PRINTER_CHANGE_SET_PRINTER) printf("プリンタの設定変更 " );
if(ChangeReason & PRINTER_CHANGE_DELETE_PRINTER) printf("プリンタ削除 ");
if(ChangeReason & PRINTER_CHANGE_FAILED_CONNECTION_PRINTER) printf("接続失敗 ");
if(ChangeReason & PRINTER_CHANGE_ADD_JOB) printf("ジョブ追加 ");
if(ChangeReason & PRINTER_CHANGE_SET_JOB) printf("ジョブ設定変更 ");
if(ChangeReason & PRINTER_CHANGE_DELETE_JOB) printf("ジョブ削除 ");
if(ChangeReason & PRINTER_CHANGE_WRITE_JOB) printf("ジョブ書き込み ");
if(ChangeReason & PRINTER_CHANGE_ADD_FORM) printf("フォーム追加 ");
if(ChangeReason & PRINTER_CHANGE_SET_FORM) printf("フォーム設定変更 ");
if(ChangeReason & PRINTER_CHANGE_DELETE_FORM) printf("フォーム削除 ");
if(ChangeReason & PRINTER_CHANGE_ADD_PORT) printf("ポート追加 ");
if(ChangeReason & PRINTER_CHANGE_CONFIGURE_PORT) printf("ポート設定変更 ");
if(ChangeReason & PRINTER_CHANGE_DELETE_PORT) printf("ポート削除 ");
if(ChangeReason & PRINTER_CHANGE_ADD_PRINT_PROCESSOR) printf("プリントプロセッサ追加 ");
if(ChangeReason & PRINTER_CHANGE_DELETE_PRINT_PROCESSOR) printf("プリントプロセッサ削除 ");
if(ChangeReason & PRINTER_CHANGE_ADD_PRINTER_DRIVER) printf("ドライバ追加 ");
if(ChangeReason & PRINTER_CHANGE_SET_PRINTER_DRIVER) printf("ドライバ設定変更 ");
if(ChangeReason & PRINTER_CHANGE_DELETE_PRINTER_DRIVER) printf("ドライバ削除 ");
if(ChangeReason & PRINTER_CHANGE_TIMEOUT) printf("タイムアウト ");
printf("\n");
if(p != NULL) {
for(i=0; i<p->Count; i++) {
pBuf = p->aData[i].NotifyData.Data.pBuf;
adwData = p->aData[i].NotifyData.adwData;
switch(p->aData[i].Type) {
case PRINTER_NOTIFY_TYPE:
printf("\tプリンタ通知(no.%d)...", i);
switch(p->aData[i].Field) {
case PRINTER_NOTIFY_FIELD_SERVER_NAME:
printf("サーバ名:%s\n", pBuf);
break;
case PRINTER_NOTIFY_FIELD_PRINTER_NAME:
printf("プリンタ名:%s\n", pBuf);
break;
case PRINTER_NOTIFY_FIELD_SHARE_NAME:
printf("共有名:%s\n", pBuf);
break;
case PRINTER_NOTIFY_FIELD_PORT_NAME:
printf("ポート名:%s\n", pBuf);
break;
case PRINTER_NOTIFY_FIELD_DRIVER_NAME:
printf("ドライバ名:%s\n", pBuf);
break;
case PRINTER_NOTIFY_FIELD_COMMENT:
printf("プリンタの説明:%s\n", pBuf);
break;
case PRINTER_NOTIFY_FIELD_LOCATION:
printf("設置場所:%s\n", pBuf);
break;
case PRINTER_NOTIFY_FIELD_DEVMODE:
// DEVMODE structure
break;
case PRINTER_NOTIFY_FIELD_SEPFILE:
printf("区切りファイル名:%s\n", pBuf);
break;
case PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR:
printf("プリントプロセッサ名:%s\n", pBuf);
break;
case PRINTER_NOTIFY_FIELD_PARAMETERS:
printf("プリントプロセッサのパラメータ:%s\n", pBuf);
break;
case PRINTER_NOTIFY_FIELD_DATATYPE:
printf("データの種類:%s\n", pBuf);
break;
case PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR:
// SECURITY_DESCRIPTOR
break;
case PRINTER_NOTIFY_FIELD_ATTRIBUTES:
printf("プリンタの状態:\n");
if(PRINTER_ATTRIBUTE_QUEUED & adwData[0]) printf("\t\tキュー\n");
if(PRINTER_ATTRIBUTE_DIRECT & adwData[0]) printf("\t\tプリンタに直接データを送る\n");
if(PRINTER_ATTRIBUTE_DEFAULT & adwData[0]) printf("\t\tデフォルト\n");
if(PRINTER_ATTRIBUTE_SHARED & adwData[0]) printf("\t\t共有する\n");
if(PRINTER_ATTRIBUTE_NETWORK & adwData[0]) printf("\t\tネットワーク\n");
if(PRINTER_ATTRIBUTE_HIDDEN & adwData[0]) printf("\t\t隠しプリンタ\n");
if(PRINTER_ATTRIBUTE_LOCAL & adwData[0]) printf("\t\tローカルプリンタ\n");
if(PRINTER_ATTRIBUTE_ENABLE_DEVQ & adwData[0]) printf("\t\t一致しないドキュメントを保留する\n");
if(PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS & adwData[0]) printf("\t\t印刷後ドキュメントを残す\n");
if(PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST & adwData[0]) printf("\t\tスプールされたドキュメントを最初に印刷する\n");
if(PRINTER_ATTRIBUTE_WORK_OFFLINE & adwData[0]) printf("\t\tオフライン印刷\n");
if(PRINTER_ATTRIBUTE_ENABLE_BIDI & adwData[0]) printf("\t\tenable BIDI(?)\n");
if(PRINTER_ATTRIBUTE_RAW_ONLY & adwData[0]) printf("\t\t直接データ送信のみ\n");
break;
case PRINTER_NOTIFY_FIELD_PRIORITY:
printf("現在の優先度:%d\n", adwData[0]);
break;
case PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY:
printf("デフォルトの優先度:%d\n", adwData[0]);
break;
case PRINTER_NOTIFY_FIELD_START_TIME:
printf("利用可能となる開始時間:%02d:%02d\n", adwData[0]/60, adwData[0]%60);
break;
case PRINTER_NOTIFY_FIELD_UNTIL_TIME:
printf("利用不可能になる時間:%02d:%02d\n", adwData[0]/60, adwData[0]%60);
break;
case PRINTER_NOTIFY_FIELD_STATUS:
if(adwData[0] & PRINTER_STATUS_PAUSED) printf("一時停止 ");
if(adwData[0] & PRINTER_STATUS_ERROR) printf("エラー ");
if(adwData[0] & PRINTER_STATUS_PENDING_DELETION) printf("pending_deletion ");
if(adwData[0] & PRINTER_STATUS_PAPER_JAM) printf("紙詰まり ");
if(adwData[0] & PRINTER_STATUS_PAPER_OUT) printf("紙排出 ");
if(adwData[0] & PRINTER_STATUS_MANUAL_FEED) printf("manual_feed ");
if(adwData[0] & PRINTER_STATUS_PAPER_PROBLEM) printf("紙の問題 ");
if(adwData[0] & PRINTER_STATUS_OFFLINE) printf("オフライン ");
if(adwData[0] & PRINTER_STATUS_IO_ACTIVE) printf("io_active ");
if(adwData[0] & PRINTER_STATUS_BUSY) printf("busy ");
if(adwData[0] & PRINTER_STATUS_PRINTING) printf("印刷中 ");
if(adwData[0] & PRINTER_STATUS_OUTPUT_BIN_FULL) printf("output_bin_full ");
if(adwData[0] & PRINTER_STATUS_NOT_AVAILABLE) printf("not_available ");
if(adwData[0] & PRINTER_STATUS_WAITING) printf("待機中 ");
if(adwData[0] & PRINTER_STATUS_PROCESSING) printf("処理中 ");
if(adwData[0] & PRINTER_STATUS_INITIALIZING) printf("初期化中 ");
if(adwData[0] & PRINTER_STATUS_WARMING_UP) printf("warming_up ");
if(adwData[0] & PRINTER_STATUS_TONER_LOW) printf("トナーが少ない ");
if(adwData[0] & PRINTER_STATUS_NO_TONER) printf("トナーが無い ");
if(adwData[0] & PRINTER_STATUS_PAGE_PUNT) printf("page_punt ");
if(adwData[0] & PRINTER_STATUS_USER_INTERVENTION) printf("user_intervention ");
if(adwData[0] & PRINTER_STATUS_OUT_OF_MEMORY) printf("out_of_memory ");
if(adwData[0] & PRINTER_STATUS_DOOR_OPEN) printf("door_open ");
if(adwData[0] & PRINTER_STATUS_SERVER_UNKNOWN) printf("server_unknown ");
if(adwData[0] & PRINTER_STATUS_POWER_SAVE) printf("power_save ");
break;
case PRINTER_NOTIFY_FIELD_STATUS_STRING:
printf("状態:%d\n", pBuf);
case PRINTER_NOTIFY_FIELD_CJOBS:
printf("キューにためられたジョブの数:%d\n", adwData[0]);
break;
case PRINTER_NOTIFY_FIELD_AVERAGE_PPM:
printf("1ページあたりの平均印刷時間:%d分\n", adwData[0]);
break;
case PRINTER_NOTIFY_FIELD_TOTAL_PAGES:
printf("総ページ数:%d\n", adwData[0]);
break;
case PRINTER_NOTIFY_FIELD_PAGES_PRINTED:
printf("印刷ページ数:%d\n", adwData[0]);
break;
case PRINTER_NOTIFY_FIELD_TOTAL_BYTES:
printf("総バイト数:%d\n", adwData[0]);
break;
case PRINTER_NOTIFY_FIELD_BYTES_PRINTED:
printf("印刷バイト数:%d\n", adwData[0]);
break;
}
break;
case JOB_NOTIFY_TYPE:
printf("\tジョブ通知(no.%d, id:%d)...", i, p->aData[i].Id);
switch(p->aData[i].Field) {
case JOB_NOTIFY_FIELD_PRINTER_NAME:
printf("プリンタ名:%s\n", pBuf);
break;
case JOB_NOTIFY_FIELD_MACHINE_NAME:
printf("ジョブ作成元マシン名:%s\n", pBuf);
break;
case JOB_NOTIFY_FIELD_PORT_NAME:
printf("ポート:%s\n", pBuf);
break;
case JOB_NOTIFY_FIELD_USER_NAME:
printf("ジョブ作成元ユーザ名:%s\n", pBuf);
break;
case JOB_NOTIFY_FIELD_NOTIFY_NAME:
printf("通知先ユーザ:%s\n", pBuf);
break;
case JOB_NOTIFY_FIELD_DATATYPE:
printf("データの種類:%s\n", pBuf);
break;
case JOB_NOTIFY_FIELD_PRINT_PROCESSOR:
printf("プリントプロセッサ名:%s\n", pBuf);
break;
case JOB_NOTIFY_FIELD_PARAMETERS:
printf("プリントプロセッサへのパラメータ:%s\n", pBuf);
break;
case JOB_NOTIFY_FIELD_DRIVER_NAME:
printf("ドライバ名:%s\n", pBuf);
break;
case JOB_NOTIFY_FIELD_DEVMODE:
// DEVMODE
break;
case JOB_NOTIFY_FIELD_STATUS:
printf("ジョブの状態(flag):");
if(adwData[0] & JOB_STATUS_PAUSED) printf("一時停止 ");
if(adwData[0] & JOB_STATUS_ERROR) printf("エラー ");
if(adwData[0] & JOB_STATUS_DELETING) printf("削除中 ");
if(adwData[0] & JOB_STATUS_SPOOLING) printf("スプール中 ");
if(adwData[0] & JOB_STATUS_PRINTING) printf("印刷中 ");
if(adwData[0] & JOB_STATUS_OFFLINE) printf("オフライン ");
if(adwData[0] & JOB_STATUS_PAPEROUT) printf("出力中 ");
if(adwData[0] & JOB_STATUS_PRINTED) printf("印刷終了 ");
if(adwData[0] & JOB_STATUS_DELETED) printf("削除終了 ");
if(adwData[0] & JOB_STATUS_BLOCKED_DEVQ) printf("blocked_dev_queue ");
if(adwData[0] & JOB_STATUS_USER_INTERVENTION) printf("user_intervention ");
if(adwData[0] & JOB_STATUS_RESTART) printf("リスタート ");
printf("\n");
break;
case JOB_NOTIFY_FIELD_STATUS_STRING:
printf("ジョブの状態(msg):%s\n", pBuf);
break;
case JOB_NOTIFY_FIELD_DOCUMENT:
printf("ドキュメント名:%s\n", pBuf);
break;
case JOB_NOTIFY_FIELD_PRIORITY:
printf("優先度:%d\n", adwData[0]);
break;
case JOB_NOTIFY_FIELD_POSITION:
printf("順番:%d\n", adwData[0]);
break;
case JOB_NOTIFY_FIELD_SUBMITTED:
//SYSTEMTIME
break;
case JOB_NOTIFY_FIELD_START_TIME:
printf("印刷開始時間: %d:%d\n", adwData[0]/60, adwData[0]%60);
break;
case JOB_NOTIFY_FIELD_UNTIL_TIME:
printf("印刷終了時間: %d:%d\n", adwData[0]/60, adwData[0]%60);
break;
case JOB_NOTIFY_FIELD_TIME:
printf("経過時間: %d: %d\n", adwData[0]/60, adwData[0]%60);
break;
case JOB_NOTIFY_FIELD_TOTAL_PAGES:
printf("印刷総枚数: %d\n", adwData[0]);
break;
case JOB_NOTIFY_FIELD_PAGES_PRINTED:
printf("印刷枚数: %d\n", adwData[0]);
break;
case JOB_NOTIFY_FIELD_TOTAL_BYTES:
printf("総バイト数: %d\n", adwData[0]);
break;
case JOB_NOTIFY_FIELD_BYTES_PRINTED:
printf("印刷バイト数: %d\n", adwData[0]);
break;
}
break;
}
}
b = FreePrinterNotifyInfo(p);
if(!b) printf("free error:%d\n", GetLastError());
}
}
if(hPrinter!=INVALID_HANDLE_VALUE) {
ClosePrinter(hPrinter);
FindClosePrinterChangeNotification(hNotify);
}
}