Creating and Using Annotations (C++ 4.0 and later)

Note: This topic is for Document/Medical only.

Take the following steps to add code that demonstrates the creation and deletion, saving and loading, and copying and pasting of annotation objects. This code also demonstrates the related events. Message boxes prompt for user actions that trigger events.

1. Start with the project that you created in Loading and Displaying an Image.

2. Go to the Project WorkSpace and click the ResourceView tab.

3. Double-click Dialog and double-click IDD_TUTOR_DIALOG to bring up the application's dialog box.

4. image\btncmd.gif Add four new buttons at the top of the form. To do this for each button, select the button control on the Controls toolbar. Then, click and drag to position the button on the dialog box. Then double-click the button to change its properties. Set the properties as follows:

ID

Caption

IDC_ANNTOGGLE

Start

IDC_IOTOGGLE

Save

IDC_CLIPBOARDTOGGLE

Copy

IDC_REALIZE

Realize

5. Press Ctrl-F4 to close all windows back to the Project Workspace.

6. Add code for the user mode toggle button (IDC_ANNTOGGLE). To do so, press Ctrl-W to go to the MFC Class Wizard; then do the following:

a. Click the Message Maps tab.

b. In the Class Name combo box, select CTutorDlg.

c. In the Object IDs list box, select IDC_ANNTOGGLE.

d. In the Messages list box, select BN_CLICKED.

e. Click the Add function button. Choose OK for the default function name (OnAnntoggle).

f. Click the Edit Code button to start entering the code.

void CTutorDlg::OnAnntoggle() 
{
   CString Caption;
   // Use the button to toggle between design mode and run mode
   CWnd *pButton = GetDlgItem(IDC_ANNTOGGLE);
   pButton->GetWindowText(Caption);
   if (Caption == "Start")
   {
      m_Lead1.SetAnnUserMode(ANNUSERMODE_DESIGN);
      m_Lead1.SetAnnTool(ANNTOOL_BUTTON);
      // Make run mode the next thing.
      pButton->SetWindowText("Run Mode");
      MessageBox("In design mode now. Draw a button object.");
   }
   else if (Caption == "Design Mode")
   {
      m_Lead1.SetAnnUserMode(ANNUSERMODE_DESIGN);
      m_Lead1.SetAnnTool(ANNTOOL_BUTTON);
      // Make run mode the next thing.
      pButton->SetWindowText("Run Mode");
   }
   else // The button takes us to run mode
   {
      m_Lead1.SetAnnUserMode(ANNUSERMODE_RUN);
      MessageBox("Click on your new button.");
      pButton->SetWindowText("Design Mode");
   }
}

7. Add code for the load and save toggle button (IDC_IOTOGGLE). To do so, press Ctrl-W to go to the MFC Class Wizard; then do the following:

a. Click the Message Maps tab.

b. In the Class Name combo box, select CTutorDlg.

c. In the Object IDs list box, select IDC_IOTOGGLE.

d. In the Messages list box, select BN_CLICKED.

e. Click the Add function button. Choose OK for the default function name (OnIotoggle).

f. Click the Edit Code button to start entering the code.

void CTutorDlg::OnIotoggle() 
{
   CString Caption;
   int nRet;
   // Disable errors so that we can trap our own.
   m_Lead1.SetEnableMethodErrors(FALSE);
   // Use the button to toggle between saving and loading annotations
   CWnd *pButton = GetDlgItem(IDC_IOTOGGLE);
   pButton->GetWindowText(Caption);
   if (Caption == "Save")
   {
      // Do nothing if there are no annotations.
      if (m_Lead1.GetAnnContainer() == 0)
      return;
      // Save the selected annotations.
      nRet = m_Lead1.AnnSave("c:\\lead\\images\\tmp.ann", 
         ANNFMT_NATIVE, TRUE, SAVE_OVERWRITE, 0);
      if (nRet == 0)
      {
         pButton->SetWindowText("Load");
         // Make loading the next thing.
         MessageBox("Use the right mouse button to delete any annotations, then click Load.");
      }
      else
      {
         char  buffer[50];
         sprintf(buffer, "LEAD Error %d", nRet);
         MessageBox(buffer, "ERROR", MB_OK);
      }
   }
   else // We are loading annotations
   {
      // Make sure we are in design mode
      m_Lead1.SetAnnUserMode(ANNUSERMODE_DESIGN);
      // Load the annotations.
      nRet = m_Lead1.AnnLoad("c:\\lead\\images\\tmp.ann", 1);
      if (nRet == 0)
         pButton->SetWindowText("Save");
      else
         MessageBox("No annotations to load.");
   }
}

