To start a project and add code that demonstrates adding images to or deleting images from the BLOB field of a database file:
First create a database file (DB1.MDB) with the fields listed below, before running this tutorial.
Field Name |
Type |
Image |
OleObject |
Size |
Number |
| 1. | Start a new project as follows: | |
| Run Microsoft Visual Studio, select the File New Project, and do the following: | ||
| a. | Expand Visual C++ tree, if it is not already expanded. | |
| b. | Select MFC from the sub tree. | |
| c. | Select MFC Application from the right window. | |
| d. | In the Project name text box, specify ImageBlob. | |
| e. | In the Location text box, specify the path of the project. | |
| f. | Click the OK button. | |
| 2. | In the overview window Just click Next. | |
| 3. | In the Application Type step dialog box, do the following: | |
| a. | Select Dialog based. | |
| b. | Use MFC in a shared DLL | |
| c. | Click the Next button. | |
| 4. | In the Step 2 of 4 dialog box, do the following: | |
| a. | Ensure that About Box is selected. | |
| b. | Ensure that System Menu is selected. | |
| c. | 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: | |
| a. | In the Project Workspace, click the Solution Explorer tab. | |
| b. | Double-click the ImageBlob Project 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" | 7. | Add a static text control to the main window as follows: | |
| a. | In the Project Workspace, click the ResourceView tab. | |
| b. | Double-click the ImageBlob.rc folder to open it. | |
| c. | Double-click the Dialog folder to open it. | |
| d. | Double-click IDD_IMAGEBLOB_DIALOG to design the form. | |
| e. | Select the TODO... text control; then press the Delete key to delete it. | |
| f. | 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. | |
| 8. | Add #import statements to your program so you can access the Microsoft ActiveX Data Object 2.6 Library: | |
| a. | In the Project Workspace, click the Solution Explorer tab. | |
| b. | Double-click the ImageBlob 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 .tlb files reside): | ||
#import <C:\\\\Windows\\\\system32\\\\msado26.tlb> rename("EOF", "ADOEOF")using namespace ADODB;
| 9. | Click the Resrouce 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. | ||
| 10. | Do the following to add m_btnAddRecord to the CImageBlobDlg class and link the variable to the CButton control using dynamic data exchange: | |
| a. | Open ImageBlob.rc and Double-click on IDD_IMAGEBLOB_DIALOG. | |
| b. | Right-click on the Add Record button, and choose Add Variable. | |
| c. | Specify m_btnAddRecord as the variable name, and Control as the category. | |
| d. | Click Finish to close the dialog box. | |
| 11. | 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 | |
| 12. | Add the following Member Variables to the CImageBlobDlg class: | |
| _ConnectionPtr | m_pConnection; | |
| _RecordsetPtr | m_pRecordset; | |
| LBitmapWindow | m_LBitmapWnd; | |
| 13. | Go to the OnInitDialog() function as follows: | |
| a. | From view menu, select Class view. | |
| b. | In the Project Workspace, click the ClassView tab. | |
| c. | Double-click the ImageBlob folder to open it. | |
| d. | Click on the CImageBlobDlg class. | |
| e. | Double-click the OnInitDialog()function in the lower window to edit it. | |
| 14. |
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);RECT rc;GetDlgItem(IDC_STATIC)->GetWindowRect(&rc);ScreenToClient(&rc);HWND hWnd = m_LBitmapWnd.CreateWnd(this->GetSafeHwnd(),0,WS_VISIBLE|L_BS_CENTER|L_BS_PROCESSKEYBOARD,rc.left ,rc.top ,rc.right ,rc.bottom );m_LBitmapWnd.EnableAutoScroll(TRUE);m_LBitmapWnd.SetFileName (MAKE_IMAGE_PATH(TEXT("image1.cmp")));int nRet = m_LBitmapWnd.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);
| 15. | Do the following to add an event handler to the Connect To Database button: | |
| a. | Open ImageBlob.rc and Double-click on IDD_IMAGEBLOB_DIALOG. | |
| b. | Right-click on the Connect To Database button, and choose Add Event Handler. | |
| c. | From the Message Type List, choose BN_CLICKED. | |
| d. | 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);}}
| 16. | Do the following to add an event handler to the Disconnect From Data Base button: | |
| a. | Open ImageBlob.rc and Double-click on IDD_IMAGEBLOB_DIALOG. | |
| b. | Right-click on the Disconnect From Data Base button, and choose Add Event Handler. | |
| c. | From the Message Type List, choose BN_CLICKED. | |
| d. | 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);
| 17. | Do the following to add an event handler to the Add Record button: | |
| a. | Open ImageBlob.rc and Double-click on IDD_IMAGEBLOB_DIALOG. | |
| b. | Right-click on the Add Record button, and choose Add Event Handler. | |
| c. | From Message Type List, choose BN_CLICKED. | |
| d. | 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_LBitmapWnd);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);}
| 18. | Do the following to add an event handler to the Delete Record button: | |
| a. | Open ImageBlob.rc and Double-click on IDD_IMAGEBLOB_DIALOG. | |
| b. | Right-click on the Delete Record button, and choose Add Event Handler. | |
| c. | From the Message Type List, choose BN_CLICKED. | |
| d. | 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);}}
| 19. | Do the following to add an event handler to the Move Next button: | |
| a. | Open ImageBlob.rc and Double-click on IDD_IMAGEBLOB_DIALOG. | |
| b. | Right-click on the Move Next button, and choose Add Event Handler. | |
| c. | From the Message Type List, choose BN_CLICKED. | |
| d. | 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();}
| 20. | Do the following to add an event handler to the Move Previous button: | |
| a. | Open ImageBlob.rc and Double-click on IDD_IMAGEBLOB_DIALOG. | |
| b. | Right-click on the Move Previous button, and choose Add Event Handler. | |
| c. | From the Message Type List, choose BN_CLICKED. | |
| d. | 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();}
21. |
Go to ImageBlobDlg.h file then add the following function declarations: |
afx_msg void OnClose();void BlobToVariant(VARIANT &varArray, BYTE* pData, LONG lSize);void ReadImage();
22. |
Go to ImageBlobDlg.cpp file then add the following line between the BEGIN_MESSAGE_MAP and END_MESSAGE_MAP: ON_WM_CLOSE() |
23. |
Add the following functions to ImageBlobDlg.cpp: |
void CImageBlobDlg::OnClose(){if (m_LBitmapWnd.IsAllocated()){m_LBitmapWnd.Free();}LBase::UnloadLibraries(LT_KRN);LBase::UnloadLibraries(LT_DIS);LBase::UnloadLibraries(LT_FIL);CoInitialize(NULL);CDialog::OnClose();}void CImageBlobDlg::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 arraypsa = SafeArrayCreate(VT_I1, 1, rgsabound);// set the data of the array with data in the edit boxif(SafeArrayAccessData(psa,(void **)&pByte) == NOERROR)memcpy((LPVOID)pByte, (LPVOID)pData, lSize);SafeArrayUnaccessData(psa);varArray.vt = VT_ARRAY | VT_UI1;varArray.parray = psa;}void CImageBlobDlg::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 imagem_LBitmapWnd.Free();MessageBox(TEXT("old image freed"));if(nSize){_variant_t varBLOB;VariantInit(&varBLOB);// get the chunk of datavarBLOB = 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_LBitmapWnd);LBuffer LeadMemBuffer (pBuf,nSize);nRet = LeadMemFile.Load(LeadMemBuffer,24,ORDER_BGR, NULL);SafeArrayUnaccessData(varBLOB.parray);}}}
| 24. | Create a new file called Imports.cpp in place it beside your project files. | |
| a. | In the Project Workspace, click the Solution Explorer tab. | |
| b. | Double-click the ImageBlob folder to open it. | |
| c. | Right-click the Source files folder and select Add New item. | |
| d. | Right-click on the Source file | |
| e. | Expand Visual C++ tree, if it is not already expanded. | |
| f. | Select Code from the sub tree. | |
| g. | Select C++ File (.cpp) from the right window. | |
| h. | In the name text box, specify Imports. | |
| i. | Click the OK button. | |
| j. | Double-click the import.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\\CDLLVC10\\x64\\Ltwvc_x.lib")#else#pragma comment(lib, "..\\..\\..\\..\\..\\Lib\\CDLLVC10\\Win32\\Ltwvc_u.lib")#endif // #if defined(WIN64)
25. |
On the main menu, select Build > Build ImageBlob.exe to build the project. |
26. |
On the main menu, select Build > Execute ImageBlob.exe to run the project. |
Help Collections
Raster .NET | C API | C++ Class Library | HTML5 JavaScript
Document .NET | C API | C++ Class Library | HTML5 JavaScript
Medical .NET | C API | C++ Class Library | HTML5 JavaScript
Medical Web Viewer .NET
Multimedia
Direct Show .NET | C API | Filters
Media Foundation .NET | C API | Transforms
Supported Platforms
.NET, Java, Android, and iOS/macOS Assemblies
Imaging, Medical, and Document
C API/C++ Class Libraries
Imaging, Medical, and Document
HTML5 JavaScript Libraries
Imaging, Medical, and Document
