WM_LTANNEVENT Message (Document/Medical only)

When received, the WM_LTANNEVENT message indicates that an annotation event has occurred. The message parameters contain the following information:

image\sqrblit.gif wParam contains one of the following constants:

LTANNEVENT_ACTIVATE

[3] Indicates that an activation event was triggered by the L_AnnSetActiveState function. Only the automation, audio clip, button, and hot spot objects generate activation events.

LTANNEVENT_DEACTIVATE

[4] Indicates that a dectivation event was triggered by the L_AnnSetActiveState function. Only the automation, audio clip, button, and hot spot objects generate activation events.

LTANNEVENT_AUTOCLICKED

[9] Indicates that the user has clicked a button or hot spot object in run mode using the automated features.

LTANNEVENT_AUTOACTION

This event gets fired once for each automation action, even if the change is applied to multiple objects. For example,
1. Selecting all objects fires this event once.
2. Changing the foreground color of all objects fires this event again.

LTANNEVENT_TOOLCREATE

[1] Indicates that the annotation toolbar, used for automation, has been created.

LTANNEVENT_TOOLDESTROY

[2] Indicates that the annotation toolbar, used for automation, has been destroyed.

LTANNEVENT_TOOLCHECKED

[0] Indicates that the user has selected a different tool on the toolbar.

LTANNEVENT_INSERT

[5] Indicates that an annotation object has been inserted into a container. The L_AnnInsert function generates this message, but it does so only if the specified container has a window handle. (This is not an issue in automation mode.)

LTANNEVENT_REMOVE

[6] Indicates that an annotation object is being removed from a container. You can use this message in automation mode to detect the deletion of an object, because objects are removed from the container before they are deleted.

LTANNEVENT_AUTOBEGINSET

[7] Indicates that the user has begun drawing an object. This event occurs before the first call to the L_AnnDefine function.

LTANNEVENT_AUTOENDSET

[8] Indicates that the user has finished drawing an object. This event occurs after the last call to the L_AnnDefine function.

LTANNEVENT_AUTOCHANGED

[10] Occurs when the coordinates of an annotation object changes in automation mode.

LTANNEVENT_AUTOITEMCHANGED

[11] Occurs when any property of an annotation object changes in automation mode.

LTANNEVENT_AUTOSELECT

[12] Occurs when the Selected property of an annotation object changes in automation mode.

LTANNEVENT_LOCKED

[13] Indicates the object has been locked.

LTANNEVENT_UNLOCKED

[14] Indicates the object has been unlocked.

LTANNEVENT_HYPERLINK

[15] Indicates that an object with a hyperlink of type ANNLINK_LTANNEVENT has been clicked. THis is in run mode only.

LTANNEVENT_HYPERLINKMENU

[16] Indicates the Hyperlink menu item has been activated for an object or a group of objects. (design mode only) In this case, if there are selected objects, then the hyperlink is meant to be for all objects. If there are no selected objects, the hyperlink is intended for the automation menu. When receiving this automation event, you have to bring up a dialog box or provide the means to set the desired type of hyperlink for the specified object(s).

LTANNEVENT_LBUTTONDOWN

[17] Indicates that the left mouse button has been pressed in design mode. The user can change the mouse position or the key flags (so it can simulate that a certain key is pressed).

LTANNEVENT_MOUSEMOVE

[18] Indicates that the mouse is moving in design mode. Note that there is no guarantee that the left mouse button is pressed. lParam is a pointer to an ANNMOUSEPOS structure.

LTANNEVENT_LBUTTONUP

[19] Indicates that the left mouse button has been depressed in design mode.

LTANNEVENT_MENU

[20] Allows you to add user-defined menus that can be displayed in automation design mode. When the right mouse button is clicked in design mode, a popup menu is displayed. Menu items can be added to that menu. The commands should be in the range LTANNEVENT_MENUFIRST [256] to LTANNEVENT_MENULAST [511] inclusively. For more information, refer to the Comments section below.

 

LParam contains the handle to the popup menu about to be displayed. The menu can be changed using the Windows API menu functions (Append Menu, CreatePopupMenu, etc.)

LTANNEVENT_AUTOITEMCHANGING

Indicates that changes are about to occur. Everything that can be done in annotation automated mode sends two messages. Both messages are sent via _LTANNEVENT with wParam equal to LTANNEVENT_AUTOITEMCHANGING. The lParam argument points to a structure of type ANNCHANGEPARAM. The ANNCHANGEPARAM structure has a field called nChange.

1. One message is sent before the action is done. Setting the nChange field to SUCCESS_NO_CHANGE prevents the change, and cancels the "after" event. Returning SUCCESS_CHANGE allows both the change to take place, and the ‘after’ message to be sent.