8. Add code for the clipboard toggle button (IDC_CLIPBOARDTOGGLE). To do so, press Ctrl-W to go to the MFC Class Wizard; then do the following. (Note that Copy, Cut, and Paste are available as automated popup menu options. This code is for tailoring your application.)

a. Click the Message Maps tab.

b. In the Class Name combo box, select CTutorDlg.

c. In the Object IDs list box, select IDC_IOTOGGLE.

d. In the Messages list box, select BN_CLICKED.

e. Click the Add function button. Choose OK for the default function name (OnIotoggle).

f. Click the Edit Code button to start entering the code.

void CTutorDlg::OnClipboardtoggle() 
{
   CString Caption;
   int nRet;
   // Disable errors so that we can trap our own.
   m_Lead1.SetEnableMethodErrors(FALSE);
   // Use the button to toggle between copying and pasting annotations
   CWnd *pButton = GetDlgItem(IDC_CLIPBOARDTOGGLE);
   pButton->GetWindowText(Caption);
   if (Caption == "Copy")
   {
      // Do nothing if there are no annotations.
      if (m_Lead1.GetAnnContainer() == 0)
         return;
      // Copy the selected annotations to the clipboard.
      nRet = m_Lead1.AnnCopy(ANNFMT_NATIVE, TRUE, TRUE);
      if (nRet == 0)
      {
         // Make pasting the next thing.
         pButton->SetWindowText("Paste");
         MessageBox("Use the right mouse button to delete any annotations, then click Paste");
      }
      else
      {
         char  buffer[50];
         sprintf(buffer, "LEAD Error %d", nRet);
         MessageBox(buffer, "ERROR", MB_OK);
      }
   }
   else // We are pasting annotations
   {
      // Make sure we are in design mode
      m_Lead1.SetAnnUserMode(ANNUSERMODE_DESIGN);
      // Paste the annotations
      if (m_Lead1.GetAnnPasteReady())
      {
         m_Lead1.AnnPaste();
         pButton->SetWindowText("Copy");
      }
      else
      {
          MessageBox("No annotations to paste");
      }
   }
}

9. Add code for the realize button (IDC_REALIZE), which renders the annotation objects to the bitmap. To do so, press Ctrl-W to go to the MFC Class Wizard; then do the following:

a. Click the Message Maps tab.

b. In the Class Name combo box, select CTutorDlg.

c. In the Object IDs list box, select IDC_REALIZE.

d. In the Messages list box, select BN_CLICKED.

e. Click the Add function button. Choose OK for the default function name (OnIotoggle).

f. Click the Edit Code button to start entering the code.

void CTutorDlg::OnRealize() 
{
   m_Lead1.AnnRealize(FALSE);
   m_Lead1.ForceRepaint();
   MessageBox("Annotations are now rendered to the bitmap");
}

10. To add the code for the LEAD control's annotation events, do the following:

a. Press Ctrl-W to go to the MFC ClassWizard.

b. In the Class Name combo box, select CTutorDlg.

c. In the Object IDs list box, select IDC_LEAD1.

d. Continue with the remaining steps for each mouse event.

11. In the MFC ClassWizard, double-click the AnnCreate event and add code as follows:

void CTutorDlg::OnAnnCreateLead1(long hObject) 
{
   //  Update the tag if we need one.
   static int NewTag;
   if ((m_Lead1.AnnGetType(hObject) == ANNOBJECT_BUTTON) || 
      (m_Lead1.AnnGetType(hObject) == ANNOBJECT_HOTSPOT)) 
   {
      NewTag = NewTag + 1;
      m_Lead1.AnnSetTag(hObject, NewTag);
   }
}

12. In the MFC ClassWizard, double-click the AnnDrawn event and add code as follows:

void CTutorDlg::OnAnnDrawnLead1(long hObject) 
{
   m_Lead1.SetAnnTool(ANNTOOL_SELECT);
   MessageBox("Use the right mouse button to modify this object; then click on Run Mode to test it.");
}

13. In the MFC ClassWizard, double-click the AnnClicked event and add code as follows:

void CTutorDlg::OnAnnClickedLead1(long hObject) 
{
   char  buffer[50];
   sprintf(buffer, " This is what we do for the button tagged %d", m_Lead1.AnnGetTag(hObject));
   MessageBox(buffer, "NOTE", MB_OK);
}

14. In the MFC ClassWizard, double-click the AnnDestroy event and add code as follows:

void CTutorDlg::OnAnnDestroyLead1(long hObject) 
{
   char  buffer[50];
   sprintf(buffer, "The object tagged %d is deleted.", m_Lead1.AnnGetTag(hObject));
   MessageBox(buffer, "NOTE", MB_OK);
}

15. Compile and run your program to test it.