Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Просмотр картинок из DB Access

7.3K
29 сентября 2005 года
LamerMFC
48 / / 17.09.2005
Всем доброго времени суток!

У меня есть таблица в которой следующие поля:
1) ID
2) name
3) surname
4) photo

к базе данных подключаюсь следующим образом

CDatabase db;
CRecordset* rs;

db.OpenEx("DBQ=Base//Patient.mdb;Driver={Microsoft Access Driver (*.mdb)}");
rs = new CRecordset(&db);

далее выбираю данные из таблицы:

CDBVariant dbv;
CString str;
str.Format(“SELECT * FROM people WHERE id =1”);
rs->Open(CRecorset::snapshot, str);
rs->GetFieldValue(“surname”, str);
rs->GetFieldValue(“photo”, dbv);
rs->Close();

с фамилией все просто, а вот с фотографией проблемы. В общем залез я в поиск и нашел кучу примеров но ничего не понял, как то там все сильно расплывчато, да я и сам не блещу талантами. Единственное что я понял, так это то, что в dbv-> m_pbinary.m_hData хранится двоичный код изображения типа HGLOBAL, а в dbv-> m_pbinary. m_dwDataLength хранится его размер. Теперь моя задача преобразовать HGLOBAL в HBITMAP. Как это сделать я не знаю. Помогите пожалуйста.
7.3K
30 сентября 2005 года
LamerMFC
48 / / 17.09.2005
неужели никто не знает как из HGLOBAL получить HBITMAP???????
7.3K
01 октября 2005 года
LamerMFC
48 / / 17.09.2005
Цитата:
Originally posted by LamerMFC
неужели никто не знает как из HGLOBAL получить HBITMAP???????



там еще что то про LockResource упоминалось

406
01 октября 2005 года
vitaly2003s
481 / / 27.07.2004
Цитата:
Originally posted by LamerMFC
там еще что то про LockResource упоминалось


попробуй так:

main()
{
HBITMAP hbm=DIBToDDB(dbv->m_pbinary.m_hData);
}

или так:

main()
{
LPVOID lpv=LockResource(dbv->m_pbinary.m_hData);
HBITMAP hbm=DIBToDDB(lpv);
}

HBITMAP DIBToDDB( HANDLE hDIB )
{
LPBITMAPINFOHEADER lpbi;
HBITMAP hbm;
HPALETTE pal;
HPALETTE* pOldPal;
HDC hdch;

if (hDIB == NULL)
return NULL;
hdch=GetDC(NULL);

lpbi = (LPBITMAPINFOHEADER)hDIB;

int nColors = lpbi->biClrUsed ? lpbi->biClrUsed :
1 << lpbi->biBitCount;

BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
LPVOID lpDIBBits;
if( bmInfo.bmiHeader.biBitCount > 8 )
lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors +
bmInfo.bmiHeader.biClrUsed) +
((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
else
lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);

// Create and select a logical palette if needed
if( nColors <= 256 && GetDeviceCaps(hdch,RASTERCAPS) & RC_PALETTE)
{
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];

pLP->palVersion = 0x300;
pLP->palNumEntries = nColors;

for( int i=0; i < nColors; i++)
{
pLP->palPalEntry.peRed = bmInfo.bmiColors.rgbRed;
pLP->palPalEntry.peGreen = bmInfo.bmiColors.rgbGreen;
pLP->palPalEntry.peBlue = bmInfo.bmiColors.rgbBlue;
pLP->palPalEntry.peFlags = 0;
}

pal=CreatePalette( pLP );

delete[] pLP;

// Select and realize the palette
pOldPal =(HPALETTE*) SelectPalette(hdch, pal, FALSE );
RealizePalette(hdch);
}


hbm = CreateDIBitmap(hdch, // handle to device context
(LPBITMAPINFOHEADER)lpbi, // pointer to bitmap info header
(LONG)CBM_INIT, // initialization flag
lpDIBBits, // pointer to initialization data
(LPBITMAPINFO)lpbi, // pointer to bitmap info
DIB_RGB_COLORS ); // color-data usage


