Using the Events OnStatus, OnPrinterReport, and OnPrintJobReport Example for C++ 6.0 and later

// We are going to make use of some ATL-specific code, so we
// need to include <atlbase.h> and <atlcom.h>. Furthermore, as
// <atlcom.h> is looking for an instance of CComModule named
// _Module, we need to create a dummy object.
#include <atlbase.h>
CComModule _Module;
#include <atlcom.h>

/* Creating the Sink Object */

// Type info for the OnStatus event handler function
_ATL_FUNC_INFO OnStatusInfo = { CC_STDCALL,
                                VT_EMPTY,
                                2,
                                { VT_I4, VT_I4 } };

// Type info for the OnPrinterReport event handler function
_ATL_FUNC_INFO OnPrinterReportInfo = { CC_STDCALL,
                                       VT_EMPTY,
                                       4,
                                       { VT_I2,
                                         VT_BSTR,
                                         VT_BSTR,
                                         VT_BSTR } };

// Type info for the OnPrintJobReport event handler function
_ATL_FUNC_INFO OnPrintJobReportInfo = { CC_STDCALL,
                                        VT_EMPTY,
                                        6,
                                        { VT_BSTR,
                                          VT_I2,
                                          VT_BSTR,
                                          VT_BSTR,
                                          VT_BSTR,
                                          VT_BSTR } };

// The class implementing the sink
class CPrintSCUSink :
   public IDispEventSimpleImpl<1, CPrintSCUSink,
                               &DIID__ILEADDicomPrintSCUEvents>
{
private:
   ILEADDicomPrintSCU* m_pPrintSCU;

public:
   CPrintSCUSink(ILEADDicomPrintSCU* pPrintSCU)
   {
      m_pPrintSCU = pPrintSCU;
      m_pPrintSCU->AddRef();

      // Attach to the source
      DispEventAdvise((IUnknown*) m_pPrintSCU);
   }

   virtual ~CPrintSCUSink()
   {
      m_pPrintSCU->Release();

      // Detach from the source
      DispEventUnadvise((IUnknown*) m_pPrintSCU);
   }

   // This function will be called when the OnStatus event is fired
   void __stdcall OnStatus(PrintScuStatusEnum Status,
                           long lOperationStatus)
   {
      ILEADDicomPrintSCUPtr spPrintSCU = m_pPrintSCU;
      char szMsg[32];
      LPCSTR pszStatusCodeType;

      switch (Status)
      {
      case PRNSCU_STATUS_RECEIVE_ABORT:
         wsprintf(szMsg, "Source = %hd, Reason = %hd",
                  spPrintSCU->AbortSource, spPrintSCU->AbortReason);
         MessageBox(NULL, szMsg, "Print SCP Aborted the Association", MB_OK);

         break;

      case PRNSCU_STATUS_RECEIVE_PRINT_FILM_SESSION_RSP:
         if (lOperationStatus == COMMAND_STATUS_SUCCESS)
         {
            if (spPrintSCU->LastOperationStatus == COMMAND_STATUS_SUCCESS)
            {
               pszStatusCodeType = "Success";
            }
            else
            {
               pszStatusCodeType = "Warning";
            }
         }
         else
         {
            pszStatusCodeType = "Failure";
         }

         wsprintf(szMsg, "Status: 0x%04X (%s)",
                  spPrintSCU->LastOperationStatus, pszStatusCodeType);
         MessageBox(NULL, szMsg, "Received N-ACTION-RSP (Basic Film Session SOP Class)", MB_OK);

         break;
      }
   }

   // This function will be called when the OnPrinterReport event is fired
   void __stdcall OnPrinterReport(short nEventTypeID,
                                  BSTR bstrPrinterStatusInfo,
                                  BSTR bstrFilmDestination,
                                  BSTR bstrPrinterName)
   {
      LPCSTR pszEventTypeName = "Normal";
      switch (nEventTypeID)
      {
      case 2:
         pszEventTypeName = "Warning";
         break;

      case 3:
         pszEventTypeName = "Failure";
         break;
      }

      char szMsg[256];

      wsprintf(szMsg, "Event Type Name: %s", pszEventTypeName);

      if (nEventTypeID != 1)
      {
         wsprintf(szMsg,
                  "%s\n"
                  "Printer Status Info: %s\n"
                  "Film Destination: %s\n"
                  "Printer Name: %s",
                  szMsg,
                  LPCSTR(_bstr_t(bstrPrinterStatusInfo)),
                  LPCSTR(_bstr_t(bstrFilmDestination)),
                  LPCSTR(_bstr_t(bstrPrinterName)));
      }

      MessageBox(NULL, szMsg, "Printer Status Report", MB_OK); 
   }

   // This function will be called when the OnPrintJobReport event is fired
   void __stdcall OnPrintJobReport(BSTR bstrPrintJobSOPInstanceUID,
                                   short nEventTypeID,
                                   BSTR bstrExecutionStatusInfo,
                                   BSTR bstrPrintJobID,
                                   BSTR bstrFilmSessionLabel,
                                   BSTR bstrPrinterName)
   {
      LPCSTR pszEventTypeName = "Pending";
      switch (nEventTypeID)
      {
      case 2:
         pszEventTypeName = "Printing";
         break;

      case 3:
         pszEventTypeName = "Done";
         break;

      case 4:
         pszEventTypeName = "Failure";
         break;
      }

      char szMsg[512];

      wsprintf(szMsg,
              "Print Job SOP Instance UID: %s\n"
              "Event Type Name: %s\n"
              "Execution Status Info: %s\n"
              "Film Session Label: %s\n"
              "Printer Name: %s\n",
              LPCSTR(_bstr_t(bstrPrintJobSOPInstanceUID)),
              pszEventTypeName,
              LPCSTR(_bstr_t(bstrExecutionStatusInfo)),
              LPCSTR(_bstr_t(bstrFilmSessionLabel)),
              LPCSTR(_bstr_t(bstrPrinterName)));

      MessageBox(NULL, szMsg, "Print Job Status Report", MB_OK);
   }

   // IDispEventSimpleImpl<> needs a sink map
   // Note: The DISPIDs of the events OnStatusOnPrinterReport, and
   // OnPrintJobReport are 1, 2, and 3, respectively
   BEGIN_SINK_MAP(CPrintSCUSink)
      SINK_ENTRY_INFO(1, DIID__ILEADDicomPrintSCUEvents,
                      1, OnStatus, &OnStatusInfo)
      SINK_ENTRY_INFO(1, DIID__ILEADDicomPrintSCUEvents,
                      2, OnPrinterReport, &OnPrinterReportInfo)
      SINK_ENTRY_INFO(1, DIID__ILEADDicomPrintSCUEvents,
                      3, OnPrintJobReport, &OnPrintJobReportInfo)
   END_SINK_MAP()
};