Collecting Container Events

Start with the project you created in Using Container objects

1.

Add the following callback function before the OnOpen function definition:

L_VOID ConvertFloatToString (L_INT flt, L_TCHAR szBuff[], L_INT nPrecise) 
{
   L_INT   left, right; 
   TCHAR   lChar[10] = TEXT("\0");
   TCHAR   rChar[10] = TEXT("\0");
   L_INT   nPercentage; 

   nPercentage = (L_INT)pow((L_DOUBLE) 10, (L_DOUBLE) nPrecise); 

   left  = flt / nPercentage; 
   if (left) 
      right = abs(flt % (left * nPercentage)); 
   else
      right = abs(flt); 

   wsprintf(lChar, TEXT("%d"), left); 
   
   if (right > 9) 
      wsprintf(rChar, TEXT("%d"), right); 
   else
      wsprintf(rChar, TEXT("0%d"), right); 

   wsprintf(szBuff, TEXT("%s.%s"), lChar, rChar); 
}

L_INT EXT_CALLBACK LeadContainerProc 
 (
   pCONTAINERHANDLE pContainer, 
   CONTAINEREVENTTYPE nEventType, 
   L_VOID *pEventData, 
   L_VOID *pUserData 

{
   pCONTAINEROBJECTDATA pContainerObjectData = ( pCONTAINEROBJECTDATA ) pEventData ; 
   L_TCHAR pszState [ 80 ] ; 
   L_TCHAR buffer [ 500 ] ; 
   HWND   hwndOwner ; 
   L_TCHAR xP1[10]; memset(xP1, 0, 10); 
   L_TCHAR yP1[10]; memset(yP1, 0, 10); 
   L_TCHAR xP2[10]; memset(xP2, 0, 10); 
   L_TCHAR yP2[10]; memset(yP2, 0, 10); 
   L_TCHAR xP3[10]; memset(xP3, 0, 10); 
   L_TCHAR yP3[10]; memset(yP3, 0, 10); 
   L_TCHAR xP4[10]; memset(xP4, 0, 10); 
   L_TCHAR yP4[10]; memset(yP4, 0, 10); 


   switch ( pContainerObjectData->fState ) 
   {
      case CONTAINER_STATE_BEGIN: 
         lstrcpy ( pszState, TEXT("Begin, ") ) ; 
         break ; 

      case CONTAINER_STATE_PROCESS: 
         lstrcpy ( pszState, TEXT("Process, ") ) ; 
         break ; 

      case CONTAINER_STATE_END: 
         lstrcpy ( pszState, TEXT("End, ") ) ; 
         break ; 

      case CONTAINER_STATE_ABORT: 
         lstrcpy ( pszState, TEXT("Abort, ") ) ; 
         break ; 
   }     

   switch ( nEventType ) 
   {
      case CONTAINER_EVENT_TYPE_DRAW: 
         {
            switch ( pContainerObjectData->nObjectType ) 
            {
               // process the point object events 
               case CONTAINER_OBJECT_TYPE_POINT: 
                  {  
                     CONTAINERPOINTDATA PointData ; 

                     PointData = * ( ( pCONTAINERPOINTDATA ) ( pContainerObjectData->pObjectData ) ) ; 

                     ConvertFloatToString((L_INT) (PointData.vptPoint.x * 1000), xP1, 3); 
                     ConvertFloatToString((L_INT) (PointData.vptPoint.y * 1000), yP1, 3); 

                     wsprintf ( buffer, 
                               TEXT("%s %s (%s, %s)"), 
                               TEXT("Point: "),
                               pszState, 
                               xP1, 
                               yP1 ) ; 
                  }
                  
                  break ; 

               // process the line object events 
               case CONTAINER_OBJECT_TYPE_LINE: 
                  {  
                     CONTAINERLINEDATA LineData ; 

                     LineData = * ( ( pCONTAINERLINEDATA ) ( pContainerObjectData->pObjectData ) ) ; 

                     ConvertFloatToString((L_INT) (LineData.vptLine[0].x * 1000), xP1, 3); 
                     ConvertFloatToString((L_INT) (LineData.vptLine[0].y * 1000), yP1, 3); 
                     ConvertFloatToString((L_INT) (LineData.vptLine[1].x * 1000), xP2, 3); 
                     ConvertFloatToString((L_INT) (LineData.vptLine[1].y * 1000), yP2, 3); 

                     wsprintf ( buffer, 
                               TEXT("%s %s (%s, %s) (%s, %s)"), 
                               TEXT("Line: "),
                               pszState, 
                               xP1, 
                               yP1, 
                               xP2, 
                               yP2 ) ; 
                  } 

                  break ; 

               // process the square object events 
               case CONTAINER_OBJECT_TYPE_SQUARE: 
                  {  
                     CONTAINERSQUAREDATA SquareData ; 

                     SquareData = * ( ( pCONTAINERSQUAREDATA ) ( pContainerObjectData->pObjectData ) ) ; 

                     ConvertFloatToString((L_INT) (SquareData.vptSquare[0].x * 1000), xP1, 3); 
                     ConvertFloatToString((L_INT) (SquareData.vptSquare[0].y * 1000), yP1, 3); 
                     ConvertFloatToString((L_INT) (SquareData.vptSquare[1].x * 1000), xP2, 3); 
                     ConvertFloatToString((L_INT) (SquareData.vptSquare[1].y * 1000), yP2, 3); 

                     wsprintf ( buffer, 
                               TEXT("%s %s (%s, %s) (%s, %s)"), 
                               TEXT("Square: "),
                               pszState, 
                               xP1, 
                               yP1, 
                               xP2, 
                               yP2 ) ; 
                  } 

                  break ; 

               // process the rectangle object events 
               case CONTAINER_OBJECT_TYPE_RECT: 
                  {  
                     CONTAINERRECTDATA RectData ; 

                     RectData = * ( ( pCONTAINERRECTDATA ) ( pContainerObjectData->pObjectData ) ) ; 

                     ConvertFloatToString((L_INT) (RectData.vptRect[0].x * 1000), xP1, 3); 
                     ConvertFloatToString((L_INT) (RectData.vptRect[0].y * 1000), yP1, 3); 
                     ConvertFloatToString((L_INT) (RectData.vptRect[1].x * 1000), xP2, 3); 
                     ConvertFloatToString((L_INT) (RectData.vptRect[1].y * 1000), yP2, 3); 

                     wsprintf ( buffer, 
                               TEXT("%s %s (%s, %s) (%s, %s)"), 
                               TEXT("Rect: "),
                               pszState, 
                               xP1, 
                               yP1, 
                               xP2, 
                               yP2 ) ; 
                  } 

                  break ; 

               // process the circle object events 
               case CONTAINER_OBJECT_TYPE_CIRCLE: 
                  {  
                     CONTAINERCIRCLEDATA CircleData ; 

                     CircleData = * ( ( pCONTAINERCIRCLEDATA ) ( pContainerObjectData->pObjectData ) ) ; 

                     ConvertFloatToString((L_INT) (CircleData.vptCircle[0].x * 1000), xP1, 3); 
                     ConvertFloatToString((L_INT) (CircleData.vptCircle[0].y * 1000), yP1, 3); 
                     ConvertFloatToString((L_INT) (CircleData.vptCircle[1].x * 1000), xP2, 3); 
                     ConvertFloatToString((L_INT) (CircleData.vptCircle[1].y * 1000), yP2, 3); 

                     wsprintf ( buffer, 
                               TEXT("%s %s (%s, %s) (%s, %s)"), 
                               TEXT("Circle: "),
                               pszState, 
                               xP1, 
                               yP1, 
                               xP2, 
                               yP2 ) ; 
                  } 

                  break ; 

               // process the ellipse object events 
               case CONTAINER_OBJECT_TYPE_ELLIPSE: 
                  {
                     CONTAINERELLIPSEDATA EllipseData ; 

                     EllipseData = * ( ( pCONTAINERELLIPSEDATA ) ( pContainerObjectData->pObjectData ) ) ; 

                     ConvertFloatToString((L_INT) (EllipseData.vptEllipse[0].x * 1000), xP1, 3); 
                     ConvertFloatToString((L_INT) (EllipseData.vptEllipse[0].y * 1000), yP1, 3); 
                     ConvertFloatToString((L_INT) (EllipseData.vptEllipse[1].x * 1000), xP2, 3); 
                     ConvertFloatToString((L_INT) (EllipseData.vptEllipse[1].y * 1000), yP2, 3); 

                     wsprintf ( buffer, 
                               TEXT("%s %s (%s, %s) (%s, %s)"), 
                               TEXT("Ellipse: "),
                               pszState, 
                               xP1, 
                               yP1, 
                               xP2, 
                               yP2 ) ; 
                  } 

                  break ; 

               // process the polyline object events 
               case CONTAINER_OBJECT_TYPE_POLYLINE: 
                  {  
                     CONTAINERPOLYLINEDATA PolylineData ; 

                     PolylineData = * ( ( pCONTAINERPOLYLINEDATA ) ( pContainerObjectData->pObjectData ) ) ; 

                     wsprintf ( buffer, 
                               TEXT("%s %s %d"), 
                               TEXT("Polyline: "),
                               pszState, 
                               PolylineData.nPointCount ) ; 
                  } 

                  break ; 

               // process the bezier object events 
               case CONTAINER_OBJECT_TYPE_BEZIER: 
                  {  
                     CONTAINERBEZIERDATA BezierData ; 

                     BezierData = * ( ( pCONTAINERBEZIERDATA ) ( pContainerObjectData->pObjectData ) ) ; 

                     ConvertFloatToString((L_INT) (BezierData.vptBezier[0].x * 1000), xP1, 3); 
                     ConvertFloatToString((L_INT) (BezierData.vptBezier[0].y * 1000), yP1, 3); 
                     ConvertFloatToString((L_INT) (BezierData.vptBezier[1].x * 1000), xP2, 3); 
                     ConvertFloatToString((L_INT) (BezierData.vptBezier[1].y * 1000), yP2, 3); 
                     ConvertFloatToString((L_INT) (BezierData.vptBezier[2].x * 1000), xP3, 3); 
                     ConvertFloatToString((L_INT) (BezierData.vptBezier[2].y * 1000), yP3, 3); 
                     ConvertFloatToString((L_INT) (BezierData.vptBezier[3].x * 1000), xP4, 3); 
                     ConvertFloatToString((L_INT) (BezierData.vptBezier[3].y * 1000), yP4, 3); 

                     wsprintf ( buffer, 
                               TEXT("%s %s (%s, %s) (%s, %s) (%s, %s) (%s, %s)"), 
                               TEXT("Bezier: "),
                               pszState, 
                               xP1, 
                               yP1, 
                               xP2, 
                               yP2, 
                               xP3, 
                               yP3, 
                               xP4, 
                               yP4 ) ; 
                  } 
                  
                  break ; 

               // process the arc object events 
               case CONTAINER_OBJECT_TYPE_ARC: 
                  {  
                     CONTAINERARCDATA ArcData ; 

                     ArcData = * ( ( pCONTAINERARCDATA ) ( pContainerObjectData->pObjectData ) ) ; 

                     ConvertFloatToString((L_INT) (ArcData.vptCenter.x * 1000), xP1, 3); 
                     ConvertFloatToString((L_INT) (ArcData.vptCenter.y * 1000), yP1, 3); 
                     ConvertFloatToString((L_INT) (ArcData.Radius * 1000), xP2, 3); 
                     ConvertFloatToString((L_INT) (ArcData.StartAngle * 1000), yP2, 3); 
                     ConvertFloatToString((L_INT) (ArcData.SweepAngle * 1000), xP3, 3); 

                     wsprintf ( buffer, 
                               TEXT("%s %s (%s, %s) %s, %s, %s"), 
                               TEXT("Arc: "),
                               pszState, 
                               xP1, 
                               yP1, 
                               xP2, 
                               yP2, 
                               xP3 ) ; 
                  } 
                  
                  break ; 

                // process the text object events 
               case CONTAINER_OBJECT_TYPE_TEXT: 
                  {  
                     CONTAINERTEXTDATA TextData ; 

                     TextData = * ( ( pCONTAINERTEXTDATA ) ( pContainerObjectData->pObjectData ) ) ; 

                     wsprintf ( buffer, 
                              TEXT("%s %s %s (%d, %d) (%d, %d)"), 
                               TEXT("Text: "),
                               pszState, 
                               TextData.pszText, 
                               TextData.rcText.left, 
                               TextData.rcText.top, 
                               TextData.rcText.right, 
                               TextData.rcText.bottom ) ; 
                  } 
                  
                  break ; 
               }

               break ; 
         }
   }

   L_ContainerGetOwner ( pContainer, &hwndOwner ) ; 

   SetWindowText ( hwndOwner, buffer ) ; 

   return SUCCESS ; 
}

2.

Add the following function call to the WndProc function, just before the CheckMenuRadioItem function call in the WM_CREATE message:

L_ContainerSetCallback ( pContainer, LeadContainerProc, NULL ) ;

3.

Compile and run the project by selecting Build->Rebuild Solution from the menu, and then Debug->Start Without Debugging.