BOOL FindNextPrinterChangeNotification( HANDLE hChange, PDWORD ChangeFlags, LPPRINTER_NOTIFY_OPTIONS PrinterNotifyOptions, LPPRINTER_NOTIFY_INFO *PrinterNotifyInfo);
この関数の詳しい説明については、SDKのドキュメントか、後述に記したサンプルを参照。
引数の意味は、以下の通り。
hChange | 変更通知オブジェクトのハンドル。 |
ChangeFlags | どのようなイベントが起こったのかを表すフラグ。PRINTER_CHANGE_XXXの組み合わせ。 |
PrinterNotifyOptions | 次回変更情報取得時にどのような情報を受け取るかを指定するデータ。フラグにPRINTER_NOTIFY_OPTIONS_REFRSHを指定した場合、すべての情報を受け取る。(JOB型は返らない) |
PrinterNotifyInfo | 変更通知情報を格納位置を受け取るためのポインタのポインタ。 |
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); } }