Creando HBITMAP desde el buffer de memoria

Tengo una aplicación que carga algunos datos de blobs de una base de datos que pueden representar datos binarios en formato png o en bruto para varios mapas de bits e íconos. Esto se almacena en un std::vector

Estoy usando objetos CImageList para mostrar varias imágenes en vistas de árbol, imágenes de la barra de herramientas, etc. pero el problema es crear mapas de bits a partir de los datos en la memoria que salen borrosos como si le faltaran píxeles al hacer algo como a continuación:

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

Para solucionar este problema por ahora simplemente estoy escribiendo los datos () en el vector en un archivo temporal y luego usando LoadImage para volver a leerlo y crear el HBITMAP a partir de eso. Esto funciona perfectamente, sin embargo, es un truco descarado y debería ser completamente innecesario, espero.

He buscado en línea pero no he encontrado ejemplos realmente buenos de cómo “crear” hbitmaps de la memoria “correctamente”. Me gustaría poder crear estos mapas de bits para agregarlos a la lista de imágenes sin ningún archivo de E / S y cantidades limitadas de copiar los datos, si es posible.

Buscando la mejor manera de hacer esto y, obviamente, el código específico de Windows está bien.

ACTUALIZAR:

Basado en la respuesta de jdv, comencé a jugar con CreateCompatibleBitmap, CreateDIBitmap y finalmente CreateDIBSection. Todo esto terminó creando encantadores mapas de bits negros en lugar de los borrosos mapas de bits anteriores, así que debo estar haciendo algo mal otra vez y mi suposición es que esta creación de bitmap se hace en un objeto que no tiene el concepto de pantalla o ventana que usa GetDC(NULL) y CreateCompatibleDC(NULL) no son buenos. Código de muestra:

  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); 

Ahora, por supuesto, estoy pensando que tiene que haber una forma más simple de hacerlo, evitando por completo el HBITMAP y trabajando directamente con la clase CBitmap . Cuando se trata de agregar la imagen al CImageList , estoy usando CBitmap::FromHandle(HBITMAP hbitmap, COLORREF mask) todos modos. ¿Alguien sabe una forma simple de inicializar un objeto CBitmap desde un std::vector ?

Yo usaría CreateCompatibleBitmap , y luego llamaría a SetDIBits para llenarlo con sus datos. Estas son funciones que he visto que funcionan, y SetDIBits es bastante flexible, aunque prolijo.

En mis años de MFC, se evitó CreateBitmap debido a problemas de rendimiento sospechosos.

Usando GdiPlus obtuve algo que funciona bastante bien y ¡no implica sacar ningún diente!

 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(); } 

Editar: cambiado por Jegatheesh