Creazione di HBITMAP dal buffer di memoria

Ho un’applicazione che carica alcuni dati blob da un database che può rappresentare dati binari formattati o grezzi per varie bitmap e icone. Questo viene salvato in un file std::vector

CImageList oggetti CImageList per visualizzare varie immagini in viste ad albero, immagini della barra degli strumenti, ecc. Ma il problema è la creazione di bitmap dai dati in memoria che stanno uscendo sfocati come se mancassero pixel quando si fa qualcosa di simile di seguito:

 std::vector bits; HBITMAP hbitmap = CreateBitmap(16, 16, 1, 32, bits.data()); 

Per ovviare a questo problema, per il momento, sto semplicemente scrivendo i dati () nel vettore in un file temporaneo e quindi utilizzando LoadImage per leggerlo di nuovo e creare da questo l’HBITMAP. Questo funziona perfettamente, tuttavia, che è certamente un trucco spudorato e dovrebbe essere completamente inutile, spero.

Mi sono guardato in giro online ma non ho trovato nessun buon esempio di come “correttamente” creare hbitmap dalla memoria. Mi piacerebbe essere in grado di creare questi bitmap da aggiungere all’elenco delle immagini senza alcun file I / O e quantità limitate di copia dei dati, se ansible.

Cerchi il modo migliore per farlo e ovviamente il codice specifico di Windows va bene.

AGGIORNARE:

Sulla base della risposta di jdv ho iniziato a giocare con CreateCompatibleBitmap, CreateDIBitmap e infine CreateDIBSection. Tutti questi hanno finito per creare belle bitmap nere invece delle precedenti bitmap fuzzy, quindi devo fare ancora qualcosa di sbagliato e la mia ipotesi è che questa creazione di bitmap viene eseguita in un object che non ha alcun concetto di schermata dc o finestra che utilizza GetDC(NULL) e CreateCompatibleDC(NULL) non vanno bene. Codice d’esempio:

  BITMAPINFO bmi; ZeroMemory(&bmi, sizeof(BITMAPINFO)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biHeight = 16; bmi.bmiHeader.biWidth = 16; bmi.bmiHeader.biPlanes = 1; HDC dc = CreateCompatibleDC(NULL); HBITMAP hbitmap = CreateDIBSection(dc, &bmi, DIB_RGB_COLORS, (void**)blobData.GetMember().data(), NULL, 0); 

Ora sto pensando, ovviamente, che ci sia un modo più semplice per farlo, evitando del tutto l’HBITMAP e lavorando direttamente con la class CBitmap ? Quando si tratta di aggiungere l’immagine a CImageList sto utilizzando comunque CBitmap::FromHandle(HBITMAP hbitmap, COLORREF mask) . Qualcuno sa un modo semplice per inizializzare un object CBitmap da un file std::vector ?

Vorrei utilizzare CreateCompatibleBitmap e quindi chiamare SetDIBits per riempirlo con i dati. Queste sono funzioni che ho visto funzionare, e SetDIBits è abbastanza flessibile, anche se prolisso.

Nei miei anni MFC, CreateBitmap stato evitato a causa di sospetti problemi di prestazioni.

Usando GdiPlus ho qualcosa che funziona abbastanza bene e non comporta l’estrazione di alcun dente!

 Gdiplus::Bitmap* pBitmap = NULL; IStream* pStream = NULL; HRESULT hResult = ::CreateStreamOnHGlobal( NULL, TRUE, &pStream ); if(hResult == S_OK && pStream) { hResult = pStream->Write(&bits[0], ULONG(bits.size()), NULL); if(hResult == S_OK) pBitmap = Gdiplus::Bitmap::FromStream(pStream); pStream->Release(); } 

Modifica: modificato per Jegatheesh