为什么 CreateCompatibleBitmap() 与 CreateCompatibleDC() 不兼容
Why CreateCompatibleBitmap() isn't compatible with CreateCompatibleDC()
我创建了一个应该截屏的小程序。我想了解第 11 行:
HBITMAP hbm = CreateCompatibleBitmap(hdcmem, w, h);
如果我用桌面DC调用CreateCompatibleBitmap
,效果很好;但是,如果我将 hdcmem
作为第一个参数,就会出错:缓冲区最终为空。如果 hdcmem
与桌面 DC 兼容,为什么会这样?
#include <Windows.h>
#include <fstream>
int main()
{
UINT w = 100;
UINT h = 100;
UINT bitsPerPix = 24;
UINT buffSize = (w * bitsPerPix + 31) / 32 * 4 * h;
HDC desktop = GetDC(0);
HDC hdcmem = CreateCompatibleDC(desktop);
HBITMAP hbm = CreateCompatibleBitmap(hdcmem, w, h);
hbm = (HBITMAP)SelectObject(hdcmem, hbm);
BitBlt(hdcmem, 0, 0, w, h, desktop, 0, 0, SRCCOPY);
hbm = (HBITMAP)SelectObject(hdcmem, hbm);
BITMAPFILEHEADER bmf{};
bmf.bfType = 0x4d42;
bmf.bfOffBits = sizeof BITMAPFILEHEADER + sizeof BITMAPINFOHEADER;
bmf.bfSize = sizeof BITMAPFILEHEADER + sizeof BITMAPINFOHEADER + buffSize;
BITMAPINFOHEADER bmi{};
bmi.biSize = sizeof bmi;
bmi.biWidth = w;
bmi.biHeight = h;
bmi.biBitCount = bitsPerPix;
bmi.biCompression = 0;
bmi.biPlanes = 1;
char* buff = new char[buffSize];
GetDIBits(hdcmem, hbm, 0, h, buff, (LPBITMAPINFO)&bmi, DIB_RGB_COLORS);
std::ofstream ofile("D:\test.bmp", std::ios_base::binary);
ofile.write((char*)&bmf, sizeof bmf);
ofile.write((char*)&bmi, sizeof bmi);
ofile.write(buff, buffSize);
ofile.close();
delete[] buff;
DeleteObject(hbm);
DeleteDC(hdcmem);
ReleaseDC(0, desktop);
return 0;
}
CreateCompatibleBitmap
函数创建一个与 物理设备 兼容的位图,该位图与作为其第一个参数传递的设备上下文相关联。内存设备上下文没有这样的关联物理设备,那么该位图将与什么兼容?可能,虽然没有明确记录,但它将与当前选择的位图兼容——对于newly-created内存DC是1 x 1 单色 位图。
Note: When a memory device context is created, it initially has a
1-by-1 monochrome bitmap selected into it. If this memory device
context is used in CreateCompatibleBitmap, the bitmap that is
created is a monochrome bitmap. To create a color bitmap, use the
HDC that was used to create the memory device context, as shown in the following code …
我创建了一个应该截屏的小程序。我想了解第 11 行:
HBITMAP hbm = CreateCompatibleBitmap(hdcmem, w, h);
如果我用桌面DC调用CreateCompatibleBitmap
,效果很好;但是,如果我将 hdcmem
作为第一个参数,就会出错:缓冲区最终为空。如果 hdcmem
与桌面 DC 兼容,为什么会这样?
#include <Windows.h>
#include <fstream>
int main()
{
UINT w = 100;
UINT h = 100;
UINT bitsPerPix = 24;
UINT buffSize = (w * bitsPerPix + 31) / 32 * 4 * h;
HDC desktop = GetDC(0);
HDC hdcmem = CreateCompatibleDC(desktop);
HBITMAP hbm = CreateCompatibleBitmap(hdcmem, w, h);
hbm = (HBITMAP)SelectObject(hdcmem, hbm);
BitBlt(hdcmem, 0, 0, w, h, desktop, 0, 0, SRCCOPY);
hbm = (HBITMAP)SelectObject(hdcmem, hbm);
BITMAPFILEHEADER bmf{};
bmf.bfType = 0x4d42;
bmf.bfOffBits = sizeof BITMAPFILEHEADER + sizeof BITMAPINFOHEADER;
bmf.bfSize = sizeof BITMAPFILEHEADER + sizeof BITMAPINFOHEADER + buffSize;
BITMAPINFOHEADER bmi{};
bmi.biSize = sizeof bmi;
bmi.biWidth = w;
bmi.biHeight = h;
bmi.biBitCount = bitsPerPix;
bmi.biCompression = 0;
bmi.biPlanes = 1;
char* buff = new char[buffSize];
GetDIBits(hdcmem, hbm, 0, h, buff, (LPBITMAPINFO)&bmi, DIB_RGB_COLORS);
std::ofstream ofile("D:\test.bmp", std::ios_base::binary);
ofile.write((char*)&bmf, sizeof bmf);
ofile.write((char*)&bmi, sizeof bmi);
ofile.write(buff, buffSize);
ofile.close();
delete[] buff;
DeleteObject(hbm);
DeleteDC(hdcmem);
ReleaseDC(0, desktop);
return 0;
}
CreateCompatibleBitmap
函数创建一个与 物理设备 兼容的位图,该位图与作为其第一个参数传递的设备上下文相关联。内存设备上下文没有这样的关联物理设备,那么该位图将与什么兼容?可能,虽然没有明确记录,但它将与当前选择的位图兼容——对于newly-created内存DC是1 x 1 单色 位图。
Note: When a memory device context is created, it initially has a 1-by-1 monochrome bitmap selected into it. If this memory device context is used in CreateCompatibleBitmap, the bitmap that is created is a monochrome bitmap. To create a color bitmap, use the HDC that was used to create the memory device context, as shown in the following code …