SelectPalette(hdch,(HPALETTE)pOldPal,FALSE);
DeleteDC(hdch);
return hbm;
}

7.3K
01 октября 2005 года
LamerMFC
48 / / 17.09.2005
Цитата:
Originally posted by vitaly2003s
попробуй так:

main()
{
HBITMAP hbm=DIBToDDB(dbv->m_pbinary.m_hData);
}

или так:

main()
{
LPVOID lpv=LockResource(dbv->m_pbinary.m_hData);
HBITMAP hbm=DIBToDDB(lpv);
}

HBITMAP DIBToDDB( HANDLE hDIB )
{
LPBITMAPINFOHEADER lpbi;
HBITMAP hbm;
HPALETTE pal;
HPALETTE* pOldPal;
HDC hdch;

if (hDIB == NULL)
return NULL;
hdch=GetDC(NULL);

lpbi = (LPBITMAPINFOHEADER)hDIB;

int nColors = lpbi->biClrUsed ? lpbi->biClrUsed :
1 << lpbi->biBitCount;

BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
LPVOID lpDIBBits;
if( bmInfo.bmiHeader.biBitCount > 8 )
lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors +
bmInfo.bmiHeader.biClrUsed) +
((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
else
lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);

// Create and select a logical palette if needed
if( nColors <= 256 && GetDeviceCaps(hdch,RASTERCAPS) & RC_PALETTE)
{
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];

pLP->palVersion = 0x300;
pLP->palNumEntries = nColors;

for( int i=0; i < nColors; i++)
{
pLP->palPalEntry.peRed = bmInfo.bmiColors.rgbRed;
pLP->palPalEntry.peGreen = bmInfo.bmiColors.rgbGreen;
pLP->palPalEntry.peBlue = bmInfo.bmiColors.rgbBlue;
pLP->palPalEntry.peFlags = 0;
}

pal=CreatePalette( pLP );

delete[] pLP;

// Select and realize the palette
pOldPal =(HPALETTE*) SelectPalette(hdch, pal, FALSE );
RealizePalette(hdch);
}


hbm = CreateDIBitmap(hdch, // handle to device context
(LPBITMAPINFOHEADER)lpbi, // pointer to bitmap info header
(LONG)CBM_INIT, // initialization flag
lpDIBBits, // pointer to initialization data
(LPBITMAPINFO)lpbi, // pointer to bitmap info
DIB_RGB_COLORS ); // color-data usage


SelectPalette(hdch,(HPALETTE)pOldPal,FALSE);
DeleteDC(hdch);
return hbm;
}





почему то не работает

пишу

m_hBitmap = LoadBitmap(GetModuleHandle(NULL), (LPCTSTR)IDB_BITMAP1);

все отлично, а если

m_hBitmap = DIBToDDB(m_varValue.m_pbinary->m_hData);

ничего не работает

может это из-за того, что я не правильно вывожу битмап, хотя в первом случае битмап выводится, вот ф-ция с помощью которой я вывожу картинку

void DrawBitmap(CDC& dc, HBITMAP bmp, int x, int y)
{
CDC memdc;
BITMAP bm;

GetObject(bmp, sizeof(BITMAP), &bm);
memdc.m_hDC = CreateCompatibleDC(dc.m_hDC);
SelectObject(memdc.m_hDC, bmp);

dc.BitBlt(x, y, bm.bmWidth, bm.bmHeight, &memdc, 0, 0, SRCCOPY);
}

406
01 октября 2005 года
vitaly2003s
481 / / 27.07.2004
Может формат в бинарнике совсем не тот который нужен. Ты пробовал второй вариант с LockResource?
Можеш привести код где показана запись в бд картинки,т.е типа каким образом там просиходит преобразование например из HBITMAP в бинарник кторый затем и записывают в бд?
7.3K
01 октября 2005 года
LamerMFC
48 / / 17.09.2005
Цитата:
Originally posted by vitaly2003s
Может формат в бинарнике совсем не тот который нужен. Ты пробовал второй вариант с LockResource?
Можеш привести код где показана запись в бд картинки,т.е типа каким образом там просиходит преобразование например из HBITMAP в бинарник кторый затем и записывают в бд?



