Converting LEAD Annotation Objects to DICOM Annotation Objects example for C++ 5.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 OnConvertLEADAnnObjToDicomAnnObj event handler function
_ATL_FUNC_INFO OnConvertLEADAnnObjToDicomAnnObjInfo = { CC_STDCALL,
                                                        VT_EMPTY,
                                                        1,
                                                        { VT_BOOL } };

// The class implementing the sink
class CDicomDSSink :
   public IDispEventSimpleImpl<1, CDicomDSSink,
                               &DIID__LEADDicomDSEvents>
{
private:
   ILEADDicomDS* m_pDicomDS;

public:
   CDicomDSSink(ILEADDicomDS* pDicomDS)
   {
      m_pDicomDS = pDicomDS;
      m_pDicomDS->AddRef();

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

   virtual ~CDicomDSSink()
   {
      m_pDicomDS->Release();

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

   // This function will be called when the OnConvertLEADAnnObjToDicomAnnObj event is fired
   void __stdcall OnConvertLEADAnnObjToDicomAnnObj(VARIANT_BOOL bGraphicObject)
   {
      char szMsg[512];

      // Display the attributes of the resulted DICOM annotation object
      if (bGraphicObject) // The resulted DICOM annotation object is a graphic object
      {
         IDicomGraphicObjectAttributesPtr spGraphicObjAttribs;
         spGraphicObjAttribs = m_pDicomDS->GraphicObjectAttributes;

         lstrcpy(szMsg, "Graphic Annotation Units: ");
         switch (spGraphicObjAttribs->GetUnits())
         {
         case DICOM_UNIT_PIXEL:
            lstrcat(szMsg, "PIXEL\n");
               break;
      
         case DICOM_UNIT_DISPLAY:
            lstrcat(szMsg, "DISPLAY\n");
            break;
         }

         lstrcat(szMsg, "Graphic Type: ");
         switch (spGraphicObjAttribs->GetType())
         {
         case DICOM_GRAPHIC_OBJECT_TYPE_POINT:
            lstrcat(szMsg, "POINT\n");
            break;

         case DICOM_GRAPHIC_OBJECT_TYPE_POLYLINE:
            lstrcat(szMsg, "POLYLINE\n");
            break;

         case DICOM_GRAPHIC_OBJECT_TYPE_INTERPOLATED:
            lstrcat(szMsg, "INTERPOLATED\n");
            break;

         case DICOM_GRAPHIC_OBJECT_TYPE_CIRCLE:
            lstrcat(szMsg, "CIRCLE\n");
            break;

         case DICOM_GRAPHIC_OBJECT_TYPE_ELLIPSE:
            lstrcat(szMsg, "ELLIPSE\n");
            break;
         }

         if (spGraphicObjAttribs->Filled)
         {
            lstrcat(szMsg, "Graphic Filled: Y\n");
         }
         else
         {
            lstrcat(szMsg, "Graphic Filled: N\n");
         }
      
         long lCount = spGraphicObjAttribs->PointCount;
         wsprintf(szMsg, "%sNumber of Graphic Points: %li\n", szMsg, lCount);
      
         if (lCount < 10)
         {
            lstrcat(szMsg, "Graphic Data: \n");
            for (long i = 0; i < lCount; i++)
            {
               sprintf(szMsg, "%s   X%i, Y%i = %.2f, %.2f\n", szMsg,
                       i + 1, i + 1,
                       spGraphicObjAttribs->PointsX [i],
                       spGraphicObjAttribs->PointsY [i]);
            }
         }

         MessageBox(NULL, szMsg, "Graphic Annotation Object", MB_OK);
      }
      else // The resulted DICOM annotation object is a text object
      {
         IDicomTextObjectAttributesPtr spTextObjAttribs;
         spTextObjAttribs = m_pDicomDS->TextObjectAttributes;

         if (spTextObjAttribs->BoundingBoxUsed)
         {
            wsprintf(szMsg, "Unformatted Text Value: %s\n",
                     spTextObjAttribs->TextValue.operator char *());

            lstrcat(szMsg, "Bounding Box Annotation Units: ");
            switch(spTextObjAttribs->GetBoundingBoxUnits ())
            {
            case DICOM_UNIT_PIXEL:
               lstrcat(szMsg, "PIXEL\n");
               break;

            case DICOM_UNIT_DISPLAY:
               lstrcat(szMsg, "DISPLAY\n");
               break;
            }

            sprintf(szMsg, "%sBounding Box Top Left Hand Corner: %.2f, %.2f\n",
                    szMsg,
                    spTextObjAttribs->BoundingBoxTLHCornerX,
                    spTextObjAttribs->BoundingBoxTLHCornerY);
            
            sprintf(szMsg, "%sBounding Box Bottom Right Hand Corner: %.2f, %.2f\n",
                    szMsg,
                    spTextObjAttribs->BoundingBoxBRHCornerX,
                    spTextObjAttribs->BoundingBoxBRHCornerY);

            lstrcat(szMsg, "Bounding Box Text Horizontal Justification: ");
            switch (spTextObjAttribs->GetBoundingBoxTextJustification ())
            {
            case DICOM_TEXT_JUSTIFICATION_LEFT:
               lstrcat(szMsg, "LEFT\n");
               break;

            case DICOM_TEXT_JUSTIFICATION_RIGHT:
               lstrcat(szMsg, "RIGHT\n");
               break;

            case DICOM_TEXT_JUSTIFICATION_CENTER:
               lstrcat(szMsg, "CENTER\n");
               break;
            }
         }
         else
         {
            wsprintf(szMsg, "Unformatted Text Value: %s\n",
                     spTextObjAttribs->TextValue.operator char *());
            
            lstrcat(szMsg, "Anchor Point Annotation Units: ");
            switch (spTextObjAttribs->GetAnchorPointUnits ())
            {
            case DICOM_UNIT_PIXEL:
               lstrcat(szMsg, "PIXEL\n");
               break;

            case DICOM_UNIT_DISPLAY:
               lstrcat(szMsg, "DISPLAY\n");
               break;
            }

            sprintf(szMsg, "%sAnchor Point: %.2f, %.2f\n",
                    szMsg,
                    spTextObjAttribs->AnchorPointX,
                    spTextObjAttribs->AnchorPointY);
            
            if (spTextObjAttribs->AnchorPointVisible)
            {
               lstrcat(szMsg, "Anchor Point Visibility: Y");
            }
            else
            {
               lstrcat(szMsg, "Anchor Point Visibility: N");
            }
         }

         MessageBox(NULL, szMsg, "Text Annotation Object", MB_OK);
      }

      // If it is desired to stop the conversion process...
      //m_pDicomDS->EndConversion(DICOM_ERROR_ANN); // Any error code, but not 0
   }

   // IDispEventSimpleImpl<> needs a sink map
   // Note: The DISPID of the event OnConvertLEADAnnObjToDicomAnnObj is 3
   BEGIN_SINK_MAP(CDicomDSSink)
      SINK_ENTRY_INFO(1, DIID__LEADDicomDSEvents,
                      3, OnConvertLEADAnnObjToDicomAnnObj,
                      &OnConvertLEADAnnObjToDicomAnnObjInfo)
   END_SINK_MAP()
};

void LEADAnnToDicomAnn(ILEADDicomDSPtr& spPresStateDS)
{
   // The sink
   CDicomDSSink DicomDSSink(spPresStateDS);

   // Update the CurrentElement property with a Graphic Annotation Item so
   // that the resulted DICOM annotation objects are added to the Data Set
   if (spPresStateDS->FindFirstGraphicAnnItem () != 0)
   {
      // (Make sure that the specified layer is already defined in the
      // "Graphic Layer Module")
      spPresStateDS->CreateGraphicAnnItem (0, "LAYER_0");
      spPresStateDS->FindFirstGraphicAnnItem ();
   }

   ILEADRasterAnnotationPtr spRasterAnn(__uuidof(LEADRasterAnnotation));
   
   // Let's create a LEAD rectangle annotation object
   spRasterAnn->AnnCreate(ANN_OBJECT_RECT, VARIANT_FALSE, VARIANT_FALSE);
   long hAnnObject = spRasterAnn->AnnObject;
   spRasterAnn->AnnRectLeft[hAnnObject] = 150;
   spRasterAnn->AnnRectTop[hAnnObject] = 175;
   spRasterAnn->AnnRectWidth[hAnnObject] = 200;
   spRasterAnn->AnnRectHeight[hAnnObject] = 100;
   spRasterAnn->AnnSetFillMode(hAnnObject, ANN_FILLMODE_TRANSPARENT, VARIANT_FALSE);
   
   // Convert the LEAD annotation object. Now, for each resulted DICOM annotation
   // object, the OnConvertLEADAnnObjToDicomAnnObj event gets fired. By handling
   // the event, you can inspect the resulted object.
   if (spPresStateDS->ConvertLEADAnnObjToDicomAnnObjs(hAnnObject, 0) == DICOM_SUCCESS)
   {
      MessageBox(NULL, "The LEAD annotation object was converted successfully.",
                 "Converting a LEAD Annotation Object", MB_OK);
   }
   
   // Destroy the LEAD annotation object
   spRasterAnn->AnnDestroy(hAnnObject, 0);
}