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 |
Start a new project as follows: Run Microsoft Visual Studio, select the File New Project, and do the following:
In the overview window Just click Next.
In the Application Type step dialog box, do the following:
In the Step 2 of 4 dialog box, do the following:
In the Step 3 of 4 dialog box, just click Finish:
Add #include statements to your program so you can access the LEAD C++ Class Library constants and classes:
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"
Add a static text control to the main window as follows:
Add #import statements to your program so you can access the Microsoft ActiveX Data Object 2.6 Library:
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;
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.
Do the following to add m_btnAddRecord to the CImageBlobDlg class and link the variable to the CButton control using dynamic data exchange:
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 |
Add the following Member Variables to the CImageBlobDlg class:
_ConnectionPtr m_pConnection;
_RecordsetPtr m_pRecordset;
LBitmapWindow m_LBitmapWnd;
Go to the OnInitDialog() function as follows:
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);
Do the following to add an event handler to the Connect To Database button:
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);
}
}
Do the following to add an event handler to the Disconnect From Data Base button:
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);
Do the following to add an event handler to the Add Record button:
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);
}
Do the following to add an event handler to the Delete Record button:
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);
}
}
Do the following to add an event handler to the Move Next button:
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();
}
Do the following to add an event handler to the Move Previous button:
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();
}
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();
Go to ImageBlobDlg.cpp file then add the following line between the BEGIN_MESSAGE_MAP and END_MESSAGE_MAP:
ON_WM_CLOSE()
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 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 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 image
m_LBitmapWnd.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_LBitmapWnd);
LBuffer LeadMemBuffer (pBuf,nSize);
nRet = LeadMemFile.Load(LeadMemBuffer,24,ORDER_BGR, NULL);
SafeArrayUnaccessData(varBLOB.parray);
}
}
}
Create a new file called Imports.cpp in place it beside your project files.
#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)
On the main menu, select Build -> Build ImageBlob.exe to build the project.
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