Click here to Skip to main content
15,902,189 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more: , +
I am creating a dialog based application in mfc.
I have two button and one picture control.
I want to save and retrieve bmp into(from) ms access 2007.
In database, I have field(picture,OLE Object)
In save button click
C++
CDaoDatabase* m_database= new CDaoDatabase();
m_database->Open(L"C:\\Users\\ABC\\ABC.mdb",TRUE,FALSE,L"");
if(m_database->IsOpen())
{
    CString strSQL =_T("SELECT picture FROM Table2");
    CDaoRecordset m_reordset(m_database);
    m_reordset.Open(AFX_DAO_USE_DEFAULT_TYPE,strSQL,0);
    int iRecords =m_reordset.GetRecordCount();
    //CLongBinary bin1;
    if (!iRecords)
    {
        m_reordset.AddNew();
        CPictureHolder pic;
        CBitmap bmp;
        bmp. LoadBitmap (IDB_BITMAP1);

        if (pic.CreateFromBitmap (&bmp))
        {
            IStream* pStream;
            CreateStreamOnHGlobal (NULL, TRUE, &pStream);
            if (pStream)
            {
                LONG sz;
                pic.m_pPict-> SaveAsFile (pStream, TRUE, &sz);

                HGLOBAL hGlobal;
                GetHGlobalFromStream (pStream, &hGlobal);

                CByteArray barray;
                CLongBinary bin;
                bin.m_dwDataLength = GlobalSize (hGlobal);
                bin.m_hData = hGlobal;
                m_reordset.SetFieldValue (_T("picture"), COleVariant (bin));//Register "long binary data"
            }
            m_reordset.Update();
        }
    }
    m_database->Close();

picture field is showing "Long binary data".
In retrieve button click
C++
    CDaoDatabase* m_database= new CDaoDatabase();
COleVariant valuer;
m_database->Open(L"C:\\Users\\ABC\\ABC.mdb",TRUE,FALSE,L"");
if(m_database->IsOpen())
{
    CString strSQL =_T("SELECT picture FROM Table2");
    CBitmap ABitmap;
    BITMAP bm;
    CDaoRecordset m_reordset(m_database);
    m_reordset.Open(AFX_DAO_USE_DEFAULT_TYPE,strSQL,0);
    int iRecords =m_reordset.GetRecordCount();
    valuer=m_reordset.GetFieldValue(0);
    //Retrieve size of array
    u_long pcBufLen =valuer.parray->rgsabound[0].cElements;
    BYTE    *ppBuf = new BYTE[pcBufLen]; //Allocate a buffer to store the data
    BYTE *tmp= NULL;
    if( valuer.vt!=VT_NULL)
    {
        void* pArrayData;
        CByteArray Photo;
        const void* lpbits;
        Photo.SetSize(pcBufLen);

        SafeArrayAccessData(valuer.parray,&pArrayData);

        memcpy(Photo.GetData(),pArrayData,Photo.GetSize());

        memcpy(&bm,pArrayData,sizeof(BITMAP));


        HDC hdc,hdcMem;
        HWND hh=::GetDlgItem(GetSafeHwnd(),IDC_pic);
        hdc = ::GetWindowDC(hh);
        HBITMAP hBitmap=NULL;
        hdcMem  = ::CreateCompatibleDC(hdc);


        SelectObject(hdcMem,::CreateBitmap(bm.bmWidth,bm.bmHeight,bm.bmPlanes,bm.bmBitsPixel,bm.bmBits));
        int res=BitBlt(hdc, 0,0, bm.bmWidth, bm.bmHeight,hdcMem,0,0,SRCCOPY);


        hBitmap=CreateCompatibleBitmap(hdc,100,100);

        HBITMAP t=m_nHeight.SetBitmap(hBitmap);
        DeleteDC(hdcMem );

        SafeArrayUnaccessData(valuer.parray);
    }
    m_database->Close();

m_nHeight is CStatic class for IDC_pic control
CSS
value of t is 0x00000000 {unused=??? }

and

bm.bmType=137776450

bm.bmWidth=7

bm.bmHeight=3538944

bm.bmWidthBytes=2621440

bm.bmPlanes=0

bm.bmBitsPixel=320

bm.bmBits=0x01e00000

I am not getting image on picture control, its getting black screen.
 I think problem is in bm.bmPlanes.

Help me!
Posted
Updated 30-Nov-12 0:16am
v4

1 solution

Please observe :) :
C++
void GetImage(VARIANT& val)
{
  CImage img;
  img.LoadFromResource(::AfxGetInstanceHandle(), IDB_BITMAP1);
  COleStreamFile file;
  if (file.CreateMemoryStream()) {
    IStream* pStream(file.GetStream());
    if (pStream &&
        S_OK == cViewImage.Save(pStream, ImageFormatPNG)) {
      file.SeekToBegin();
      UINT uiLen(static_cast<UINT>(file.GetLength()));

      CByteArray arRowData;
      arRowData.SetSize(static_cast<INT_PTR>(uiLen));
      file.Read(arRowData.GetData(), uiLen);

      CD_CSafeArray arPngDump; // just an incapsulation of the SAFEARRAY
      arPngDump.CreateOneDim(VT_UI1, uiLen, arRowData.GetData());
      val = arPngDump.Detach();
    }
  }
  file.Close();
}

void TestBackDbDump(CD_CSafeArray& arPngDump)
{
  COleStreamFile file;
  if (file.CreateMemoryStream()) {
    IStream* pStream(file.GetStream());
    if (pStream) {
      UINT uiLen(static_cast<UINT>(arPngDump.GetLength()));

      CByteArray arRowData;
      arRowData.SetSize(static_cast<INT_PTR>(uiLen));
      arPngDump.Read(arRowData.GetData(), uiLen); // Access/Unaccess inside...
      file.Write(arRowData.GetData(), uiLen); // The data is now in the stream...
      file.SeekToBegin();

      CImage img;
      im.Load(pStream);
      img.Save(_T("d:\\last_test.png"), ImageFormatPNG); // yes, we hope :)
    }
  }
  file.Close();
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900