да я просто в access делаю тип поля "Поле объекта OLE" и потом нажимаю правую кнопку мыши и выбираю добавить объект, дале выбираю точечный рисунок или рисунок DIB или рисунок BMP, без разницы, все равно ничего не получается, обидно.

430
02 октября 2005 года
craftyfox
157 / / 20.02.2000
может быть, поможет вот это:
http://www.codeguru.com/Cpp/data/mfc_database/microsoftaccess/article.php/c1117/

или это:
http://www.codeproject.com/database/usingblob.asp

хотя, кажется мне, должны быть способы получше...
7.3K
02 октября 2005 года
LamerMFC
48 / / 17.09.2005
Цитата:
Originally posted by craftyfox
может быть, поможет вот это:
http://www.codeguru.com/Cpp/data/mfc_database/microsoftaccess/article.php/c1117/

или это:
http://www.codeproject.com/database/usingblob.asp

хотя, кажется мне, должны быть способы получше...



спасибо большое за ссылки, но ни одна из них не подходит. да я и не очень а англише шарю. блин, ну как же это битмап заставить появится, а?

430
02 октября 2005 года
craftyfox
157 / / 20.02.2000
Цитата:
Originally posted by LamerMFC
спасибо большое за ссылки, но ни одна из них не подходит. да я и не очень а англише шарю.


блин, ну куда ж без него-то?..

Цитата:
блин, ну как же это битмап заставить появится, а?


нашел кое-что получше (хотя, мне это тож не совсем нравится, но вроде как работает):
http://www.codeproject.com/wtl/oledb2.asp#xx1238535xx

Применительно к твоему коду это могло бы выглядеть
примерно так:

Код:
//это оттуда
void SkipOleHeader(IStream* pstm, ULONG& ulStatus)
{
    LARGE_INTEGER liOffset = { 0, 0 };
    struct OLEOBJHDR { WORD Sig; WORD Size; } Hdr;
    enum { DBSTATUS_S_OLE = 15 };
    // set stream to 0 and load header structure
    pstm->Seek(liOffset, STREAM_SEEK_SET, NULL);
    pstm->Read(&Hdr, sizeof(Hdr), NULL);

    // set stream past OLE bitmap object
    if (Hdr.Sig == 0x1C15 /*&& Hdr.Size == 0x2F*/) //условие на размер                           пришлось убрать - (cf)
    {
        liOffset.QuadPart = Hdr.Size + 1 + 30; //откуда беруться цифры,
                            пока не раскопал :(
        ulStatus = DBSTATUS_S_OLE;
    }
    pstm->Seek(liOffset, STREAM_SEEK_SET, NULL);
}

/////твой код:
    CDBVariant dbv;
    CString str;
    str.Format(“SELECT * FROM people WHERE id =1”);
    rs->Open(CRecorset::snapshot, str);
    rs->GetFieldValue(“surname”, str);
    rs->GetFieldValue(“photo”, dbv);
    rs->Close();
////далее:
    IStream* pIStream = 0;
    IPicture* ppict=0;
    void* pdata=GlobalLock(dbv.m_pbinary->m_hData);
      //LockResource
    //здесь совсем не причем, там под HGLOBAL понимается совсем не то,
    // что в функциях для работы с памятью
    HRESULT hr=::CreateStreamOnHGlobal(pdata, TRUE, &pIStream);
    if(FAILED(hr))
    {
      GlobalUnlock(dbv.m_pbinary->m_hData);
      //дальше не продолжать, вернуть ошибку    
    }
    ULONG status;
    SkipOleHeader(pIStream,status); // причина всех бед...
    hr=::OleLoadPicture(pIStream, 0, FALSE, IID_IPicture,
                  (LPVOID*)&ppict);
    if(FAILED(hr))
    {
      GlobalUnlock(dbv.m_pbinary->m_hData);
      //дальше не продолжать, вернуть ошибку    
    }
    GlobalUnlock(dbv.m_pbinary->m_hData);
    HBITMAP hbm=0;
    ASSERT(ppict);
    ppict->get_Handle((OLE_HANDLE*)&hbm);
    //теперь в hbm должен быть HBITMAP,который можно ипользовать
    //для рисования

Можно не использовать OLE API, а ,как в примере с codeguru, просто пропустить
"OLE header" в pdata, за ним, начиная с сигнатуры "BM" будет BITMAPFILEHEADER,
далее везде...
430
03 октября 2005 года
craftyfox
157 / / 20.02.2000
Нашел еще кое-что более вразумительное
(можно работать с любыми OLE объектами):
http://www.codeguru.com/Cpp/data/mfc_database/microsoftaccess/article.php/c1123/

Поупражняйся в английском-то :)
Правда, чтобы что-то понять, нужно скачать sources.

