求printwindow函数获取图片后无法保存到缓冲区的解决方法

帅牛 2014-09-16 04:47:06
HDC hScrDC, hMemDC;
CRect m_WindowRect;
::GetWindowRect(m_Winhwnd , m_WindowRect);
hScrDC = ::GetDC(m_Winhwnd);
ASSERT(hScrDC);
hMemDC = ::CreateCompatibleDC(hScrDC);
ASSERT(hMemDC);

HBITMAP hBitmap,hOldBitmap;
hBitmap=::CreateCompatibleBitmap(hScrDC, m_WindowRect.Width(), m_WindowRect.Height());
ASSERT(hBitmap);
hOldBitmap=(HBITMAP)SelectObject(hMemDC,hBitmap);

unsigned char *lpvBits = NULL;
LONG ImageSize = m_WindowRect.Width()*m_WindowRect.Height()*4 ;
lpvBits = new unsigned char[ImageSize];

BITMAPINFO bmpInfo;
memset(&bmpInfo, 0 , sizeof(BITMAPINFO));
bmpInfo.bmiHeader.biSize = sizeof(bmpInfo.bmiHeader);
bmpInfo.bmiHeader.biWidth=m_WindowRect.Width();
bmpInfo.bmiHeader.biHeight =m_WindowRect.Height();
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 32;
bmpInfo.bmiHeader.biCompression = BI_RGB;
bmpInfo.bmiHeader.biSizeImage = ImageSize;

::PrintWindow(m_Winhwnd , hMemDC , 0);
OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hBitmap);
CloseClipboard(); //剪切板验证图片是正确拿到的
::GetDIBits(hMemDC, hBitmap, 0 , m_WindowRect.Height() , lpvBits , &bmpInfo, DIB_RGB_COLORS);
//这里的返回值也是图片高度,只是lpvBits值为0
hBitmap=(HBITMAP)SelectObject(hMemDC,hOldBitmap);
DeleteDC(hMemDC);
DeleteDC(hScrDC);
DeleteObject(hBitmap);



最近在做一个桌面取图的程序,这个是对窗口进行取图,取图后会把图片保存在缓存区,然后进一步操作。我桌面取图和桌面区域取图都没问题,就这个的指针老是为零。
...全文
152 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
帅牛 2014-09-28
  • 打赏
  • 举报
回复
现在想想,这段代码本身没有问题,我修改和不修改其实都一样的。编译器虽然显示值为零,但是调用该指针指向的内容时,数据是已经存在了的,并且是正确的,一开始我是因为测试数据方法不当造成的错误。
帅牛 2014-09-19
  • 打赏
  • 举报
回复
修改了下代码: BITMAPINFO bmpInfo = {0}; bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); GetDIBits(hMemDC, hBitmap, 0 , 0 ,NULL , &bmpInfo, DIB_RGB_COLORS); 用函数GetDIBits获取BITMAPINFO 信息后,调用GetDIBits获取缓冲区指针就能够成功,已经成功写入。 最后,谢谢赵老师的回复。。
赵4老师 2014-09-17
  • 打赏
  • 举报
回复
仅供参考
#pragma comment(lib,"gdi32")
#include <windows.h>
#include <stdio.h>

int main() {
    const DWORD uWidth = 18 + 17 * 256, uHeight = 18 + 17 * 128;

    PBITMAPINFO pbmi = (PBITMAPINFO) LocalAlloc (LPTR, sizeof (BITMAPINFOHEADER) + sizeof (RGBQUAD) * 2);
    pbmi->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
    pbmi->bmiHeader.biWidth = uWidth;
    pbmi->bmiHeader.biHeight = uHeight;
    pbmi->bmiHeader.biPlanes = 1;
    pbmi->bmiHeader.biBitCount = 1;
    pbmi->bmiHeader.biSizeImage = ((uWidth + 31) & ~31) / 8 * uHeight;
    pbmi->bmiColors[0].rgbBlue = 0;
    pbmi->bmiColors[0].rgbGreen = 0;
    pbmi->bmiColors[0].rgbRed = 0;
    pbmi->bmiColors[1].rgbBlue = 255;
    pbmi->bmiColors[1].rgbGreen = 255;
    pbmi->bmiColors[1].rgbRed = 255;

    HDC hDC = CreateCompatibleDC (0);
    void * pvBits;
    HBITMAP hBitmap = CreateDIBSection (hDC, pbmi, 0, &pvBits, NULL, 0);
    SelectObject (hDC, hBitmap);
    HFONT hFont = CreateFont (16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "宋体");
//  HFONT hFont = CreateFont (16, 0, 0, 0, 0, 0, 0, 0, SHIFTJIS_CHARSET, 0, 0, 0, 0, "宋体");
    SelectObject (hDC, hFont);
    BitBlt (hDC, 0, 0, uWidth, uHeight, NULL, 0, 0, WHITENESS);

    char c[4];
    int i, j;
    for (i = 128; i < 256; i++) {
        sprintf (c, "%02X", i);
        TextOut (hDC, 1, (i - 127) * 17 + 1, c, 2);
    }
    for (j = 0; j < 256; j++) {
        sprintf (c, "%02X", j);
        TextOut (hDC, (j + 1)* 17 + 1, 1, c, 2);
    }
    for (i = 128; i < 256; i++) {
        for (j = 0; j < 256; j++) {
            c[0] = (char) i;
            c[1] = (char) j;
            TextOut (hDC, (j + 1) * 17 + 1, (i - 127) * 17 + 1, c, 2);
        }
    }
    for (i = 0; i < 130; i++) {
        MoveToEx (hDC, 0, i * 17, NULL);
        LineTo (hDC, uWidth, i * 17);
    }
    for (j = 0; j < 258; j++) {
        MoveToEx (hDC, j * 17, 0, NULL);
        LineTo (hDC, j * 17, uHeight);
    }

    BITMAPFILEHEADER bmfh;
    bmfh.bfType = *(PWORD) "BM";
    bmfh.bfReserved1 = 0;
    bmfh.bfReserved2 = 0;
    bmfh.bfOffBits = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) + sizeof (RGBQUAD) * 2;
    bmfh.bfSize = bmfh.bfOffBits + pbmi->bmiHeader.biSizeImage;

    HANDLE hFile = CreateFile ("goal.bmp", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
    if (hFile != INVALID_HANDLE_VALUE) {
        DWORD dwWritten;
        WriteFile (hFile, &bmfh, sizeof (BITMAPFILEHEADER), &dwWritten, NULL);
        WriteFile (hFile, pbmi, sizeof (BITMAPINFOHEADER) + sizeof (RGBQUAD) * 2, &dwWritten, NULL);
        WriteFile (hFile, pvBits, pbmi->bmiHeader.biSizeImage, &dwWritten, NULL);

        CloseHandle (hFile);
    }

    DeleteObject (hFont);
    DeleteObject (hBitmap);
    DeleteDC (hDC);
    LocalFree (pbmi);

    return 0;
}
帅牛 2014-09-17
  • 打赏
  • 举报
回复
没人知道么,,是不是少了东西?
帅牛 2014-09-16
  • 打赏
  • 举报
回复
来位大神指导下,或者有类似经历的一起讨论下。谢谢大家~!

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