Просмотр картинок из DB Access
У меня есть таблица в которой следующие поля:
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. Как это сделать я не знаю. Помогите пожалуйста.
неужели никто не знает как из HGLOBAL получить HBITMAP???????
там еще что то про LockResource упоминалось
там еще что то про 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;
}
попробуй так:
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);
}
Можеш привести код где показана запись в бд картинки,т.е типа каким образом там просиходит преобразование например из HBITMAP в бинарник кторый затем и записывают в бд?
Может формат в бинарнике совсем не тот который нужен. Ты пробовал второй вариант с LockResource?
Можеш привести код где показана запись в бд картинки,т.е типа каким образом там просиходит преобразование например из HBITMAP в бинарник кторый затем и записывают в бд?
да я просто в access делаю тип поля "Поле объекта OLE" и потом нажимаю правую кнопку мыши и выбираю добавить объект, дале выбираю точечный рисунок или рисунок DIB или рисунок BMP, без разницы, все равно ничего не получается, обидно.
http://www.codeguru.com/Cpp/data/mfc_database/microsoftaccess/article.php/c1117/
или это:
http://www.codeproject.com/database/usingblob.asp
хотя, кажется мне, должны быть способы получше...
может быть, поможет вот это:
http://www.codeguru.com/Cpp/data/mfc_database/microsoftaccess/article.php/c1117/
или это:
http://www.codeproject.com/database/usingblob.asp
хотя, кажется мне, должны быть способы получше...
спасибо большое за ссылки, но ни одна из них не подходит. да я и не очень а англише шарю. блин, ну как же это битмап заставить появится, а?
спасибо большое за ссылки, но ни одна из них не подходит. да я и не очень а англише шарю.
блин, ну куда ж без него-то?..
нашел кое-что получше (хотя, мне это тож не совсем нравится, но вроде как работает):
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,
далее везде...
(можно работать с любыми OLE объектами):
http://www.codeguru.com/Cpp/data/mfc_database/microsoftaccess/article.php/c1123/
Поупражняйся в английском-то :)
Правда, чтобы что-то понять, нужно скачать sources.
{
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 устроен, мне не понятно :(
Нашел еще кое-что более вразумительное
(можно работать с любыми OLE объектами):
http://www.codeguru.com/Cpp/data/mfc_database/microsoftaccess/article.php/c1123/
Поупражняйся в английском-то :)
Правда, чтобы что-то понять, нужно скачать sources.
{
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 устроен, мне не понятно :(
да я упражняюсь, а за ответ спасибо, щас буду пробовать
Нашел еще кое-что более вразумительное
(можно работать с любыми OLE объектами):
http://www.codeguru.com/Cpp/data/mfc_database/microsoftaccess/article.php/c1123/
Поупражняйся в английском-то :)
Правда, чтобы что-то понять, нужно скачать sources.
{
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 устроен, мне не понятно :(
если бы ты видел как я прыгал от щастья когда увидел заветный бытмам... даже и не знаю как тебя благодорить, жаль ты в тундре живешь...:)
Нашел еще кое-что более вразумительное
(можно работать с любыми OLE объектами):
http://www.codeguru.com/Cpp/data/mfc_database/microsoftaccess/article.php/c1123/
Поупражняйся в английском-то :)
Правда, чтобы что-то понять, нужно скачать sources.
{
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, но как именно не написано:(
перед ppict=0, в случае ненулевого ppict нужно
вызвать ppict->Release();