Loading and Saving Annotations Using Databases (C++ 5.0 and later)

To start a project and add code that demonstrates adding annotation objects to or deleting annotation objects from the BLOB field of a database file:

First create a database file (in this case, named D:\TEMP\DB1.MDB) with one table named Images and with the fields listed below:

Field Name Type
Image Binary
Size Number

Start a new project as follows:

  1. Run Microsoft Visual Studio, select the File New Project, and do the following:

    1. Expand Visual C++ tree, if it is not already expanded.
    2. Select MFC from the sub tree.
    3. Select MFC Application from the right window.
    4. In the Project name text box, specify AnnBlob.
    5. In the Location text box, specify the path of the project.
    6. Click the OK button.
  2. In the overview window Just click Next.

  3. In the Application Type step dialog box, do the following:

    1. Select Dialog based.
    2. Use MFC in a shared DLL.
    3. Click the Next button.
  4. In the Step 2 of 4 dialog box, do the following:

    1. Ensure that About Box is selected.
    2. Ensure that System Menu is selected.
    3. Click the Next button.
  5. In the Step 3 of 4 dialog box, just click Finish:

  6. Add #include statements to your program so you can access the LEAD C++ Class Library constants and classes:

    1. In the Project Workspace, click the Solution Explorer tab.
    2. Double-click the AnnBlob Project folder to open it.
    3. Double-click the Header Files folder to open it.
    4. Double-click the StdAfx.h file to edit it.
  7. 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:

    1. In the Project Workspace, click the ResourceView tab.
    2. Double-click the AnnBlob.rc folder to open it.
    3. Double-click the Dialog folder to open it.
    4. Double-click IDD_IMAGEBLOB_DIALOG to design the form.
    5. Select the TODO... text control; then press the Delete key to delete it.
    6. Click the Static Text control icon, add a control to the dialog, then size and position the control as you want it to appear at run time.
  9. Add #import statements to your program so you can access the Microsoft ActiveX Data Object 2.6 Library:

    1. In the Project Workspace, click the Solution Explorer tab.
    2. Double-click the AnnBlob folder to open it.
    3. Double-click the Header Files folder to open it.
    4. Double-click the StdAfx.h file to edit it.
  10. Add the following lines to the end of the file (keep in mind, you may have to change the path to where the .tlb files reside):

    #import <C:\\Windows\\system32\\msado26.tlb> rename("EOF", "ADOEOF")   
    using namespace ADODB; 

  11. Click the Resource View tab. On the View menu, select ToolBox, and then add six command buttons to your form and name them as follows:

    ID Caption
    IDC_CONNECT &Connect To Database
    IDC_DISCONNECT &Disconnect From Database
    IDC_ADDRECORD &Add Record
    IDC_DELETERECORD D&elete Record
    IDC_MOVENEXT Move &Next
    IDC_MOVEPREVIOUS Move &Previous

    Save the resource file.

  12. Do the following to add m_btnAddRecord to the CAnnBlobDlg class and link the variable to the CButton control using dynamic data exchange:

    1. Open AnnBlob.rc and Double-click on IDD_IMAGEBLOB_DIALOG.
    2. Right-click on the Add Record button, and choose Add Variable.
    3. Specify m_btnAddRecord as the variable name, and Control as the category.
    4. Click Finish to close the dialog box.
  13. Repeat step 11 for the other buttons, using the following variable names:

    ID Member Variable Name
    IDC_MOVEPREVIOUS m_btnMovePrevious
    IDC_MOVENEXT m_btnMoveNext
    IDC_DISCONNECT m_btnDisconnect
    IDC_DELETERECORD m_btnDeleteRecord
    IDC_CONNECT m_btnConnect
  14. Add the following Member Variables to the CAnnBlobDlg class:

    Type Member
    _ConnectionPtr m_pConnection
    _RecordsetPtr m_pRecordset
    LAnnotationWindow m_LAnnoWnd
  15. Go to the OnInitDialog() function as follows:

    1. From view menu, select Class view.
    2. In the Project Workspace, click the ClassView tab.
    3. Double-click the AnnBlob folder to open it.
    4. Click on the CAnnBlobDlg class.
    5. Double-click the OnInitDialog()function in the lower window to edit it.
  16. Edit the OnInitDialog() function to add the following code after the line that says //TODO: Add extra initialization here:

    LBase::LoadLibraries(LT_KRN); 
    LBase::LoadLibraries(LT_DIS); 
    LBase::LoadLibraries(LT_FIL); 
    LBase::LoadLibraries(LT_ANN); 
    L_TCHAR * pszLicenseFile = L"Replace this with the path to the LEADTOOLS license file"; 
    L_TCHAR * pszDeveloperKey = L"Replace this with your developer key"; 
    LSettings::SetLicenseFile(pszLicenseFile, pszDeveloperKey); 
    RECT rc; 
     
    GetDlgItem(IDC_STATIC)->GetWindowRect(&rc); 
    ScreenToClient(&rc); 
    HWND hWnd = m_LAnnoWnd.CreateWnd(this->GetSafeHwnd(),0, WS_VISIBLE|L_BS_CENTER| L_BS_PROCESSKEYBOARD, rc.left, rc.top, rc.right, rc.bottom); 
     
    if (!m_LAnnoWnd.GetToolBar().IsCreated()) 
       m_LAnnoWnd.GetToolBar().Create(hWnd, NULL, ANNTOOLALIGN_RIGHT | ANNTOOLALIGN_TOP, TRUE, NULL, NULL); 
     
    m_LAnnoWnd.EnableAutoScroll(TRUE); 
    m_LAnnoWnd.SetFileName (MAKE_IMAGE_PATH(TEXT("image1.cmp"))); 
    int nRet = m_LAnnoWnd.Load (0,ORDER_BGR, 1); 
    HRESULT hr; 
    CoInitialize(NULL); 
    hr = m_pConnection.CreateInstance(__uuidof( Connection)); 
    m_pRecordset.CreateInstance(__uuidof(Recordset)); 
    m_btnMoveNext.EnableWindow(FALSE); 
    m_btnMovePrevious.EnableWindow(FALSE); 
    m_btnAddRecord.EnableWindow(FALSE); 
    m_btnDeleteRecord.EnableWindow(FALSE); 

  17. Do the following to add an event handler to the Connect To Database button:

    1. Open AnnBlob.rc and Double-click on IDD_IMAGEBLOB_DIALOG.
    2. Right-click on the Connect To Database button, and choose Add Event Handler.
    3. From the Message Type List, choose BN_CLICKED.
    4. Click the Add and Edit button to close the dialog box, then enter the following code:
      HRESULT hr; 
      _bstr_t bstrConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=d:\\temp\\DB1.mdb;"); 
      _bstr_t bstrQuery("SELECT * FROM Images"); 
      _variant_t vNull; 
      vNull.vt = VT_ERROR; 
      vNull.scode = DISP_E_PARAMNOTFOUND; 
      if (m_pConnection->State == adStateClosed) 
      { 
         hr = m_pConnection->Open( bstrConnection, _bstr_t(L""), _bstr_t(L""), adModeUnknown ); 
      } 
       
      if (SUCCEEDED(hr)) 
      { 
         m_pRecordset->PutRefActiveConnection(m_pConnection); 
         hr = m_pRecordset->Open(_variant_t(bstrQuery), vNull, adOpenKeyset, adLockOptimistic, adCmdText); 
       
         if (SUCCEEDED(hr)) 
         { 
            if(!m_pRecordset->GetBOF()) 
            { 
               m_pRecordset->MoveFirst(); 
            } 
             
            if (!m_pRecordset->GetADOEOF()) 
            { 
               m_btnMoveNext.EnableWindow(TRUE); 
               m_btnMovePrevious.EnableWindow(TRUE); 
               m_btnDeleteRecord.EnableWindow(TRUE); 
            } 
             
            m_btnAddRecord.EnableWindow(TRUE); 
         } 
      } 
  18. Do the following to add an event handler to the Disconnect From Data Base button:

    1. Open AnnBlob.rc and Double-click on IDD_IMAGEBLOB_DIALOG.
    2. Right-click on the Disconnect From Data Base button, and choose Add Event Handler.
    3. From the Message Type List, choose BN_CLICKED.
    4. Click the Add and Edit button to close the dialog box, then enter the following code:
      if (m_pConnection->State == adStateOpen) 
      { 
         m_pConnection->Close(); 
      } 
       
      if (m_pRecordset->State == adStateOpen ) 
      { 
         m_pRecordset->Close(); 
      } 
       
      m_btnMoveNext.EnableWindow(FALSE); 
      m_btnMovePrevious.EnableWindow(FALSE); 
      m_btnAddRecord.EnableWindow(FALSE); 
      m_btnDeleteRecord.EnableWindow(FALSE); 
  19. Do the following to add an event handler to the Add Record button:

    1. Open AnnBlob.rc and Double-click on IDD_IMAGEBLOB_DIALOG.
    2. Right-click on the Add Record button, and choose Add Event Handler.
    3. From the Message Type List, choose BN_CLICKED.
    4. Click the Add and Edit button to close the dialog box, then enter the following code:
      L_SIZE_T nSize; 
      int nRet; 
      LMemoryFile LeadMemFile; 
      LBuffer LeadMemBuffer; 
       
      if (m_pConnection->State == adStateClosed ) 
      { 
         MessageBox (TEXT("Connection closed")); 
         return; 
      } 
       
      LeadMemFile.SetBitmap((LBitmapBase *) &m_LAnnoWnd); 
      nRet = LeadMemFile.Save(&LeadMemBuffer,FILE_LEAD,24,QS); 
      nSize = LeadMemBuffer.GetSize(); 
      BYTE * pData = (BYTE *)LeadMemBuffer.Lock(); 
       
      VARIANT varBLOB; 
      BlobToVariant(varBLOB, pData, (LONG)nSize); 
      LeadMemBuffer.Unlock(); 
      LeadMemBuffer.Free(); 
       
      m_pRecordset->AddNew(); 
      m_pRecordset->Fields->Item[0L]->AppendChunk(varBLOB); 
      m_pRecordset->Fields->Item[1L]->PutValue((LONG)nSize); 
      m_pRecordset->Update(); 
      VariantClear(&varBLOB); 
      if(m_pRecordset->RecordCount >= 0) 
      { 
         m_btnMoveNext.EnableWindow(TRUE); 
         m_btnMovePrevious.EnableWindow(TRUE); 
         m_btnDeleteRecord.EnableWindow(TRUE); 
      } 
  20. Do the following to add an event handler to the Delete Record button:

    1. Open AnnBlob.rc and Double-click on IDD_IMAGEBLOB_DIALOG.
    2. Right-click on the Delete Record button, and choose Add Event Handler.
    3. From the Message Type List, choose BN_CLICKED.
    4. Click the Add and Edit button to close the dialog box, then enter the following code:
      if (m_pConnection->State == adStateClosed) 
      { 
         MessageBox (TEXT("Connection closed")); 
         return; 
      } 
       
      if (!m_pRecordset->GetBOF() || !m_pRecordset->GetADOEOF()) 
      { 
         m_pRecordset->MoveLast(); 
         m_pRecordset->Delete(adAffectCurrent); 
         m_pRecordset->Update(); 
         if(m_pRecordset->RecordCount <= 0) 
         { 
            m_btnMoveNext.EnableWindow(FALSE); 
            m_btnMovePrevious.EnableWindow(FALSE); 
            m_btnDeleteRecord.EnableWindow(FALSE); 
         } 
      } 
  21. Do the following to add an event handler to the Move Next button:

    1. Open AnnBlob.rc and Double-click on IDD_IMAGEBLOB_DIALOG.
    2. Right-click on the Move Next button, and choose Add Event Handler.
    3. From the Message Type List, choose BN_CLICKED.
    4. Click the Add and Edit button to close the dialog box, then enter the following code:
      if (m_pConnection->State == adStateClosed) 
      { 
         MessageBox (TEXT("Connection closed")); 
         return; 
      } 
       
      if (!m_pRecordset->GetADOEOF()) 
      { 
         m_pRecordset->MoveNext(); 
      } 
       
      if (m_pRecordset->GetADOEOF()) 
      { 
         MessageBox(TEXT("Unable to get the Image from db")); 
         m_pRecordset->MovePrevious(); 
      } 
      else 
      { 
         ReadImage(); 
      } 
  22. Do the following to add an event handler to the Move Previous button:

    1. Open AnnBlob.rc and Double-click on IDD_IMAGEBLOB_DIALOG.
    2. Right-click on the Move Previous button, and choose Add Event Handler.
    3. From the Message Type List, choose BN_CLICKED.
    4. Click the Add and Edit button to close the dialog box, then enter the following code:
      if (m_pConnection->State == adStateClosed) 
      { 
         MessageBox (TEXT("Connection closed")); 
         return; 
      } 
       
      if (!m_pRecordset->GetBOF()) 
      { 
         m_pRecordset->MovePrevious(); 
      } 
       
      if (m_pRecordset->GetBOF()) 
      { 
         MessageBox(TEXT("Unable to get the Image from db")); 
         m_pRecordset->MoveNext(); 
      } 
      else 
      { 
         ReadImage(); 
      } 
  23. Go to AnnBlobDlg.h file then add the following function declarations:

    afx_msg void OnClose(); 
    void BlobToVariant(VARIANT &varArray, BYTE* pData, LONG lSize); 
    void ReadImage(); 

  24. Go to AnnBlobDlg.cpp file then add the following line between the BEGIN_MESSAGE_MAP and END_MESSAGE_MAP:

    ON_WM_CLOSE() 

  25. Add the following functions to AnnBlobDlg.cpp:

    void CAnnBlobDlg::OnClose() 
    { 
       if (m_LAnnoWnd.IsAllocated()) 
       { 
          m_LAnnoWnd.Free(); 
       } 
       LBase::UnloadLibraries(LT_KRN); 
       LBase::UnloadLibraries(LT_DIS); 
       LBase::UnloadLibraries(LT_FIL); 
       LBase::UnloadLibraries(LT_ANN); 
       CoInitialize(NULL); 
       CDialog::OnClose(); 
    } 
     
    void CAnnBlobDlg::BlobToVariant(VARIANT &varArray, BYTE* pData, LONG lSize) 
    { 
       BYTE *pByte; 
       SAFEARRAY FAR* psa; 
       SAFEARRAYBOUND rgsabound[1]; 
       rgsabound[0].lLbound = 0; 
       rgsabound[0].cElements = lSize; 
        
       // create a single dimensional byte array 
       psa = SafeArrayCreate(VT_I1, 1, rgsabound); 
        
       // set the data of the array with data in the edit box 
       if(SafeArrayAccessData(psa,(void **)&pByte) == NOERROR) 
          memcpy((LPVOID)pByte, (LPVOID)pData, lSize); 
     
       SafeArrayUnaccessData(psa); 
        
       varArray.vt = VT_ARRAY | VT_UI1; 
       varArray.parray = psa; 
    } 
     
    void CAnnBlobDlg::ReadImage() 
    { 
       LONG nSize; 
       BYTE * pData = NULL; 
       LMemoryFile LeadMemFile; 
       int nRet; 
       _variant_t varSize; 
       varSize = m_pRecordset->Fields->Item[1L]->Value; 
       nSize = varSize.intVal; 
        
       //free old image 
       m_LAnnoWnd.Free(); 
       MessageBox(TEXT("old image freed")); 
        
       if(nSize) 
       { 
          _variant_t varBLOB; 
          VariantInit(&varBLOB); 
          // get the chunk of data 
          varBLOB = m_pRecordset->Fields->Item[0L]->GetChunk(nSize); 
          pData =(BYTE *) malloc(nSize); 
          memset(pData,0,nSize); 
           
          if(varBLOB.vt == (VT_ARRAY | VT_UI1)) 
          { 
             BYTE *pBuf = NULL; 
             SafeArrayAccessData(varBLOB.parray,(void **)&pBuf); 
             LeadMemFile.SetBitmap((LBitmapBase *)& m_LAnnoWnd); 
             LBuffer LeadMemBuffer (pBuf,nSize); 
             nRet = LeadMemFile.Load(LeadMemBuffer,24,ORDER_BGR, NULL); 
             SafeArrayUnaccessData(varBLOB.parray); 
          } 
       } 
    } 

  26. Create a new file called Imports.cpp in place it beside your project files.

    1. In the Project Workspace, click the Solution Explorer tab.
    2. Double-click the AnnBlob folder to open it.
    3. Right-click the Source files folder and select Add New item.
    4. Right-click on the Source file.
    5. Expand Visual C++ tree, if it is not already expanded.
    6. Select Code from the sub tree.
    7. Select C++ File (.cpp) from the right window.
    8. In the name text box, specify Imports.
    9. Click the OK button.
    10. Double-click the Imports.cpp in the Solution Explorer and add the following lines(Keep in mind, you may have to change the path to where the Libraries files reside):
      #include "StdAfx.h" 
        
      #if defined(WIN64) 
         #pragma comment(lib, "..\\..\\..\\..\\..\\Lib\\CDLL\\x64\\Ltwvc_x.lib") 
      #else 
         #pragma comment(lib, "..\\..\\..\\..\\..\\Lib\\CDLL\\Win32\\Ltwvc_u.lib") 
      #endif // #if defined(WIN64) 
  27. On the main menu, select Build -> Build AnnBlob.exe to build the project.

  28. On the main menu, select Build -> Execute AnnBlob.exe to run the project.

Help Version 22.0.2023.2.2
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2023 LEAD Technologies, Inc. All Rights Reserved.

LEADTOOLS Raster Imaging C++ Class Library Help

Products | Support | Contact Us | Intellectual Property Notices
© 1991-2023 LEAD Technologies, Inc. All Rights Reserved.