C++ 为什么GetObject返回带有空bmBits的位图?

C++ 为什么GetObject返回带有空bmBits的位图?,c++,windows,gdi,C++,Windows,Gdi,背景:我正试图拍摄另一个窗口的截图,将其输入OpenCV。我在网上找到了一些代码,可以将位图转换成OpenCV可以使用的格式。不幸的是,我遇到了一些麻烦 问题:为什么bmBits属性/成员总是空的?(我还尝试使用PrintWindow而不是BitBlt,结果相同) #包括 #包括 #包括 int main(int argc,char*argv[]) { std::wstring windowName=L“计算器”; RECT-RECT; HWND HWND=FindWindow(NULL,win

背景:我正试图拍摄另一个窗口的截图,将其输入OpenCV。我在网上找到了一些代码,可以将位图转换成OpenCV可以使用的格式。不幸的是,我遇到了一些麻烦

问题:为什么bmBits属性/成员总是空的?(我还尝试使用PrintWindow而不是BitBlt,结果相同)

#包括
#包括
#包括
int main(int argc,char*argv[])
{
std::wstring windowName=L“计算器”;
RECT-RECT;
HWND HWND=FindWindow(NULL,windowName.c_str());
if(hwnd==NULL)
{
返回0;
}
GetClientRect(hwnd和rect);
HDC hdcScreen=GetDC(NULL);
HDC HDC=CreateCompatibleDC(hdcScreen);
HBITMAP hbmp=CreateCompatibleBitmap(hdcScreen,
rect.right-rect.left,rect.bottom-rect.top);
选择对象(hdc、hbmp);
打印窗口(仅限hwnd、hdc、PW_客户端);
位图bmp;
GetObject(hbmp、sizeof(位图)和bmp);
返回0;
}

对于DIB节,
bmBits
成员为非空。对于依赖于设备的位图(如您正在创建的位图),不会设置
bmBits
,因为像素位于视频卡上,而不是主内存中

在您的示例中,如果希望直接访问位,则需要将
CreateCompatibleBitmap
更改为
CreateDIBSection

仅供参考。 从文件加载位图并希望使用位图.bmBits(对于glTexImage2DglDrawPixels):

必须指定标志
LR\u CREATEDIBSECTION

HBITMAP hBmp = NULL;
BITMAP BMp;
hBmp = (HBITMAP) LoadImage(NULL, "bitmap.bmp", IMAGE_BITMAP, 0, 0,
                                       LR_LOADFROMFILE | LR_CREATEDIBSECTION);
GetObject(hBmp, sizeof(BMp), &BMp);
//BMp.bmBits now points to data

您可以做的一件事是查看GetObject的返回值。如果你知道出了什么问题。调用的参数有问题。

来自MSDN上的文档。请注意第二段

如果hgdiobj是通过调用CreateDIBSection创建的位图的句柄,并且指定的缓冲区足够大,那么GetObject函数将返回一个
DIBSECTION
结构。此外,
DIBSECTION
中包含的
BITMAP
结构的bmBits成员将包含指向位图位值的指针

如果hgdiobj是通过任何其他方式创建的位图的句柄,GetObject仅返回位图的宽度、高度和颜色格式信息。您可以通过调用GetDIBitsGetBitmapBits函数来获取位图的位值


你想用这段代码做一个屏幕截图吗?看起来是这样。如果是这样的话,PrintWindow不是您所需要的。它所做的只是向目标窗口发送一个WM_打印,其中包含一个要转储的DC。不能保证Windows会处理该消息,如果是这样的话,做你想做的事情。您几乎拥有了所需的一切,但我相信您需要使用BitBlt()将位从屏幕DC提取到兼容的DC,并准备好接收新位图。这是我见过的唯一提到这一点的答案。先生,你真棒!
LoadImage(NULL, "path_to.bmp", IMAGE_BITMAP, 0, 0,
                                       LR_LOADFROMFILE);
HBITMAP hBmp = NULL;
BITMAP BMp;
hBmp = (HBITMAP) LoadImage(NULL, "bitmap.bmp", IMAGE_BITMAP, 0, 0,
                                       LR_LOADFROMFILE | LR_CREATEDIBSECTION);
GetObject(hBmp, sizeof(BMp), &BMp);
//BMp.bmBits now points to data