2. A second messages is sent after the action is done. The return value of this message is ignored.

LTANNEVENT_HIGHLIGHT

[27] Indicates that part or all of the annotation object (EXCEPT for the rotated ellipse, protractor, ruler, and cross product objects, which do not send this message) is about to be drawn with a highlight. This can occur due to selecting the object, changing the object using automation, or changing the object by making calls to L_AnnDefine. The lParam argument points to a variable of type pANNHILIGHT.

This message gets sent for all objects EXCEPT:

image\sqrblit.gif Rotated Ellipse--does not get fired if ellipse is rotated

image\sqrblit.gif Protractor

image\sqrblit.gif Ruler

image\sqrblit.gif Cross product

The highlight behavior can be customized by changing the ppts array. For example, if the annotation object is a rectangle, uCount will be 4 and ppts will be an array of four coordinates (client coordinates) that correspond the corners of the rectangle. Modifying the four points will change the way the rectangle is highlighted.

This message is also useful for updating information about an annotation in real time.

For example, if you are doing a resize/rotate on a rectangle, you can use this event to display the size and angle as it changes.

LTANNEVENT_MENUFIRST

[256]

LTANNEVENT_MENULAST

[511] User defined menu. Refer to the Comments section below.

 

image\sqrblit.gif lParam contains one of the following:

 

The handle to the annotation object.

 

Or, if the message is from the toolbar, one of the Annotation Toolbar Button constants.

 

Or the menu handle (LTANNEVENT_MENU).

 

Or a pointer to an ANNCHANGEPARAM structure (LTANNEVENT_AUTOCHANGING).

 

Or a pointer to an ANNMOUSEPOS structure (LTANNEVENT_LBUTTONDOWN, LTANNEVENT_MOUSENOVE, etc.).

 

Or a pointer to an ANNHILIGHT structure (LTANNEVENT_HIGHLIGHT).

Comments:

For all notifications in the LTANNEVENT_MENUFIRST to LTANNEVENT_MENULAST range, lParam is the handle to the selected object or the automation object. The process works as follows:

1.

When the right mouse button is clicked in design mode, the automation menu is displayed. Before it is displayed however, the WM_LTANNEVENT message is sent with the LTANNEVENT_MENU notification.

2.

At this point the menu handle can be changed and menu items can be added to it. The command IDs must be between LTANNEVENT_MENUFIRST and LTANNEVENT_MENULAST. After the WM_LTANNEVENT message is processed, the modified menu is displayed.

3.

If a standard automation menu item is selected (Undo, Delete, Copy, etc.), the command is processed automatically, and the LTANNEVENT_AUTOITEMCHANGED or LTANNEVENT_AUTOCHANGED notifications are sent.

4.

If a user defined menu item is selected, the WM_LTANNEVENT message is sent with wParam containing the selected command ID. The lParam contains the handle to the object(s) selected. LParam can have the following values:

 

a.

The handle to the automation object.

 

 

In one case no objects are selected and you should change some properties of the automation object.

 

 

In the other case one or more objects are selected and you should change the selected object(s).

 

b.

The handle to a selected object. In this case you should change the selected object.

You can add submenus by calling CreatePopupMenu and AddMenu. Menu items are generally different, depending on the object selected.

The default automation menus send LTANNEVENT_AUTOITEMCHANGED and LTANNEVENT_AUTOCHANGED notifications. If your program relies on them, make sure you send LTANNEVENT_AUTOITEMCHANGED to every object with changed properties, and LTANNEVENT_AUTOCHANGED to every object with changed coordinates.

If you create a Popup menu and add it to the automation menu, it will be destroyed automatically when the window goes away. Do not destroy the menu after adding it to the automation menu.

Example

// The following example is a function that can be used to display all the annotation events
// To use this, call the function
// L_VOID DebugLtAnnEvent(int nID, LPARAM lParam)
// in your annotation program when processing the WM_LTANNEVENT message.
// Pass wParam for the first argument, and lParam for the second argument.


L_TCHAR *aChangeToString[ANNCHANGE_LAST];