Код:
struct AccsHeader
{
    WORD signature;     // 'OC' == 0x1c15
    WORD size;          // Size of header
    LONG oletype;       //(OT_LINK, OT_EMBEDDED, OT_STATIC)
    WORD nAuxUT;        // Count of characters in AuxUserType
    WORD nProgID;       // Count of characters in ProgID
    WORD offsUT;        // Offset of AuxUserType
    WORD offsProgID;    // Offset of ProgID
    LONG something;     // (Access version <= 1.1 uses positive values).
};

HRESULT BitmapOrJpegFromRawData(bool bbmp,char* pdata,int dl,
                         IPicture*& ppict,HBITMAP* phbm,SIZE* pbmsz=0)
{
    *phbm=0,pbmsz?pbmsz->cx=0,pbmsz->cy=0:4==5;

    AccsHeader* pHdr=(AccsHeader*) pdata;
    LARGE_INTEGER lioffset={0};
    if(!bbmp)
    {
        // ищем начало JPEG
        if(dl<1024) return E_FAIL;
        char* pfnd=pdata+pHdr->nProgID + pHdr->offsProgID+sizeof(DWORD);
        for(;pfnd<(pdata+dl);)  
        {
            pfnd=(char*)memchr(pfnd,0xFF,512-(pfnd-(char*)pdata));
            if(!pfnd)
                break;
            if(*(pfnd+1)=='\x0D8' && *(pfnd+2)=='\x0ff' &&
                                                *(pfnd+3)=='\x0E0')
            {
                lioffset.QuadPart=pfnd-pdata;
                break;
            }
            pfnd++;
        }
    }
    else
        lioffset.QuadPart=pHdr->size+31; //начало Bitmap
    if(lioffset.QuadPart==0)
        return E_FAIL;
    CComPtr<IStream> pst=0;
    HRESULT hr=CreateStreamOnHGlobal(GlobalHandle(pdata),FALSE,&pst);
    if(FAILED(hr)) return hr;
    pst->Seek(lioffset,STREAM_SEEK_SET,0);

    ppict=0;
    hr=OleLoadPicture(pst,0,FALSE,IID_IPicture,(void**)&ppict);
    if(FAILED(hr)) return hr;

    hr=ppict->get_Handle((OLE_HANDLE*)phbm);
    if(pbmsz)
    {
        BITMAP bm;
        GetObject(*phbm,sizeof(bm),&bm);
        pbmsz->cx=bm.bmWidth;
        pbmsz->cy=bm.bmHeight;
    }
    return hr;
}
////// ....
        CDBVariant dbv;
        CString str;
        str.Format("SELECT * FROM table_1 WHERE ID=1");
        rs->Open(CRecordset::snapshot, str);
        rs->GetFieldValue("Surname", str);
        rs->GetFieldValue("photo", dbv);
        rs->Close();

        char* pdata=(char*)GlobalLock(dbv.m_pbinary->m_hData);
        AccsHeader* pHdr=(AccsHeader*) pdata;
        char* sprogID=pdata+pHdr->offsProgID;

        bool bmp=!strcmp(sprogID,"Paint.Picture");

        BitmapOrJpegFromRawData(bmp,pdata,dbv.m_pbinary->m_dwDataLength,
            ppict,&m_hbm,&m_bmsz);
        GlobalUnlock(dbv.m_pbinary->m_hData);
/////
}

