Implementing an Automated Annotations Program (C++ 5.0 and later)
Take the following steps to start a project and to add some code that positions, scales, and displays an image in a dialog box.
| 1. | Start a new project as follows: | |
| 
 | Run Microsoft Visual C++ 5.0, select the File >New menu option, and do the following: | |
| 
 | a. | Click the Projects tab. | 
| 
 | b. | Select MFC AppWizard (exe) as the project type | 
| 
 | c. | In the Project name text box, specify Automated. | 
| 
 | d. | In the Location text box, specify the path of the project. | 
| 
 | e. | Click the OK button. | 
| 2. | In the Step 1 dialog box, do the following: | |
| 
 | a. | Select Dialog based. | 
| 
 | b. | Click the Next button. | 
| 3. | In the Step 2 of 4 dialog box, do the following: | |
| 
 | a. | Ensure that About Box is selected. | 
| 
 | b. | Ensure that 3D Controls is selected. | 
| 
 | c. | Click the Next button. | 
| 4. | In the Step 3 of 4 dialog box, do the following: | |
| 
 | a. | For comments, ensure that Yes, Please is selected. | 
| 
 | b. | For how to use the MFC library, select Use MFC in a Shared DLL. | 
| 
 | c. | Click the Next button. | 
| 5. | In the Step 4 of 4 dialog box, just click Finish. | |
| 6. | Read New Project Information, and click OK. (The AppWizard creates the project files and opens the project.) | |
| 7. | Add #include statements to your program so you can access the LEAD Class Library constants and classes: | |
| 
 | a. | In the Project Workspace, click the FileView tab. | 
| 
 | b. | Double-click the Automated files folder to open it. | 
| 
 | c. | Double-click the Header Files folder to open it. | 
| 
 | d. | Double-click the StdAfx.h file to edit it. | 
| 
 | Add the following lines to the end of the file (keep in mind, you may have to change the path to where the header files reside): | |
#include "..\..\..\..\include\ClassLib\ltWrappr.h"
| 8. | Add a Button control to the main window as follows: | |
| 
 | a. | In the Project Workspace, click the ResourceView tab. | 
| 
 | b. | Double-click the Automated resources folder to open it. | 
| 
 | c. | Double-click the Dialog folder to open it. | 
| 
 | d. | Double-click IDD_AUTOMATED_DIALOG to design the form. | 
| 
 | e. | Select the TODO... text control; then press the Delete key to delete it. | 
| 
 | f. | Click the Button control icon; then size and position the control as you want it to appear at run time. | 
| 9. | Add a command button to your form and name it as follows: | |
| 
 | ID | Caption | 
| 
 | IDC_BITMAPWND | Bitmap Window | 
| 10. | Change the command button properties as follows: | |
| 
 | a. | Right-click on the button then select properties. | 
| 
 | b. | Click the Styles tab. | 
| 
 | c. | Select the Flat check box | 
| 
 | d. | Select the Owner Draw check box | 
| 
 | e. | Click the General tab. | 
| 
 | f. | Clear the Visible check box | 
| 
 | g. | Close the dialog | 
| 11. | Press Ctrl-F4 to close all windows back to the Project Workspace. | |
| 12. | Add the following Member Variables to CAutomatedDlg Class: | |
| 
 | LAnnContainer | m_LeadAContainer; | 
| 
 | LAnnToolBar | m_LeadAToolBar; | 
| 
 | HANNOBJECT | hAutoObject; | 
| 
 | LAnnAutomation | m_LeadAAutomation; | 
| 
 | CBitmapWindow | m_LBitmap; | 
| 13. | Go to the OnInitDialog() function as follows: | |
| 
 | a. | In the Project Workspace, click the ClassView tab. | 
| 
 | b. | Double-click the Automated classes folder to open it. | 
| 
 | c. | Expand the CAAutomatedDlg class. | 
| 
 | d. | Double-click the OnInitDialog() function to edit it. | 
| 14. | Edit the OnInitDialog() function to add the following code after the line that says //TODO: Add extra initialization here: | |
   LSettings::LoadLibraries(LT_ALL_LEADLIB);
   LSettings::UnlockSupport(L_SUPPORT_DOCUMENT, L_KEY_DOCUMENT);
   
   CWnd* pWnd = GetDlgItem(IDC_BITMAPWND);
   //m_LBitmap.SetWndHandle(hWnd);*/
   m_LBitmap.EnableAutoScroll(FALSE);
   
   CRect rcRect;
   // Get the rectangle of the button
   pWnd->GetWindowRect(&rcRect);
   ScreenToClient(&rcRect);
   // Create the LBitmapWindow control, make it visible, and make it center the image
   HWND hWnd = m_LBitmap.CreateWnd(GetSafeHwnd(), 
                                   901, 
                                   WS_VISIBLE|L_BS_CENTER|WS_HSCROLL, 
                                   rcRect.TopLeft().x,
                                   rcRect.TopLeft().y,
                                   rcRect.BottomRight().x,
                                   rcRect.BottomRight().y);
   int nRet = 0;
   RECT rcClientArea;
   ANNRECT rcContainerRect;
   
   nRet = m_LBitmap.Load(TEXT("c:\\parrots.jpg"));
   
   if(nRet == SUCCESS)
   {
      ::GetClientRect(hWnd,&rcClientArea);
      m_LBitmap.SetDstRect(&rcClientArea);
      rcContainerRect.left = 0;
      rcContainerRect.top = 0;
      rcContainerRect.right = rcClientArea.right-rcClientArea.left;
      rcContainerRect.bottom = rcClientArea.bottom-rcClientArea.top;
      m_LeadAContainer.Create(hWnd,&rcContainerRect,TRUE);
      m_LeadAContainer.SetOffsetX((L_DOUBLE) 0, 0);
      m_LeadAContainer.SetOffsetY((L_DOUBLE) 0, 0);
   
      m_LeadAAutomation.Create();
 
      /* Assign the automation object to the container */
      m_LeadAAutomation.SetAutoContainer(&m_LeadAContainer);
      /* Enable the automation object */
      m_LeadAAutomation.SetActiveState(ANNACTIVE_ENABLED);
      /* Set design mode, which allows creation of annotations */
      m_LeadAContainer.SetUserMode();
      /* Set the dots per inch for interpreting physical measurements */
      m_LeadAContainer.SetDpiX(600, 0);
      m_LeadAContainer.SetDpiY(600, 0);
      /* Set the number of possible undo actions */
      m_LeadAAutomation.SetUndoDepth(3);
      /* Set the line tool as the initial annotation tool */
   
      m_LeadAToolbar.Create(this->GetSafeHwnd(), NULL, ANNTOOLALIGN_RIGHT | ANNTOOLALIGN_TOP, TRUE);
   
      m_LBitmap.SetContainer(&m_LeadAContainer);
      m_LBitmap.SetAutomation(&m_LeadAAutomation);
      m_LBitmap.SetToolBar(&m_LeadAToolbar);
   }