L_TCHAR *annGetObjectString(L_UINT uObjectType)
{
   L_TCHAR *pszType = TEXT("Unknown");
   switch(uObjectType)
   {
   case ANNOBJECT_CONTAINER:
      pszType = TEXT("ANNOBJECT_CONTAINER");
      break;

   case ANNOBJECT_POINTER:
      pszType = TEXT("ANNOBJECT_POINTER");
      break;

   case ANNOBJECT_AUDIO:
      pszType = TEXT("ANNOBJECT_AUDIO");
      break;

   case ANNOBJECT_BUTTON:
      pszType = TEXT("ANNOBJECT_BUTTON");
      break;

   case ANNOBJECT_ELLIPSE:
      pszType = TEXT("ANNOBJECT_ELLIPSE");
      break;

   case ANNOBJECT_FREEHAND:
      pszType = TEXT("ANNOBJECT_FREEHAND");
      break;

   case ANNOBJECT_HILITE:
      pszType = TEXT("ANNOBJECT_HILITE");
      break;

   case ANNOBJECT_HOTSPOT:
      pszType = TEXT("ANNOBJECT_HOTSPOT");
      break;

   case ANNOBJECT_LINE:
      pszType = TEXT("ANNOBJECT_LINE");
      break;

   case ANNOBJECT_NOTE:
      pszType = TEXT("ANNOBJECT_NOTE");
      break;

   case ANNOBJECT_POLYGON:
      pszType = TEXT("ANNOBJECT_POLYGON");
      break;

   case ANNOBJECT_POLYLINE:
      pszType = TEXT("ANNOBJECT_POLYLINE");
      break;

   case ANNOBJECT_RECT:
      pszType = TEXT("ANNOBJECT_RECT");
      break;

   case ANNOBJECT_REDACT:
      pszType = TEXT("ANNOBJECT_REDACT");
      break;

   case ANNOBJECT_STAMP:
      pszType = TEXT("ANNOBJECT_STAMP");
      break;

   case ANNOBJECT_TEXT:
      pszType = TEXT("ANNOBJECT_TEXT");
      break;

   case ANNOBJECT_AUTOMATION:
      pszType = TEXT("ANNOBJECT_AUTOMATION");
      break;

   case ANNOBJECT_RULER:
      pszType = TEXT("ANNOBJECT_RULER");
      break;

   case ANNOBJECT_CROSSPRODUCT:
      pszType = TEXT("ANNOBJECT_CROSSPRODUCT");
      break;

   case ANNOBJECT_POINT:
      pszType = TEXT("ANNOBJECT_POINT");
      break;

   case ANNOBJECT_PROTRACTOR:
      pszType = TEXT("ANNOBJECT_PROTRACTOR");
      break;

   case ANNOBJECT_VIDEO:
      pszType = TEXT("ANNOBJECT_VIDEO");
      break;

   case ANNOBJECT_PUSHPIN:
      pszType = TEXT("ANNOBJECT_PUSHPIN");
      break;

   case ANNOBJECT_FREEHANDHOTSPOT:
      pszType = TEXT("ANNOBJECT_FREEHANDHOTSPOT");
      break;

   case ANNOBJECT_CURVE:
      pszType = TEXT("ANNOBJECT_CURVE");
      break;

   case ANNOBJECT_CURVECLOSED:
      pszType = TEXT("ANNOBJECT_CURVECLOSED");
      break;

   case ANNOBJECT_ENCRYPT:
      pszType = TEXT("ANNOBJECT_ENCRYPT");
      break;
   }
   return pszType;
}