здесь JPEG находится, даже если он в Package,
но как этот Package устроен, мне не понятно :(
7.3K
04 октября 2005 года
LamerMFC
48 / / 17.09.2005
Цитата:
Originally posted by craftyfox
Нашел еще кое-что более вразумительное
(можно работать с любыми OLE объектами):
http://www.codeguru.com/Cpp/data/mfc_database/microsoftaccess/article.php/c1123/

Поупражняйся в английском-то :)
Правда, чтобы что-то понять, нужно скачать sources.

Код:
struct AccsHeader
{
    WORD signature;     // 'OC' == 0x1c15
    WORD size;          // Size of header
    LONG oletype;       //(OT_LINK, OT_EMBEDDED, OT_STATIC)
    WORD nAuxUT;        // Count of characters in AuxUserType
    WORD nProgID;       // Count of characters in ProgID
    WORD offsUT;        // Offset of AuxUserType
    WORD offsProgID;    // Offset of ProgID
    LONG something;     // (Access version <= 1.1 uses positive values).
};

HRESULT BitmapOrJpegFromRawData(bool bbmp,char* pdata,int dl,
                         IPicture*& ppict,HBITMAP* phbm,SIZE* pbmsz=0)
{
    *phbm=0,pbmsz?pbmsz->cx=0,pbmsz->cy=0:4==5;

    AccsHeader* pHdr=(AccsHeader*) pdata;
    LARGE_INTEGER lioffset={0};
    if(!bbmp)
    {
        // ищем начало JPEG
        if(dl<1024) return E_FAIL;
        char* pfnd=pdata+pHdr->nProgID + pHdr->offsProgID+sizeof(DWORD);
        for(;pfnd<(pdata+dl);)  
        {
            pfnd=(char*)memchr(pfnd,0xFF,512-(pfnd-(char*)pdata));
            if(!pfnd)
                break;
            if(*(pfnd+1)=='\x0D8' && *(pfnd+2)=='\x0ff' &&
                                                *(pfnd+3)=='\x0E0')
            {
                lioffset.QuadPart=pfnd-pdata;
                break;
            }
            pfnd++;
        }
    }
    else
        lioffset.QuadPart=pHdr->size+31; //начало Bitmap
    if(lioffset.QuadPart==0)
        return E_FAIL;
    CComPtr<IStream> pst=0;
    HRESULT hr=CreateStreamOnHGlobal(GlobalHandle(pdata),FALSE,&pst);
    if(FAILED(hr)) return hr;
    pst->Seek(lioffset,STREAM_SEEK_SET,0);

    ppict=0;
    hr=OleLoadPicture(pst,0,FALSE,IID_IPicture,(void**)&ppict);
    if(FAILED(hr)) return hr;

    hr=ppict->get_Handle((OLE_HANDLE*)phbm);
    if(pbmsz)
    {
        BITMAP bm;
        GetObject(*phbm,sizeof(bm),&bm);
        pbmsz->cx=bm.bmWidth;
        pbmsz->cy=bm.bmHeight;
    }
    return hr;
}
////// ....
        CDBVariant dbv;
        CString str;
        str.Format("SELECT * FROM table_1 WHERE ID=1");
        rs->Open(CRecordset::snapshot, str);
        rs->GetFieldValue("Surname", str);
        rs->GetFieldValue("photo", dbv);
        rs->Close();

        char* pdata=(char*)GlobalLock(dbv.m_pbinary->m_hData);
        AccsHeader* pHdr=(AccsHeader*) pdata;
        char* sprogID=pdata+pHdr->offsProgID;

        bool bmp=!strcmp(sprogID,"Paint.Picture");

        BitmapOrJpegFromRawData(bmp,pdata,dbv.m_pbinary->m_dwDataLength,
            ppict,&m_hbm,&m_bmsz);
        GlobalUnlock(dbv.m_pbinary->m_hData);
/////
}

