Win32API プリンタの変更を監視する

プリンタの変更を監視するためには、FindFirstPrinterChangeNotification, FindNextPrinterChangeNotificationを用いる。



HANDLE FindFirstPrinterChangeNotification(
  HANDLE hPrinter,   // 変更を監視するプリンタまたはプリンタサーバーを識別する
                         // ハンドル
  DWORD fdwFlags,    // 監視する条件を指定するフラグ
  DWORD fdwOptions, // 予約済み。0 でなければならない
  LPVOID pPrinterNotifyOptions
                         // 監視するプリンタ情報を指定する構造体へのポインタ
);


HANDLE FindFirstPrinterChangeNotification(
  HANDLE hPrinter,   // 変更を監視するプリンタまたはプリンタサーバーを識別する
                         // ハンドル
  DWORD fdwFlags,    // 監視する条件を指定するフラグ
  DWORD fdwOptions, // 予約済み。0 でなければならない
  LPVOID pPrinterNotifyOptions
                         // 監視するプリンタ情報を指定する構造体へのポインタ
);



  • Microsoft XPS Document Writerを監視するサンプルプログラム
  • #include <windows.h>
    #include <stdio.h>
    #include <locale.h>
    
    #include <winspool.h>
    #pragma comment(lib, "winspool.lib")
    
    void PrintPrinterNotifyInfoData(const PRINTER_NOTIFY_INFO *lpNotifyInfo)
    {
        for (DWORD i = 0; i < lpNotifyInfo->Count; i++) {
            
            //WCHAR* pBuf = (WCHAR*)InfoData.NotifyData.Data.pBuf;
            PRINTER_NOTIFY_INFO_DATA InfoData = lpNotifyInfo->aData[i];
            if (InfoData.Type == JOB_NOTIFY_TYPE) {
                puts("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
                puts("JOB_NOTIFY_TYPE");
                printf("Job Identifier: %d\n", InfoData.Id);
                
                switch (InfoData.Field) {
                case JOB_NOTIFY_FIELD_PRINTER_NAME:
                    wprintf(L"JOB_NOTIFY_FIELD_PRINTER_NAME: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case JOB_NOTIFY_FIELD_MACHINE_NAME:
                    wprintf(L"JOB_NOTIFY_FIELD_MACHINE_NAME: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case JOB_NOTIFY_FIELD_PORT_NAME:
                    wprintf(L"JOB_NOTIFY_FIELD_PORT_NAME: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case JOB_NOTIFY_FIELD_USER_NAME:
                    wprintf(L"JOB_NOTIFY_FIELD_USER_NAME: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case JOB_NOTIFY_FIELD_NOTIFY_NAME:
                    wprintf(L"JOB_NOTIFY_FIELD_NOTIFY_NAME: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case JOB_NOTIFY_FIELD_DATATYPE:
                    wprintf(L"JOB_NOTIFY_FIELD_DATATYPE: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case JOB_NOTIFY_FIELD_PRINT_PROCESSOR:
                    wprintf(L"JOB_NOTIFY_FIELD_PRINT_PROCESSOR: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case JOB_NOTIFY_FIELD_PARAMETERS:
                    wprintf(L"JOB_NOTIFY_FIELD_PARAMETERS: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case JOB_NOTIFY_FIELD_DRIVER_NAME:
                    wprintf(L"JOB_NOTIFY_FIELD_DRIVER_NAME: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case JOB_NOTIFY_FIELD_DEVMODE:
                    wprintf(L"JOB_NOTIFY_FIELD_DEVMODE: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case JOB_NOTIFY_FIELD_STATUS:
                    switch (InfoData.NotifyData.adwData[0]) {
                    case JOB_STATUS_BLOCKED_DEVQ:
                        wprintf(L"JOB_NOTIFY_FIELD_STATUS: The driver cannot print the job.\n");
                        break;
                    case JOB_STATUS_DELETED:
                        wprintf(L"JOB_NOTIFY_FIELD_STATUS: Job has been deleted.\n");
                        break;
                        
                    case JOB_STATUS_DELETING:
                        wprintf(L"JOB_NOTIFY_FIELD_STATUS: Job is being deleted.\n");
                        break;
    
                    case JOB_STATUS_ERROR:                
                        wprintf(L"JOB_NOTIFY_FIELD_STATUS: An error is associated with the job.\n");
                        break;
                    
                    case JOB_STATUS_OFFLINE:
                        wprintf(L"JOB_NOTIFY_FIELD_STATUS: Printer is offline.\n");
                        break;
    
                    case JOB_STATUS_PAPEROUT:
                        wprintf(L"JOB_NOTIFY_FIELD_STATUS: Printer is out of paper.\n");
                        break;
    
                    case JOB_STATUS_PAUSED:
                        wprintf(L"JOB_NOTIFY_FIELD_STATUS: Job is paused.\n");
                        break;
    
    
                    case JOB_STATUS_PRINTED:
                        wprintf(L"JOB_NOTIFY_FIELD_STATUS: Job has printed.\n");
                        break;
                        
                    case JOB_STATUS_PRINTING:
                        wprintf(L"JOB_NOTIFY_FIELD_STATUS: Job is printing.\n");
                        break;
    
                    case JOB_STATUS_RESTART:
                        wprintf(L"JOB_NOTIFY_FIELD_STATUS: Job has been restarted.\n");
                        break;
    
                    case JOB_STATUS_SPOOLING:
                        wprintf(L"JOB_NOTIFY_FIELD_STATUS: Job is spooling.\n");
                        break;
    
                    case JOB_STATUS_USER_INTERVENTION:
                        wprintf(L"JOB_NOTIFY_FIELD_STATUS: Printer has an error that requires the user to do something.\n");
                        break;
                    default:
                        wprintf(L"JOB_NOTIFY_FIELD_STATUS: \n");
                        break;
                    }
                    break;
    
                case JOB_NOTIFY_FIELD_STATUS_STRING:
                    wprintf(L"JOB_NOTIFY_FIELD_STATUS_STRING: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR:
                    wprintf(L"JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR: \n");
                    break;
    
                case JOB_NOTIFY_FIELD_DOCUMENT:
                    wprintf(L"JOB_NOTIFY_FIELD_DOCUMENT: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case JOB_NOTIFY_FIELD_PRIORITY:
                    wprintf(L"JOB_NOTIFY_FIELD_PRIORITY: %d\n", InfoData.NotifyData.adwData[0]);
                    break;
    
                case JOB_NOTIFY_FIELD_POSITION:
                    wprintf(L"JOB_NOTIFY_FIELD_POSITION: %d\n", InfoData.NotifyData.adwData[0]);
                    break;
    
                case JOB_NOTIFY_FIELD_SUBMITTED:
                    wprintf(L"JOB_NOTIFY_FIELD_SUBMITTED: %04d/%02d/%02d %02d:%02d:%02d\n", 
                        ((SYSTEMTIME*)InfoData.NotifyData.Data.pBuf)->wYear,
                        ((SYSTEMTIME*)InfoData.NotifyData.Data.pBuf)->wMonth,
                        ((SYSTEMTIME*)InfoData.NotifyData.Data.pBuf)->wDay,
                        ((SYSTEMTIME*)InfoData.NotifyData.Data.pBuf)->wHour,
                        ((SYSTEMTIME*)InfoData.NotifyData.Data.pBuf)->wMinute,
                        ((SYSTEMTIME*)InfoData.NotifyData.Data.pBuf)->wSecond);
                    break;
    
                case JOB_NOTIFY_FIELD_START_TIME:
                    wprintf(L"JOB_NOTIFY_FIELD_START_TIME: %d\n", InfoData.NotifyData.adwData[0]);
                    break;
    
                case JOB_NOTIFY_FIELD_UNTIL_TIME:
                    wprintf(L"JOB_NOTIFY_FIELD_UNTIL_TIME: %d\n", InfoData.NotifyData.adwData[0]);
                    break;
    
                case JOB_NOTIFY_FIELD_TIME:
                    wprintf(L"JOB_NOTIFY_FIELD_TIME: %d\n", InfoData.NotifyData.adwData[0]);
                    break;
    
                case JOB_NOTIFY_FIELD_TOTAL_PAGES:
                    wprintf(L"JOB_NOTIFY_FIELD_TOTAL_PAGES: %d\n", InfoData.NotifyData.adwData[0]);
                    break;
    
                case JOB_NOTIFY_FIELD_PAGES_PRINTED:
                    wprintf(L"JOB_NOTIFY_FIELD_PAGES_PRINTED: %d\n", InfoData.NotifyData.adwData[0]);
                    break;
    
                case JOB_NOTIFY_FIELD_TOTAL_BYTES:
                    wprintf(L"JOB_NOTIFY_FIELD_TOTAL_BYTES: %d\n", InfoData.NotifyData.adwData[0]);
                    break;
    
                case JOB_NOTIFY_FIELD_BYTES_PRINTED:
                    wprintf(L"JOB_NOTIFY_FIELD_BYTES_PRINTED: %d\n", InfoData.NotifyData.adwData[0]);
                    break;
    
                default:
                    break;
                }
    
    
            } else if (InfoData.Type == PRINTER_NOTIFY_TYPE) {
                puts("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
                puts("PRINTER_NOTIFY_TYPE");
            
                switch (InfoData.Field) {
                    
                case PRINTER_NOTIFY_FIELD_SERVER_NAME:
                    wprintf(L"PRINTER_NOTIFY_FIELD_SERVER_NAME\n");
                    break;
    
                case PRINTER_NOTIFY_FIELD_PRINTER_NAME:
                    wprintf(L"PRINTER_NOTIFY_FIELD_PRINTER_NAME: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case PRINTER_NOTIFY_FIELD_SHARE_NAME:
                    wprintf(L"PRINTER_NOTIFY_FIELD_SHARE_NAME: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case PRINTER_NOTIFY_FIELD_PORT_NAME:
                    wprintf(L"PRINTER_NOTIFY_FIELD_PORT_NAME: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case PRINTER_NOTIFY_FIELD_DRIVER_NAME:
                    wprintf(L"PRINTER_NOTIFY_FIELD_DRIVER_NAME: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case PRINTER_NOTIFY_FIELD_COMMENT:
                    wprintf(L"PRINTER_NOTIFY_FIELD_COMMENT: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case PRINTER_NOTIFY_FIELD_LOCATION:
                    wprintf(L"PRINTER_NOTIFY_FIELD_LOCATION: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case PRINTER_NOTIFY_FIELD_DEVMODE:
                    wprintf(L"PRINTER_NOTIFY_FIELD_DEVMODE\n");
                    break;
    
                case PRINTER_NOTIFY_FIELD_SEPFILE:
                    wprintf(L"PRINTER_NOTIFY_FIELD_SEPFILE: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR:
                    wprintf(L"PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case PRINTER_NOTIFY_FIELD_PARAMETERS:
                    wprintf(L"PRINTER_NOTIFY_FIELD_PARAMETERS: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case PRINTER_NOTIFY_FIELD_DATATYPE:
                    wprintf(L"PRINTER_NOTIFY_FIELD_DATATYPE: %s\n", InfoData.NotifyData.Data.pBuf);
                    break;
    
                case PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR:
                    wprintf(L"PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR: \n");
                    break;
    
                case PRINTER_NOTIFY_FIELD_ATTRIBUTES:
                    switch (InfoData.NotifyData.adwData[0]) {
                    case PRINTER_ATTRIBUTE_QUEUED:
                        wprintf(L"PRINTER_NOTIFY_FIELD_ATTRIBUTES: PRINTER_ATTRIBUTE_QUEUED");
                        break;
                    case PRINTER_ATTRIBUTE_DIRECT:
                        wprintf(L"PRINTER_NOTIFY_FIELD_ATTRIBUTES: PRINTER_ATTRIBUTE_DIRECT");
                        break;
                    case PRINTER_ATTRIBUTE_DEFAULT:
                        wprintf(L"PRINTER_NOTIFY_FIELD_ATTRIBUTES: PRINTER_ATTRIBUTE_DEFAULT");
                        break;
                    case PRINTER_ATTRIBUTE_SHARED:
                        wprintf(L"PRINTER_NOTIFY_FIELD_ATTRIBUTES: PRINTER_ATTRIBUTE_SHARED");
                        break;
                    default:
                        wprintf(L"PRINTER_NOTIFY_FIELD_ATTRIBUTES: ");
                        break;
                    }
                    break;
    
                case PRINTER_NOTIFY_FIELD_PRIORITY:
                    wprintf(L"PRINTER_NOTIFY_FIELD_PRIORITY: %d\n", InfoData.NotifyData.adwData[0]);
                    break;
    
                case PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY:
                    wprintf(L"PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY: %d\n", InfoData.NotifyData.adwData[0]);
                    break;
    
                case PRINTER_NOTIFY_FIELD_START_TIME:
                    wprintf(L"PRINTER_NOTIFY_FIELD_START_TIME: %d\n", InfoData.NotifyData.adwData[0]);
                    break;
    
                case PRINTER_NOTIFY_FIELD_UNTIL_TIME:
                    wprintf(L"PRINTER_NOTIFY_FIELD_UNTIL_TIME: %d\n", InfoData.NotifyData.adwData[0]);
                    break;
    
                case PRINTER_NOTIFY_FIELD_STATUS:
                    wprintf(L"PRINTER_NOTIFY_FIELD_STATUS: %s\n", 
                        ((PRINTER_INFO_2*)InfoData.NotifyData.adwData[0])->pPrinterName);
                    break;
    
                case PRINTER_NOTIFY_FIELD_STATUS_STRING://Not Supported
                    wprintf(L"PRINTER_NOTIFY_FIELD_STATUS_STRING\n");
                    break;
    
                case PRINTER_NOTIFY_FIELD_CJOBS:
                    wprintf(L"PRINTER_NOTIFY_FIELD_CJOBS: %d\n", InfoData.NotifyData.adwData[0]);
                    break;
    
                case PRINTER_NOTIFY_FIELD_AVERAGE_PPM:
                    wprintf(L"PRINTER_NOTIFY_FIELD_AVERAGE_PPM: %");
                    break;
    
                case PRINTER_NOTIFY_FIELD_TOTAL_PAGES://Not Supported
                    wprintf(L"PRINTER_NOTIFY_FIELD_TOTAL_PAGES: \n");
                    break;
    
                case PRINTER_NOTIFY_FIELD_PAGES_PRINTED://Not Supported
                    wprintf(L"PRINTER_NOTIFY_FIELD_PAGES_PRINTED: \n");
                    break;
    
                case PRINTER_NOTIFY_FIELD_TOTAL_BYTES://Not Supported
                    wprintf(L"PRINTER_NOTIFY_FIELD_TOTAL_BYTES: \n");
                    break;
    
                case PRINTER_NOTIFY_FIELD_BYTES_PRINTED://Not Supported
                    wprintf(L"PRINTER_NOTIFY_FIELD_BYTES_PRINTED: \n");
                    break;
    
                case PRINTER_NOTIFY_FIELD_OBJECT_GUID://Not Supported
                    wprintf(L"PRINTER_NOTIFY_FIELD_OBJECT_GUID: \n");
                    break;
    
                case PRINTER_NOTIFY_FIELD_FRIENDLY_NAME://Not Supported
                    puts("PRINTER_NOTIFY_FIELD_FRIENDLY_NAME: \n");
                    break;
    
                default:
                    puts("Unknown");
                }
            }
        }
    }
    
    
    int main()
    {
        HANDLE hPrinter;
        PRINTER_NOTIFY_OPTIONS Options;
        PRINTER_NOTIFY_OPTIONS_TYPE  OptionsTypes[2];
        PPRINTER_NOTIFY_INFO pNotifyInfo;
        DWORD dwChange;
        HANDLE hChange;
        
        WORD JobNotifyFields[] = {
            JOB_NOTIFY_FIELD_PRINTER_NAME, 
            JOB_NOTIFY_FIELD_MACHINE_NAME,
            JOB_NOTIFY_FIELD_PORT_NAME, 
            JOB_NOTIFY_FIELD_USER_NAME,
            JOB_NOTIFY_FIELD_NOTIFY_NAME, 
            JOB_NOTIFY_FIELD_DATATYPE,
            JOB_NOTIFY_FIELD_PRINT_PROCESSOR, 
            JOB_NOTIFY_FIELD_PARAMETERS,
            JOB_NOTIFY_FIELD_DRIVER_NAME, 
            JOB_NOTIFY_FIELD_DEVMODE,
            JOB_NOTIFY_FIELD_STATUS, 
            JOB_NOTIFY_FIELD_STATUS_STRING,
            JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR, 
            JOB_NOTIFY_FIELD_DOCUMENT,
            JOB_NOTIFY_FIELD_PRIORITY, 
            JOB_NOTIFY_FIELD_POSITION,
            JOB_NOTIFY_FIELD_SUBMITTED, 
            JOB_NOTIFY_FIELD_START_TIME,
            JOB_NOTIFY_FIELD_UNTIL_TIME, 
            JOB_NOTIFY_FIELD_TIME,
            JOB_NOTIFY_FIELD_TOTAL_PAGES, 
            JOB_NOTIFY_FIELD_PAGES_PRINTED,
            JOB_NOTIFY_FIELD_TOTAL_BYTES, 
            JOB_NOTIFY_FIELD_BYTES_PRINTED,
        };
    
        WORD PrinterNotifyFields[] = {
            PRINTER_NOTIFY_FIELD_SERVER_NAME, 
            PRINTER_NOTIFY_FIELD_PRINTER_NAME,
            PRINTER_NOTIFY_FIELD_SHARE_NAME, 
            PRINTER_NOTIFY_FIELD_PORT_NAME,
            PRINTER_NOTIFY_FIELD_DRIVER_NAME, 
            PRINTER_NOTIFY_FIELD_COMMENT,
            PRINTER_NOTIFY_FIELD_LOCATION, 
            PRINTER_NOTIFY_FIELD_DEVMODE,
            PRINTER_NOTIFY_FIELD_SEPFILE, 
            PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR,
            PRINTER_NOTIFY_FIELD_PARAMETERS, 
            PRINTER_NOTIFY_FIELD_DATATYPE,
            PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, 
            PRINTER_NOTIFY_FIELD_ATTRIBUTES,
            PRINTER_ATTRIBUTE_QUEUED, 
            PRINTER_ATTRIBUTE_DIRECT,
            PRINTER_ATTRIBUTE_DEFAULT, 
            PRINTER_ATTRIBUTE_SHARED,
            PRINTER_NOTIFY_FIELD_PRIORITY, 
            PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY,
            PRINTER_NOTIFY_FIELD_START_TIME, 
            PRINTER_NOTIFY_FIELD_UNTIL_TIME,
            PRINTER_NOTIFY_FIELD_STATUS, 
            PRINTER_NOTIFY_FIELD_STATUS_STRING,
            PRINTER_NOTIFY_FIELD_CJOBS, 
            PRINTER_NOTIFY_FIELD_AVERAGE_PPM,
            PRINTER_NOTIFY_FIELD_TOTAL_PAGES, 
            PRINTER_NOTIFY_FIELD_PAGES_PRINTED,
            PRINTER_NOTIFY_FIELD_TOTAL_BYTES, 
            PRINTER_NOTIFY_FIELD_BYTES_PRINTED,
            PRINTER_NOTIFY_FIELD_OBJECT_GUID, 
            PRINTER_NOTIFY_FIELD_FRIENDLY_NAME,
        };
    
        setlocale(LC_ALL, setlocale(LC_CTYPE, ""));
    
        if (OpenPrinter(L"Microsoft XPS Document Writer", &hPrinter, NULL) == FALSE) {
            printf("OpenPrinter failed");
            return 1;
        }
    
        OptionsTypes[0].Type = PRINTER_NOTIFY_TYPE;
        OptionsTypes[0].Count = sizeof(PrinterNotifyFields)/sizeof(PrinterNotifyFields[0]);
        OptionsTypes[0].pFields = PrinterNotifyFields;
    
        OptionsTypes[1].Type = JOB_NOTIFY_TYPE;
        OptionsTypes[1].Count = sizeof(JobNotifyFields)/sizeof(JobNotifyFields[0]);
        OptionsTypes[1].pFields = JobNotifyFields;
        
        Options.Count = sizeof(OptionsTypes)/sizeof(OptionsTypes[0]);
        Options.Version = 2;
        Options.Flags = 0;//Ignored in FindFirstPrinterChangeNotification
        Options.pTypes = OptionsTypes;
    
        hChange = FindFirstPrinterChangeNotification(hPrinter, PRINTER_CHANGE_ALL,  0, &Options);
        if (hChange == INVALID_HANDLE_VALUE) {
            printf("FindFirstPrinterChangeNotification failed.");
            return 1;
        }
    
        for (;;) {
        
            if (WaitForSingleObject(hChange, INFINITE) != WAIT_OBJECT_0) {
                puts("WaitForSingleObject failed.");
                break;
            }
         
            if (FindNextPrinterChangeNotification(hChange, &dwChange, NULL, (LPVOID*)&pNotifyInfo)) {
            
                puts("---------------------------------------------------------------------------");
                Options.Flags = PRINTER_NOTIFY_OPTIONS_REFRESH;
    
                if (dwChange & PRINTER_CHANGE_ADD_FORM) {
                    puts("サーバーにフォームが追加されました。\n");
                }
                if (dwChange & PRINTER_CHANGE_ADD_JOB) {
                    puts("プリンタに印刷ジョブが送信されました。");
                }
                if (dwChange & PRINTER_CHANGE_ADD_PORT) {
                    puts("サーバーにポートまたはモニタが追加されました。");
                }
                if (dwChange & PRINTER_CHANGE_ADD_PRINT_PROCESSOR) {
                    puts("サーバーにプリントプロセッサが追加されました。");
                }
                if (dwChange & PRINTER_CHANGE_ADD_PRINTER) {
                    puts("サーバーにプリンタが追加されました。");
                }
                if (dwChange & PRINTER_CHANGE_ADD_PRINTER_DRIVER) {
                    puts("サーバーにプリンタドライバが追加されました。");
                }
                if (dwChange & PRINTER_CHANGE_CONFIGURE_PORT) {
                    puts("サーバー上でポートが設定されました。");
                }
                if (dwChange & PRINTER_CHANGE_DELETE_FORM) {
                    puts("サーバーからフォームが削除されました。");
                }
                if (dwChange & PRINTER_CHANGE_DELETE_JOB) {
                    puts("ジョブが削除されました。");
                }
                if (dwChange & PRINTER_CHANGE_DELETE_PORT) {
                    puts("サーバーからポートまたはモニタが削除されました。");
                }
                if (dwChange & PRINTER_CHANGE_DELETE_PRINT_PROCESSOR) {
                    puts("サーバーからプリントプロセッサが削除されました。");
                }
                if (dwChange & PRINTER_CHANGE_DELETE_PRINTER) {
                    puts("プリンタが削除されました。");
                }
                if (dwChange & PRINTER_CHANGE_DELETE_PRINTER_DRIVER) {
                    puts("サーバーからプリンタドライバが削除されました。");
                }
                if (dwChange & PRINTER_CHANGE_FAILED_CONNECTION_PRINTER) {
                    puts("プリンタへの接続に失敗しました。");
                }
                if (dwChange & PRINTER_CHANGE_SET_FORM) {
                    puts("サーバ上でフォームが設定されました。");
                }
                if (dwChange & PRINTER_CHANGE_SET_JOB) {
                    puts("ジョブが設定されました。");
                }
                if (dwChange & PRINTER_CHANGE_SET_PRINTER) {
                    puts("プリンタが設定されました。");
                }
                if (dwChange & PRINTER_CHANGE_SET_PRINTER_DRIVER) {
                    puts("プリンタドライバが設定されました。");
                }
                if (dwChange & PRINTER_CHANGE_WRITE_JOB) {
                    puts("ジョブデータが書き込まれました。");
                }
    
                putchar('\n');
    
                PrintPrinterNotifyInfoData(pNotifyInfo);
            }
        }
    
        FindClosePrinterChangeNotification(hChange);
        ClosePrinter(hPrinter);
    
        puts("exit.");
    
        return 0;
    }





  • 実行結果
  • ---------------------------------------------------------------------------
    プリンタに印刷ジョブが送信されました。
    プリンタが設定されました。
    
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    PRINTER_NOTIFY_TYPE
    PRINTER_NOTIFY_FIELD_CJOBS: 1
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_PRINTER_NAME: Microsoft XPS Document Writer
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_MACHINE_NAME: \\MachineName
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_PORT_NAME:
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_USER_NAME: UserName
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_NOTIFY_NAME: UserName
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_DATATYPE: RAW
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_PRINT_PROCESSOR: winprint
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_PARAMETERS:
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_DRIVER_NAME: Microsoft XPS Document Writer
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_DEVMODE: Microsoft XPS Document Writer
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_STATUS: Job is spooling.
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_STATUS_STRING:
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR:
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_DOCUMENT: ローカル ダウンレベル ドキュメント
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_PRIORITY: 1
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_POSITION: 1
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_SUBMITTED: 2012/02/25 02:25:38
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_START_TIME: 0
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_UNTIL_TIME: 0
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_TIME: 0
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_TOTAL_PAGES: 0
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_PAGES_PRINTED: 0
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_TOTAL_BYTES: 0
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_BYTES_PRINTED: 0
    ---------------------------------------------------------------------------
    ジョブが設定されました。
    
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_DOCUMENT: 印刷 - やる気が沸いてくる気がするエナジードリンクのボ
    トルデザインいろいろ - GIGAZINE
    ---------------------------------------------------------------------------
    ジョブが設定されました。
    
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_STATUS:
    ---------------------------------------------------------------------------
    ジョブが削除されました。
    ジョブが設定されました。
    プリンタが設定されました。
    
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_STATUS:
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_PORT_NAME:
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_STATUS: Job is printing.
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_STATUS:
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_STATUS_STRING:
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_STATUS:
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_STATUS:
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_STATUS:
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_STATUS:
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_PAGES_PRINTED: 12
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_BYTES_PRINTED: 0
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    PRINTER_NOTIFY_TYPE
    PRINTER_NOTIFY_FIELD_CJOBS: 0
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    JOB_NOTIFY_TYPE
    Job Identifier: 35
    JOB_NOTIFY_FIELD_STATUS:
    
    
    
    




    参考
    http://msdn.microsoft.com/ja-jp/library/cc428611.aspx FindFirstPrinterChangeNotification
    http://msdn.microsoft.com/ja-jp/library/cc428614.aspx FindNextPrinterChangeNotification
    http://msdn.microsoft.com/ja-jp/library/cc428609.aspx FindClosePrinterChangeNotification
    http://msdn.microsoft.com/ja-jp/library/dd162853.aspx PRINTER_NOTIFY_INFO structure
    http://msdn.microsoft.com/ja-jp/library/dd162854.aspx PRINTER_NOTIFY_INFO_DATA structure
    http://msdn.microsoft.com/ja-jp/library/dd162853.aspx PRINTER_NOTIFY_INFO structure
    http://msdn.microsoft.com/ja-jp/library/dd162845.aspx PRINTER_INFO_2 structure