L_VOID LoadChangeToStringTable()
{
   aChangeToString[ANNCHANGE_TAG]   = TEXT("ANNCHANGE_TAG");
   aChangeToString[ANNCHANGE_VISIBLE]   = TEXT("ANNCHANGE_VISIBLE");
   aChangeToString[ANNCHANGE_SELECTED]    = TEXT("ANNCHANGE_SELECTED");
   aChangeToString[ANNCHANGE_FONT_BOLD]   = TEXT("ANNCHANGE_FONT_BOLD");
   aChangeToString[ANNCHANGE_FONT_ITALIC]   = TEXT("ANNCHANGE_FONT_ITALIC");
   aChangeToString[ANNCHANGE_FONT_STRIKETHROUGH]   = TEXT("ANNCHANGE_FONT_STRIKETHROUGH");
   aChangeToString[ANNCHANGE_FONT_UNDERLINE]   = TEXT("ANNCHANGE_FONT_UNDERLINE");
   aChangeToString[ANNCHANGE_LINEWIDTH]   = TEXT("ANNCHANGE_LINEWIDTH");
   aChangeToString[ANNCHANGE_LINESTYLE]    = TEXT("ANNCHANGE_LINESTYLE");
   aChangeToString[ANNCHANGE_FILLPATTERN]   = TEXT("ANNCHANGE_FILLPATTERN");
   aChangeToString[ANNCHANGE_FILLMODE]   = TEXT("ANNCHANGE_FILLMODE");
   aChangeToString[ANNCHANGE_POLYFILLMODE]   = TEXT("ANNCHANGE_POLYFILLMODE");
   aChangeToString[ANNCHANGE_FONT_SIZE]   = TEXT("ANNCHANGE_FONT_SIZE");
   aChangeToString[ANNCHANGE_FORECOLOR]   = TEXT("ANNCHANGE_FORECOLOR");
   aChangeToString[ANNCHANGE_BACKCOLOR]   = TEXT("ANNCHANGE_BACKCOLOR");
   aChangeToString[ANNCHANGE_TRANSPARENT_COLOR]   = TEXT("ANNCHANGE_TRANSPARENT_COLOR");
   aChangeToString[ANNCHANGE_TRANSPARENT]   = TEXT("ANNCHANGE_TRANSPARENT");
   aChangeToString[ANNCHANGE_FONT_NAME]   = TEXT("ANNCHANGE_FONT_NAME");
   aChangeToString[ANNCHANGE_TEXT]    = TEXT("ANNCHANGE_TEXT");
   aChangeToString[ANNCHANGE_ROP2]   = TEXT("ANNCHANGE_ROP2");
   aChangeToString[ANNCHANGE_BITMAP]   = TEXT("ANNCHANGE_BITMAP"); 
   aChangeToString[ANNCHANGE_BITMAP2]    = TEXT("ANNCHANGE_BITMAP2"); 
   aChangeToString[ANNCHANGE_METAFILE]   = TEXT("ANNCHANGE_METAFILE"); 
   aChangeToString[ANNCHANGE_METAFILE2]   = TEXT("ANNCHANGE_METAFILE2"); 
   aChangeToString[ANNCHANGE_NAME_FORECOLOR]   = TEXT("ANNCHANGE_NAME_FORECOLOR");
   aChangeToString[ANNCHANGE_NAME_BACKCOLOR]   = TEXT("ANNCHANGE_NAME_BACKCOLOR"); 
   aChangeToString[ANNCHANGE_NAME_SHOWNAME]   = TEXT("ANNCHANGE_NAME_SHOWNAME");
   aChangeToString[ANNCHANGE_NAME_OFFSET]   = TEXT("ANNCHANGE_NAME_OFFSET");

   aChangeToString[ANNCHANGE_NAME_RESTRICT]   = TEXT("ANNCHANGE_NAME_RESTRICT");
   aChangeToString[ANNCHANGE_NAME_BACKTRANSPARENT]   = TEXT("ANNCHANGE_NAME_BACKTRANSPARENT");
   aChangeToString[ANNCHANGE_NAME_TEXT]   = TEXT("ANNCHANGE_NAME_TEXT");
   aChangeToString[ANNCHANGE_NAME_FONT_NAME]   = TEXT("ANNCHANGE_NAME_FONT_NAME");
   aChangeToString[ANNCHANGE_NAME_FONT_BOLD]   = TEXT("ANNCHANGE_NAME_FONT_BOLD");
   aChangeToString[ANNCHANGE_NAME_FONT_ITALIC]   = TEXT("ANNCHANGE_NAME_FONT_ITALIC");
   aChangeToString[ANNCHANGE_NAME_FONT_STRIKEOUT]   = TEXT("ANNCHANGE_NAME_FONT_STRIKEOUT");
   aChangeToString[ANNCHANGE_NAME_FONT_UNDERLINE]   = TEXT("ANNCHANGE_NAME_FONT_UNDERLINE");
   aChangeToString[ANNCHANGE_NAME_FONT_SIZE]   = TEXT("ANNCHANGE_NAME_FONT_SIZE");
   aChangeToString[ANNCHANGE_POINT_USE_BITMAP]   = TEXT("ANNCHANGE_POINT_USE_BITMAP");
   aChangeToString[ANNCHANGE_POINT_RADIUS]   = TEXT("ANNCHANGE_POINT_RADIUS");
   aChangeToString[ANNCHANGE_POINT_BORDER_COLOR]   = TEXT("ANNCHANGE_POINT_BORDER_COLOR");
   aChangeToString[ANNCHANGE_POINT_FILL_COLOR]   = TEXT("ANNCHANGE_POINT_FILL_COLOR");
   aChangeToString[ANNCHANGE_POINT_TRANSPARENT_FILL]   = TEXT("ANNCHANGE_POINT_TRANSPARENT_FILL");
   aChangeToString[ANNCHANGE_POINT_FIXED_SIZE]   = TEXT("ANNCHANGE_POINT_FIXED_SIZE");
   aChangeToString[ANNCHANGE_SHOW_DEFAULT_HANDLES]   = TEXT("ANNCHANGE_SHOW_DEFAULT_HANDLES");
   aChangeToString[ANNCHANGE_GAP_DEFAULT_HANDLES]   = TEXT("ANNCHANGE_GAP_DEFAULT_HANDLES");
   aChangeToString[ANNCHANGE_HYPERLINK]   = TEXT("ANNCHANGE_HYPERLINK");
   aChangeToString[ANNCHANGE_GAUGELENGTH]   = TEXT("ANNCHANGE_GAUGELENGTH");
   aChangeToString[ANNCHANGE_BITMAP_DPI_X]   = TEXT("ANNCHANGE_BITMAP_DPI_X");
   aChangeToString[ANNCHANGE_BITMAP_DPI_Y]   = TEXT("ANNCHANGE_BITMAP_DPI_Y");
   aChangeToString[ANNCHANGE_RULER_UNIT]   = TEXT("ANNCHANGE_RULER_UNIT");
   aChangeToString[ANNCHANGE_RULER_SHOW_FLAGS]   = TEXT("ANNCHANGE_RULER_SHOW_FLAGS");
   aChangeToString[ANNCHANGE_PROTRACTOR]   = TEXT("ANNCHANGE_PROTRACTOR");
   aChangeToString[ANNCHANGE_ENCRYPTOR_TYPE]   = TEXT("ANNCHANGE_ENCRYPTOR_TYPE");
   aChangeToString[ANNCHANGE_ENCRYPTOR_KEY]   = TEXT("ANNCHANGE_ENCRYPTOR_KEY");
   aChangeToString[ANNCHANGE_ENCRYPTOR_NEVER_ENCRYPTED]  = TEXT("ANNCHANGE_ENCRYPTOR_NEVER_ENCRYPTED");
   aChangeToString[ANNCHANGE_ENCRYPTOR_BITMAP]   = TEXT("ANNCHANGE_ENCRYPTOR_BITMAP");
   aChangeToString[ANNCHANGE_MOVE]   = TEXT("ANNCHANGE_MOVE");
   aChangeToString[ANNCHANGE_MOVE_POINT]   = TEXT("ANNCHANGE_MOVE_POINT");
   aChangeToString[ANNCHANGE_RESIZE]   = TEXT("ANNCHANGE_RESIZE");
   aChangeToString[ANNCHANGE_ROTATE]   = TEXT("ANNCHANGE_ROTATE");
   aChangeToString[ANNCHANGE_RESIZE_ROTATE]   = TEXT("ANNCHANGE_RESIZE_ROTATE");
   aChangeToString[ANNCHANGE_UNDO]    = TEXT("ANNCHANGE_UNDO");
   aChangeToString[ANNCHANGE_CUT]    = TEXT("ANNCHANGE_CUT");
   aChangeToString[ANNCHANGE_PASTE]   = TEXT("ANNCHANGE_PASTE");
   aChangeToString[ANNCHANGE_DELETE]   = TEXT("ANNCHANGE_DELETE");
   aChangeToString[ANNCHANGE_SELECT_ALL]   = TEXT("ANNCHANGE_SELECT_ALL");
   aChangeToString[ANNCHANGE_BRING_TO_FRONT]   = TEXT("ANNCHANGE_BRING_TO_FRONT");
   aChangeToString[ANNCHANGE_BRING_TO_BACK]    = TEXT("ANNCHANGE_BRING_TO_BACK");
   aChangeToString[ANNCHANGE_LOCK]                       = TEXT("ANNCHANGE_LOCK");
   aChangeToString[ANNCHANGE_UNLOCK]   = TEXT("ANNCHANGE_UNLOCK");
   aChangeToString[ANNCHANGE_LOCK_SELECTED]   = TEXT("ANNCHANGE_LOCK_SELECTED");
   aChangeToString[ANNCHANGE_UNLOCK_SELECTED]   = TEXT("ANNCHANGE_UNLOCK_SELECTED");
   aChangeToString[ANNCHANGE_INSERT]   = TEXT("ANNCHANGE_INSERT");
   aChangeToString[ANNCHANGE_NOTE_BACKCOLOR]    = TEXT("ANNCHANGE_NOTE_BACKCOLOR");
   aChangeToString[ANNCHANGE_HILITE_BACKCOLOR]   = TEXT("ANNCHANGE_HILITE_BACKCOLOR");
   aChangeToString[ANNCHANGE_REDACT_BACKCOLOR]   = TEXT("ANNCHANGE_REDACT_BACKCOLOR");
   aChangeToString[ANNCHANGE_ENCRYPT_METAFILE]   = TEXT("ANNCHANGE_ENCRYPT_METAFILE");
   aChangeToString[ANNCHANGE_DECRYPT_METAFILE]   = TEXT("ANNCHANGE_DECRYPT_METAFILE");
   aChangeToString[ANNCHANGE_HOTSPOT_METAFILE]   = TEXT("ANNCHANGE_HOTSPOT_METAFILE");
}

 

