Access数据库位图文件数据的读写(二)
从数据库读取数据到VARIANT结构中
VARIANT varVal; VariantInit(&varVal); //注意要通过get_value()才能读取数据到VARIANT结构中 rs->GetFields()->GetItem(TEXT("ImgData"))->get_Value(&varVal);
把VARIANT数据转为HBITMAP位图句柄
HBITMAP QAdo::VariantToHBitmap(VARIANT& varVal) { SAFEARRAY* psa = nullptr; void* pData = nullptr; HRESULT hr = S_OK; long ugSize=0, dataSize = 0; HBITMAP hBitmap = 0; if (V_VT(&varVal) & VT_ARRAY) { psa = V_ARRAY(&varVal); //3.访问safeArry数据 hr = SafeArrayAccessData(psa, &pData); assert(hr == S_OK); SafeArrayGetUBound(psa, 1, &ugSize); //SafeArrayGetLBound(psa, 1, &lgSize); dataSize = SafeArrayGetElemsize(psa)*ugSize + 1; BYTE* pBuffer = (BYTE*)malloc(dataSize); memcpy(pBuffer, pData, dataSize); hBitmap = CreateBitmapFromMemory((unsigned char*)pBuffer, dataSize); //assert(hBitmap); if(pBuffer) free(pBuffer); } VariantClear(&varVal); return hBitmap; } HBITMAP g_hBitmap=ado.VariantToHBitmap(varVal);
CreateBitmapFromMemory 函数的实现
/* 通过二进制数组创建位图 参数: pData 二进制数组(BYTE*) dataSize 数组大小 返回: 位图句柄 */ HBITMAP QAdo::CreateBitmapFromMemory(const unsigned char* pData, DWORD dataSize) { if (!pData || dataSize == 0) return NULL; // 1. 解析 BMP 文件头 BITMAPFILEHEADER* pFileHeader = (BITMAPFILEHEADER*)pData; // 验证是否是合法的 BMP 文件 ('BM') if (pFileHeader->bfType != 0x4D42) { return NULL; } // 2. 获取位图信息头 (BITMAPINFOHEADER) // 它紧跟在文件头之后 BITMAPINFOHEADER* pInfoHeader = (BITMAPINFOHEADER*)(pData + sizeof(BITMAPFILEHEADER)); // 3. 计算像素数据的偏移量 // bfOffBits 指定了从文件开头到像素数据的字节偏移 DWORD pixelOffset = pFileHeader->bfOffBits; // 确保偏移量合法 if (pixelOffset >= dataSize) return NULL; const void* pPixelData = (const void*)(pData + pixelOffset); // 4. 创建兼容 DC HDC hScreenDC = GetDC(NULL); // 获取屏幕 DC HDC hMemDC = CreateCompatibleDC(hScreenDC); // 5. 创建 DIB Section // DIB Section 允许我们直接操作位图内存,或者让 GDI 管理它 HBITMAP hBitmap = CreateDIBSection( hMemDC, (BITMAPINFO*)pInfoHeader, // 注意:BITMAPINFOHEADER 是 BITMAPINFO 的一部分 DIB_RGB_COLORS, NULL, // 不需要返回内存指针,因为数据已经在 pData 中 NULL, 0 ); if (hBitmap) { // 6. 将数据库中的像素数据拷贝到 HBITMAP 中 // SetDIBits 会自动处理行对齐和格式转换 int lines = SetDIBits( hMemDC, hBitmap, 0, // 起始扫描线 pInfoHeader->biHeight, // 扫描线数量 pPixelData, // 源像素数据 (BITMAPINFO*)pInfoHeader, // 位图信息 DIB_RGB_COLORS ); if (lines == 0) { DeleteObject(hBitmap); hBitmap = NULL; } } // 清理临时 DC DeleteDC(hMemDC); ReleaseDC(NULL, hScreenDC); return hBitmap; }
用位图句柄绘制到窗口上
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
if (g_hBitmap) {
// 在窗口坐标 (10, 10) 处绘制图片
DrawBitmapToWindow(hdc, g_hBitmap, 10, 10);
}
else {
TextOut(hdc, 10, 10, L"No Image Loaded", 13);
}
EndPaint(hwnd, &ps);
break;
}
效果呈现

签名:GreenLeaf1976

浙公网安备 33010602011771号