| 15. | Add a new class to the project as follows -- this class will be inherited from the LbitmapWindow class: | |
| 
 | a. | From the Insert menu, select New Class | 
| 
 | b. | In the Class Type combo box, select Generic class | 
| 
 | c. | In the Class name text box, specify CBitmapWindow | 
| 
 | d. | Click on "derived from" and type LBitmapWindow | 
| 
 | e. | Click the OK button. | 
| 16. | Add #include statements to your program so you can access the LEAD Class Library constants and classes: | |
| 
 | a. | In the Project Workspace, click the FileView tab. | 
| 
 | b. | Double-click the Automated files folder to open it. | 
| 
 | c. | Double-click the Header Files folder to open it. | 
| 
 | d. | Double-click the AutomatedDlg.h file to edit it. | 
| 
 | Add the following lines to the end of the file: | |
#include "BitmapWindow.h"
| 17. | Add the following Member Variables to the CBitmapWindow Class: | 
   LRESULT MsgProcCallBack(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
   L_VOID SetContainer(LAnnContainer * pContainer);
   L_VOID SetAutomation(LAnnAutomation * pAutomation);
   L_VOID SetToolBar(LAnnToolBar * pToolBar);
   
   L_VOID OnDraw(HDC hdc, RECT & Rect);
   
private:
      LAnnContainer* m_pContainer;
      LAnnAutomation *m_pAutomation;
      LAnnToolBar *m_pToolBar;
| 18. | Add implementation to the member method in CBitmapWindow class: | |
| 
 | a. | In the Project Workspace, click the FileView tab. | 
| 
 | b. | Double-click the Automated files folder to open it. | 
| 
 | c. | Double-click the Header files folder to open it. | 
| 
 | d. | Double-click the BitmapWindow.cpp file to edit it. | 
| 
 | e. | Add the following: | 
CBitmapWindow::CBitmapWindow()
{
   m_pContainer = NULL;
   m_pAutomation = NULL;
}
CBitmapWindow::~CBitmapWindow()
{
}
L_VOID CBitmapWindow::SetContainer(LAnnContainer * pContainer)
{
   m_pContainer = pContainer;
}
L_VOID CBitmapWindow::SetAutomation(LAnnAutomation * pAutomation)
{
   m_pAutomation = pAutomation;
}
L_VOID CBitmapWindow::SetToolBar(LAnnToolBar * pToolBar)
{
   m_pToolBar = pToolBar;
}
L_VOID CBitmapWindow::OnDraw (HDC hdc, RECT & Rect)
{
   LBitmapWindow::OnDraw(hdc, Rect);
   L_INT nRet;   
   if (m_pContainer != NULL)
   {      
      nRet = m_pContainer->Draw(hdc, &Rect);   
   }      
}
LRESULT CBitmapWindow::MsgProcCallBack(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
   switch (uMsg)
   {
   case WM_LTANNEVENT:
      if(m_pAutomation != NULL)
      {
   
            int uChecked = m_pToolBar->GetToolChecked() ;
            m_pAutomation->SetTool(uChecked);
      }
      break;
   };
   return LBitmapWindow::MsgProcCallBack(hWnd,uMsg,wParam,lParam);
}
| 19. | 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 CAutomatedDlg. | 
| 
 | c. | In the Messages list box, select WM_CLOSE. | 
| 
 | d. | Click the Add function button. Choose OK for the default function name (OnClose). | 
| 
 | e. | Click the Edit Code button and enter the following code: | 
   if (m_LBitmap.IsAllocated())
   {
      m_LBitmap.Free();
      m_LBitmap.SetContainer(NULL);
      m_LBitmap.SetAutomation(NULL);
      m_LBitmap.SetToolBar(NULL);
      m_LeadAAutomation.SetActiveState(ANNACTIVE_DISABLED);
      m_LeadAAutomation.Destroy ();
      m_LeadAContainer.Destroy();
      m_LeadAToolbar.Destroy();
   }
| 20. | On the main menu, select Build > Build Automated.exe to build the project. | 
| 21. | On the main menu, select Build > Execute Automated.exe to run the project. |