L_INT DebugLtAnnEvent_AutoItemChanging(HANNOBJECT hObject, L_TCHAR szMsg[], LPARAM lParam) 
{
   pANNCHANGEPARAM pAnnChangeParam = (pANNCHANGEPARAM)lParam; 
   L_UINT uType; 
   L_TCHAR szTemp[200]; 
   
   L_AnnGetType(hObject, &uType); 
   
   wsprintf(szMsg, TEXT("LTANNEVENT_AUTOITEMCHANGING: uChange[%25s] "), aChangeToString[pAnnChangeParam->uChange]); 
   switch (pAnnChangeParam->uUnionType) 
   {
   case ANNTYPE_NONE: 
      lstrcpy(szTemp, TEXT(""));
      break; 

   case ANNTYPE_COLORREF: 
      wsprintf(szTemp, TEXT("crColor[0x%x]"), pAnnChangeParam->u.crColor); 
      break; 
      
   case ANNTYPE_UINT32: 
      wsprintf(szTemp, TEXT("uUint32[%d]"), pAnnChangeParam->u.uUint32); 
      break; 
      
   case ANNTYPE_BOOL: 
      wsprintf(szTemp, TEXT("bBool[%s]"), pAnnChangeParam->u.bBool ? TEXT("TRUE") : TEXT("FALSE"));
      break; 
      
   case ANNTYPE_DOUBLE: 
      wsprintf(szTemp, TEXT("dDouble[%f]"), pAnnChangeParam->u.dDouble); 
      break; 
      
   case ANNTYPE_UINT: 
      wsprintf(szTemp, TEXT("uUint[%d]"), pAnnChangeParam->u.uUint); 
      break; 
      
   case ANNTYPE_LPCSTR: 
      wsprintf(szTemp, TEXT("pszString[%s]"), pAnnChangeParam->u.pszString); 
      break; 
      
   case ANNTYPE_ANNPOINT: 
      wsprintf(szTemp, TEXT("apt[%f, %f]"), pAnnChangeParam->u.apt.x, pAnnChangeParam->u.apt.y); 
      break; 
      
   case ANNTYPE_BITMAP: 
      wsprintf(szTemp, TEXT("pBitmapHandle Width[%d]  Height[%d] BitsPerPixel[%d]"), 
         pAnnChangeParam->u.pBitmapHandle->Width, 
         pAnnChangeParam->u.pBitmapHandle->Height, 
         pAnnChangeParam->u.pBitmapHandle->BitsPerPixel
         ); 
      break; 

   case ANNTYPE_HMETAFILE: 
      wsprintf(szTemp, TEXT("hMetafile [0x%x]"), pAnnChangeParam->u.hMetafile); 
      break; 

   case ANNTYPE_RULER_UNIT: 
      {
         L_TCHAR *pszUnit; 
         switch(pAnnChangeParam->u.AnnRulerUnit.uUnit) 
         {
         case ANNUNIT_INCHES: 
            pszUnit = TEXT("ANNUNIT_INCHES");
            break; 
         case ANNUNIT_FEET : 
            pszUnit = TEXT("ANNUNIT_FEET");
            break; 
         case ANNUNIT_YARDS : 
            pszUnit = TEXT("ANNUNIT_YARDS");
            break; 
         case ANNUNIT_MICROMETERS: 
            pszUnit = TEXT("ANNUNIT_MICROMETERS");
            break; 
         case ANNUNIT_MILLIMETERS: 
            pszUnit = TEXT("ANNUNIT_MILLIMETERS");
            break; 
         case ANNUNIT_CENTIMETERS: 
            pszUnit = TEXT("ANNUNIT_CENTIMETERS");
            break; 
         case ANNUNIT_METERS: 
            pszUnit = TEXT("ANNUNIT_METERS");
            break; 
         case ANNUNIT_TWIPS: 
            pszUnit = TEXT("ANNUNIT_TWIPS");
            break; 
         case ANNUNIT_POINTS: 
            pszUnit = TEXT("ANNUNIT_POINTS");
            break; 
         case ANNUNIT_PIXELS: 
            pszUnit = TEXT("ANNUNIT_PIXELS");
            break; 
         default: 
            pszUnit = TEXT("Unknown Type");
            break; 
         }
         wsprintf(szTemp, TEXT("uUnit[%s] pAbbrev[%s] uPrecision[%d]"), 
            pszUnit, 
            pAnnChangeParam->u.AnnRulerUnit.pAbbrev ? pAnnChangeParam->u.AnnRulerUnit.pAbbrev: TEXT(""),
            pAnnChangeParam->u.AnnRulerUnit.uPrecision
            ); 
         break; 
      }
   case ANNTYPE_HYPERLINK: 
      {
         L_TCHAR *pszType; 
         switch(pAnnChangeParam->u.AnnHyperlink.uLinkType) 
         {
         case ANNLINK_NONE: 
            pszType = TEXT("ANNLINK_NONE");
            break; 
         case ANNLINK_LTANNEVENT: 
            pszType = TEXT("ANNLINK_LTANNEVENT");
            break; 
         case ANNLINK_USERMSG: 
            pszType = TEXT("ANNLINK_USERMSG");
            break; 
         case ANNLINK_RUN:        
            pszType = TEXT("ANNLINK_RUN");
            break; 
         case ANNLINK_WEBPAGE: 
            pszType = TEXT("ANNLINK_WEBPAGE");
            break; 
         default: 
            pszType = TEXT("Unknown Type");
            break; 
         }
         wsprintf(szTemp, TEXT("uType[%s] uLinkMsg[%d] uLinkParam[%d] pLink[%s]"), 
            pszType, 
            pAnnChangeParam->u.AnnHyperlink.uLinkMsg, 
            pAnnChangeParam->u.AnnHyperlink.uLinkParam, 
            pAnnChangeParam->u.AnnHyperlink.pLinkText ? pAnnChangeParam->u.AnnHyperlink.pLinkText : TEXT("")
            ); 
         break; 
      }
   case ANNTYPE_PROTRACTOR: 
      {
         L_TCHAR *pszAngleUnit; 
         switch(pAnnChangeParam->u.AnnProtractor.uAngleUnit) 
         {
         case ANNANGLE_DEGREES: 
            pszAngleUnit = TEXT("ANNANGLE_DEGREES");
            break; 
         case ANNANGLE_RADIANS: 
            pszAngleUnit = TEXT("ANNANGLE_RADIANS");
            break; 
         default: 
            pszAngleUnit = TEXT("Unknown Angle Unit");
            break; 
         }
         wsprintf(szTemp, TEXT("bAcute[%s] AngleUnit[%s] pszAbbrev[%s] uPrecision[%d] dArcRadius[%f]"), 
            pAnnChangeParam->u.AnnProtractor.bAcute ? TEXT("TRUE") : TEXT("FALSE"),
            pszAngleUnit, 
            pAnnChangeParam->u.AnnProtractor.pszAbbrev ? pAnnChangeParam->u.AnnProtractor.pszAbbrev : TEXT(""),
            pAnnChangeParam->u.AnnProtractor.uAnglePrecision, 
            pAnnChangeParam->u.AnnProtractor.dArcRadius
            ); 
         break; 
      }
      
   case ANNTYPE_MOVE: 
      {
         L_TCHAR *pszState; 
         switch(pAnnChangeParam->u.AnnMove.nState) 
         {
         case STATE_BEGIN: 
            pszState = TEXT("STATE_BEGIN");
            break; 
         case STATE_UPDATE: 
            pszState = TEXT("STATE_UPDATE");
            break; 
         case STATE_END: 
            pszState = TEXT("STATE_END");
            break; 
         default: 
            pszState = TEXT("Unknown State");
            break; 
         }
         
         wsprintf(szTemp, TEXT("State[%12s] (dx,dy)(%3d,%3d)"), 
            pszState, 
            pAnnChangeParam->u.AnnMove.pt.x, 
            pAnnChangeParam->u.AnnMove.pt.y
            ); 
         break; 
      }
      
   case ANNTYPE_MOVE_POINT: 
      {
         L_TCHAR *pszState; 
         switch(pAnnChangeParam->u.AnnMovePoint.nState) 
         {
         case STATE_BEGIN: 
            pszState = TEXT("STATE_BEGIN");
            break; 
         case STATE_UPDATE: 
            pszState = TEXT("STATE_UPDATE");
            break; 
         case STATE_END: 
            pszState = TEXT("STATE_END");
            break; 
         default: 
            pszState = TEXT("Unknown State");
            break; 
         }
         
         wsprintf(szTemp, TEXT("State[%s] Point(%f,%f) Index[%d] (dx,dy)(%d,%d)"), 
            pszState, 
            pAnnChangeParam->u.AnnMovePoint.apt.x, 
            pAnnChangeParam->u.AnnMovePoint.apt.y, 
            pAnnChangeParam->u.AnnMovePoint.uIndex, 
            pAnnChangeParam->u.AnnMovePoint.pt.x, 
            pAnnChangeParam->u.AnnMovePoint.pt.y
            ); 
         break; 
      }

   case ANNTYPE_RESIZE_ROTATE: 
      {
         L_TCHAR *pszState; 
         switch(pAnnChangeParam->u.AnnResizeRotate.nState) 
         {
         case STATE_BEGIN: 
            pszState = TEXT("STATE_BEGIN");
            break; 
         case STATE_UPDATE: 
            pszState = TEXT("STATE_UPDATE");
            break; 
         case STATE_END: 
            pszState = TEXT("STATE_END");
            break; 
         default: 
            pszState = TEXT("Unknown State");
            break; 
         }
         
         wsprintf(szTemp, TEXT("State[%s] AnnXForm\n\tr11[%10.3f] r12[%10.3f]\n\tr21[%10.3f] r22[%10.3f]\n\t tx[%10.3f]  ty[%10.3f]\n\tdAngle[%10.3f]"), 
            pszState, 
            pAnnChangeParam->u.AnnResizeRotate.pAnnXForm->r11, 
            pAnnChangeParam->u.AnnResizeRotate.pAnnXForm->r12, 
            pAnnChangeParam->u.AnnResizeRotate.pAnnXForm->r21, 
            pAnnChangeParam->u.AnnResizeRotate.pAnnXForm->r22, 
            pAnnChangeParam->u.AnnResizeRotate.pAnnXForm->tx, 
            pAnnChangeParam->u.AnnResizeRotate.pAnnXForm->ty, 
            pAnnChangeParam->u.AnnResizeRotate.dAngle
              ); 
         break; 
      }

   case ANNTYPE_HANNOBJECT: 
      {
         wsprintf(szTemp, TEXT("hContainer[0x%x]"), pAnnChangeParam->u.hObject); 
         break; 
      }
      
   default: 
      lstrcpy(szTemp, TEXT("Unknown Type"));
   }
   
   lstrcat(szMsg, szTemp); 
   lstrcat(szMsg, pAnnChangeParam->bAfter ? TEXT("--After ") : TEXT("--Before"));

   if (pAnnChangeParam->uFlags) 
   {
      L_TCHAR szFlags[300]; 
      wsprintf(szFlags, TEXT(" uFlags[0x%03x]"), pAnnChangeParam->uFlags); 
      if (pAnnChangeParam->uFlags & ANNCHANGE_FLAG_UNDO) 
         lstrcat(szFlags, TEXT("ANNCHANGE_FLAG_UNDO,")); 
      if (pAnnChangeParam->uFlags & ANNCHANGE_FLAG_CUT) 
         lstrcat(szFlags, TEXT("ANNCHANGE_FLAG_CUT,")); 
      if (pAnnChangeParam->uFlags & ANNCHANGE_FLAG_PASTE) 
         lstrcat(szFlags, TEXT("ANNCHANGE_FLAG_PASTE,")); 
      if (pAnnChangeParam->uFlags & ANNCHANGE_FLAG_SELECT_ALL) 
         lstrcat(szFlags, TEXT("ANNCHANGE_SELECT_ALL,")); 
      if (pAnnChangeParam->uFlags & ANNCHANGE_FLAG_UNLOCK_SELECTED) 
         lstrcat(szFlags, TEXT("ANNCHANGE_FLAG_UNLOCK_SELECTED,")); 
      if (pAnnChangeParam->uFlags & ANNCHANGE_FLAG_LOCK_SELECTED) 
         lstrcat(szFlags, TEXT("ANNCHANGE_FLAG_LOCK_SELECTED,")); 
      lstrcat(szMsg, szFlags); 
   }
   return SUCCESS_CHANGE; 
}