здесь JPEG находится, даже если он в Package,
но как этот Package устроен, мне не понятно :(



да я упражняюсь, а за ответ спасибо, щас буду пробовать

7.3K
04 октября 2005 года
LamerMFC
48 / / 17.09.2005
Цитата:
Originally posted by craftyfox
Нашел еще кое-что более вразумительное
(можно работать с любыми OLE объектами):
http://www.codeguru.com/Cpp/data/mfc_database/microsoftaccess/article.php/c1123/

Поупражняйся в английском-то :)
Правда, чтобы что-то понять, нужно скачать sources.

Код:
struct AccsHeader
{
    WORD signature;     // 'OC' == 0x1c15
    WORD size;          // Size of header
    LONG oletype;       //(OT_LINK, OT_EMBEDDED, OT_STATIC)
    WORD nAuxUT;        // Count of characters in AuxUserType
    WORD nProgID;       // Count of characters in ProgID
    WORD offsUT;        // Offset of AuxUserType
    WORD offsProgID;    // Offset of ProgID
    LONG something;     // (Access version <= 1.1 uses positive values).
};

HRESULT BitmapOrJpegFromRawData(bool bbmp,char* pdata,int dl,
                         IPicture*& ppict,HBITMAP* phbm,SIZE* pbmsz=0)
{
    *phbm=0,pbmsz?pbmsz->cx=0,pbmsz->cy=0:4==5;

    AccsHeader* pHdr=(AccsHeader*) pdata;
    LARGE_INTEGER lioffset={0};
    if(!bbmp)
    {
        // ищем начало JPEG
        if(dl<1024) return E_FAIL;
        char* pfnd=pdata+pHdr->nProgID + pHdr->offsProgID+sizeof(DWORD);
        for(;pfnd<(pdata+dl);)  
        {
            pfnd=(char*)memchr(pfnd,0xFF,512-(pfnd-(char*)pdata));
            if(!pfnd)
                break;
            if(*(pfnd+1)=='\x0D8' && *(pfnd+2)=='\x0ff' &&
                                                *(pfnd+3)=='\x0E0')
            {
                lioffset.QuadPart=pfnd-pdata;
                break;
            }
            pfnd++;
        }
    }
    else
        lioffset.QuadPart=pHdr->size+31; //начало Bitmap
    if(lioffset.QuadPart==0)
        return E_FAIL;
    CComPtr<IStream> pst=0;
    HRESULT hr=CreateStreamOnHGlobal(GlobalHandle(pdata),FALSE,&pst);
    if(FAILED(hr)) return hr;
    pst->Seek(lioffset,STREAM_SEEK_SET,0);

    ppict=0;
    hr=OleLoadPicture(pst,0,FALSE,IID_IPicture,(void**)&ppict);
    if(FAILED(hr)) return hr;

    hr=ppict->get_Handle((OLE_HANDLE*)phbm);
    if(pbmsz)
    {
        BITMAP bm;
        GetObject(*phbm,sizeof(bm),&bm);
        pbmsz->cx=bm.bmWidth;
        pbmsz->cy=bm.bmHeight;
    }
    return hr;
}
////// ....
        CDBVariant dbv;
        CString str;
        str.Format("SELECT * FROM table_1 WHERE ID=1");
        rs->Open(CRecordset::snapshot, str);
        rs->GetFieldValue("Surname", str);
        rs->GetFieldValue("photo", dbv);
        rs->Close();

        char* pdata=(char*)GlobalLock(dbv.m_pbinary->m_hData);
        AccsHeader* pHdr=(AccsHeader*) pdata;
        char* sprogID=pdata+pHdr->offsProgID;

        bool bmp=!strcmp(sprogID,"Paint.Picture");

        BitmapOrJpegFromRawData(bmp,pdata,dbv.m_pbinary->m_dwDataLength,
            ppict,&m_hbm,&m_bmsz);
        GlobalUnlock(dbv.m_pbinary->m_hData);
/////
}

здесь JPEG находится, даже если он в Package,
но как этот Package устроен, мне не понятно :(



если бы ты видел как я прыгал от щастья когда увидел заветный бытмам... даже и не знаю как тебя благодорить, жаль ты в тундре живешь...:)

