There is an example of downloading images from a file (checked, downloads bmp, jpg, gif, etc.). How can I download HBIΠ’MAP from memory?

For the OleCreateFromData function, I can't figure out how to create an IDataObject from a piece (I think that it is the answer). There is an example for SO with GdiPlus, but there it is not clear how to translate it into HBITMAP. LoadBitmapIndirect - loads only bitmaps of a certain configuration (does not fit). OleCreateFromFile - loads from a file - does not fit.

There is more, you can create an object through CoCreateInstance , and download IStorage through IStorage . Here the strange problem in borand delphi is a piece of code , but for some reason it gives an error:

 char[] gif={0x47,0x49,0x46,0x38,0x39,0x61,0x0C,0x00,0x0C,0x00,0x80,0xFF,0x00,0x9C,0x00,0x00 ,0xC0,0xC0,0xC0,0x21,0xF9,0x04,0x01,0x00,0x00,0x01,0x00,0x2C,0x00,0x00,0x00,0x00 ,0x0C,0x00,0x0C,0x00,0x00,0x02,0x1B,0x8C,0x7F,0x80,0xA1,0x09,0xCD,0x9E,0x79,0x72 ,0xD2,0xBB,0x6E,0xCD,0x74,0x59,0x8C,0x68,0xDD,0xA7,0x68,0xD1,0x06,0x6E,0x96,0xC7,0x06,0x05,0x00,0x3B}; int dwBytes = sizeof(gif); HGLOBAL hStorage = ::GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE, dwBytes); if (hStorage == NULL) AfxThrowMemoryException(); LPVOID lpBuf = ::GlobalLock(hStorage); ASSERT(lpBuf != NULL); memcpy(lpBuf,gif, dwBytes); ::GlobalUnlock(hStorage); // throw exception in case of partial object SCODE sc = CreateILockBytesOnHGlobal(hStorage, TRUE, &m_lpLockBytes); if (sc != S_OK){::GlobalFree(hStorage);AfxThrowOleException(sc);} sc = ::StgOpenStorageOnILockBytes(m_lpLockBytes, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &m_lpStorage); 

StgOpenStorageOnILockBytes gives either an error 800300FB ( invalid header ), or 800300FF ( invalid flag ), or 0x80030050 ( file not exist ). The error depends on the flags. Is it possible to load a picture somehow differently into the CLSID_Picture_DIB object?

Here is an example of how you can load from a file (it loads gif, that is, OLE still knows how to load pictures):

 HANDLE Handle; // Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Π² Handle Π±ΠΈΡ‚ΠΌΠ°ΠΏΠ° HRESULT LoadOLE(wchar_t* FileName){ HRESULT Result; tagFORMATETC fmt; tagSTGMEDIUM stg; ILockBytes *FLockBytes=0; IStorage *iStorage=0; IDataObject *Data=0; if ((Result =CreateILockBytesOnHGlobal(0, 1, &FLockBytes))!=0) return Result; if ((Result =StgCreateDocfileOnILockBytes(FLockBytes, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, &iStorage))!=0){ FLockBytes->Release(); FLockBytes=0; return Result; }; fmt.cfFormat = CF_BITMAP; fmt.dwAspect=1; fmt.lindex=-1; fmt.ptd=0; fmt.tymed=2; Result =OleCreateFromFile(CLSID_Picture_Dib,FileName, IID_IDataObject,OLERENDER_NONE,&fmt,0,iStorage,(void**)&Data); if (Result==0) Result =OleRun(Data); if (Result==0) Result =Data->GetData(&fmt,&stg); if (Result==0) Handle = stg.hBitmap; if (Data) Data->Release(); Data=0; iStorage->Release(); iStorage=0; FLockBytes->Release(); FLockBytes=0; // return Result; // ΠžΡ‚Ρ€ΠΈΡΠΎΠ²ΠΊΠ° Handle Π±ΠΈΡ‚ΠΌΠ°ΠΏΠ° HDC dest = GetDC(0 /*ДСскриптор ΠΎΠΊΠ½Π°*/); // допустим ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ HDC dc = CreateCompatibleDC(0); SelectObject(dc,Handle); BitBlt(dest,x,y,xx,yy, dc,0,0,SRCCOPY); ReleaseDC( 0 /*ДСскриптор ΠΎΠΊΠ½Π°*/, dest); } 

But the question remains open.

    1 answer 1

    It turned out through GDIPlus, maybe not the best way, but there is a result. Written in borland, without connecting extra libraries (except for downloading gdiplus.dll). Gif uploaded. But if there is an answer through OLE I will be glad

     HBITMAP LoadBitmapGDI(char* data, int size) { HANDLE m = GlobalAlloc(GMEM_FIXED,size); DWORD sz; ReadProcessMemory(GetCurrentProcess(),data, m,size,&sz); IStream * stm = 0; if ( CreateStreamOnHGlobal(m,0,&stm) != 0 ) { GlobalFree(m); return 0; } HANDLE g = LoadLibraryA("gdiplus.dll"); int __stdcall (*GdiplusStartup)(void*,void*); int __stdcall (*GdiplusShutdown)(); int __stdcall (*GdipCreateBitmapFromStream)(IStream* stream, void** nativebitmap); int __stdcall (*GdipCreateHBITMAPFromBitmap)(void* nativebitmap, void** bitmap, int argbBackground); int __stdcall (*GdipDisposeImage)(void* h); (void*)GdiplusStartup=GetProcAddress(g,"GdiplusStartup"); (void*)GdiplusShutdown=GetProcAddress(g,"GdiplusShutdown"); (void*)GdipCreateBitmapFromStream =GetProcAddress(g,"GdipCreateBitmapFromStream"); (void*)GdipCreateHBITMAPFromBitmap = GetProcAddress(g,"GdipCreateHBITMAPFromBitmap"); (void*)GdipDisposeImage = GetProcAddress(g,"GdipDisposeImage"); HANDLE h = 0; HBITMAP bm = 0; char st[256] = { 1, 0,}; HANDLE st2 = 0; GdiplusStartup(&st2,&st); GdipCreateBitmapFromStream(stm,&h); GdipCreateHBITMAPFromBitmap(h,&bm,0 /*color !*/); GdipDisposeImage(h); GdiplusShutdown(); FreeLibrary(g); GlobalFree(m); stm->Release(); stm = 0; return bm; } -----------------------------------------test char[] gif={0x47,0x49,0x46,0x38,0x39,0x61,0x0C,0x00,0x0C,0x00,0x80,0xFF,0x00,0x9C,0x00,0x00 ,0xC0,0xC0,0xC0,0x21,0xF9,0x04,0x01,0x00,0x00,0x01,0x00,0x2C,0x00,0x00,0x00,0x00 ,0x0C,0x00,0x0C,0x00,0x00,0x02,0x1B,0x8C,0x7F,0x80,0xA1,0x09,0xCD,0x9E,0x79,0x72 ,0xD2,0xBB,0x6E,0xCD,0x74,0x59,0x8C,0x68,0xDD,0xA7,0x68,0xD1,0x06,0x6E,0x96,0xC7,0x06,0x05,0x00,0x3B}; HBITMAP h = LoadBitmapGDI(gif,sizeof(gif)); 

    Here are some more examples.

    example1 quite simple

    which ship the listed formats.