L_VOID DebugLtAnnEvent(int nID, LPARAM lParam) 
{
   static int nCount = 0; 
   const L_TCHAR * pszMsg = NULL; 
   L_TCHAR szMsg[500]; 
   HANNOBJECT hObject = (HANNOBJECT)lParam; 
   pANNCHANGEPARAM pAnnChangeParam; 

   if (!gbMessages) 
      return; 
  
   // This displays only the WM_LTANNEVENT LTANNEVENT_AUTOITEMCHANGING events
   // Remove the line below to display ALL annotation messages
   if (nID != LTANNEVENT_AUTOITEMCHANGING) 
      return; 
   
   pAnnChangeParam = (pANNCHANGEPARAM)lParam; 
   hObject = pAnnChangeParam->hObject; 
   pAnnChangeParam->nChange = DebugLtAnnEvent_AutoItemChanging(hObject, szMsg, lParam); 
   pszMsg = szMsg; 
   
   if (pszMsg) 
   {
      L_TCHAR szMsg[300]; 
      L_TCHAR *pszType= NULL; 
      L_UINT uObjectType=999; 

      if (hObject) 
      {
         L_AnnGetType(hObject, &uObjectType); 
         pszType = annGetObjectString(uObjectType); 
         wsprintf(szMsg, TEXT("[%3d]*** [(%2d) %20s] %s\n"), nCount++, uObjectType, pszType, pszMsg); 
      }
      else
      {
         wsprintf(szMsg, TEXT("[%3d]*** %s\n"), nCount++, pszMsg); 
      }
      OutputDebugString(szMsg); 
   }
}