7.3K
04 октября 2005 года
LamerMFC
48 / / 17.09.2005
Цитата:
Originally posted by craftyfox
Нашел еще кое-что более вразумительное
(можно работать с любыми OLE объектами):
http://www.codeguru.com/Cpp/data/mfc_database/microsoftaccess/article.php/c1123/

Поупражняйся в английском-то :)
Правда, чтобы что-то понять, нужно скачать sources.

Код:
struct AccsHeader
{
    WORD signature;     // 'OC' == 0x1c15
    WORD size;          // Size of header
    LONG oletype;       //(OT_LINK, OT_EMBEDDED, OT_STATIC)
    WORD nAuxUT;        // Count of characters in AuxUserType
    WORD nProgID;       // Count of characters in ProgID
    WORD offsUT;        // Offset of AuxUserType
    WORD offsProgID;    // Offset of ProgID
    LONG something;     // (Access version <= 1.1 uses positive values).
};

HRESULT BitmapOrJpegFromRawData(bool bbmp,char* pdata,int dl,
                         IPicture*& ppict,HBITMAP* phbm,SIZE* pbmsz=0)
{
    *phbm=0,pbmsz?pbmsz->cx=0,pbmsz->cy=0:4==5;

    AccsHeader* pHdr=(AccsHeader*) pdata;
    LARGE_INTEGER lioffset={0};
    if(!bbmp)
    {
        // ищем начало JPEG
        if(dl<1024) return E_FAIL;
        char* pfnd=pdata+pHdr->nProgID + pHdr->offsProgID+sizeof(DWORD);
        for(;pfnd<(pdata+dl);)  
        {
            pfnd=(char*)memchr(pfnd,0xFF,512-(pfnd-(char*)pdata));
            if(!pfnd)
                break;
            if(*(pfnd+1)=='\x0D8' && *(pfnd+2)=='\x0ff' &&
                                                *(pfnd+3)=='\x0E0')
            {
                lioffset.QuadPart=pfnd-pdata;
                break;
            }
            pfnd++;
        }
    }
    else
        lioffset.QuadPart=pHdr->size+31; //начало Bitmap
    if(lioffset.QuadPart==0)
        return E_FAIL;
    CComPtr<IStream> pst=0;
    HRESULT hr=CreateStreamOnHGlobal(GlobalHandle(pdata),FALSE,&pst);
    if(FAILED(hr)) return hr;
    pst->Seek(lioffset,STREAM_SEEK_SET,0);

    ppict=0;
    hr=OleLoadPicture(pst,0,FALSE,IID_IPicture,(void**)&ppict);
    if(FAILED(hr)) return hr;

    hr=ppict->get_Handle((OLE_HANDLE*)phbm);
    if(pbmsz)
    {
        BITMAP bm;
        GetObject(*phbm,sizeof(bm),&bm);
        pbmsz->cx=bm.bmWidth;
        pbmsz->cy=bm.bmHeight;
    }
    return hr;
}
////// ....
        CDBVariant dbv;
        CString str;
        str.Format("SELECT * FROM table_1 WHERE ID=1");
        rs->Open(CRecordset::snapshot, str);
        rs->GetFieldValue("Surname", str);
        rs->GetFieldValue("photo", dbv);
        rs->Close();

        char* pdata=(char*)GlobalLock(dbv.m_pbinary->m_hData);
        AccsHeader* pHdr=(AccsHeader*) pdata;
        char* sprogID=pdata+pHdr->offsProgID;

        bool bmp=!strcmp(sprogID,"Paint.Picture");

        BitmapOrJpegFromRawData(bmp,pdata,dbv.m_pbinary->m_dwDataLength,
            ppict,&m_hbm,&m_bmsz);
        GlobalUnlock(dbv.m_pbinary->m_hData);
/////
}

здесь JPEG находится, даже если он в Package,
но как этот Package устроен, мне не понятно :(



я еще читал что это все очень легко делается через класс CPicture, но как именно не написано:(

430
04 октября 2005 года
craftyfox
157 / / 20.02.2000
В последнем примере есть весьма сарьезный баг.
перед ppict=0, в случае ненулевого ppict нужно
вызвать ppict->Release();
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог