2011-05-24 79 views
2

很长时间以来一直在使用XP。切换到7,并试图捕获与我以前运作的代码截图不再有效。简单的概念和相对通用的代码...只需找到我打电话的窗口并将其保存为.png即可。任何想法可能会使这个坏男孩再次运行?无法使用当前的设置进行调试,但它会一路顺利并在bmp-> save(...)...无法保存图像文件之后吐出错误消息。编辑:也创建/保存一个文件,但它是空白的,没有写入。也许位图编码或GDI被搞砸了?Windows 7和ScreenShot.cpp GDI + PNG问题

bool CScreenShot::Snap(CString wintitle, CString file, CString& ermsg) 
{ 
    ermsg = ""; // no error message 

    // create screen shot bitmap 
    EnumWinProcStruct prm = {0, (LPSTR)(LPCTSTR)wintitle, 0}; 

    // Find the descriptor of the window with the caption wintitle 
    EnumDesktopWindows(0, EnumWindowsProc, (LPARAM)&prm); 
    if(!prm.hwnd) 
    { 
     ermsg.Format("couldn't find window \"%s\"", wintitle); 
     return false; 
    } 

    // Make the window the topmost window 
    SetWindowPos(prm.hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); 
    Sleep(300); 

    // Get device context for the top-level window and client rect 
    HDC hDC = GetDC(prm.hwnd); 
    RECT rc; 
    GetClientRect(prm.hwnd, &rc); 

    HDC memDC = CreateCompatibleDC(hDC); 

    // Set the size and color depth for the screen shot image 
    BITMAPINFO bmpInfo; 
    memset(&bmpInfo, 0, sizeof(bmpInfo)); 
    bmpInfo.bmiHeader.biSize = sizeof(bmpInfo.bmiHeader); 
    bmpInfo.bmiHeader.biWidth = rc.right - rc.left; 
    bmpInfo.bmiHeader.biHeight = rc.bottom - rc.top; 
    bmpInfo.bmiHeader.biPlanes = 1; 
    bmpInfo.bmiHeader.biBitCount = 24; 
    bmpInfo.bmiHeader.biCompression = BI_RGB; 
    bmpInfo.bmiHeader.biSizeImage = bmpInfo.bmiHeader.biWidth * bmpInfo.bmiHeader.biHeight * 3; 

    // Create memory buffer and perform a bit-block transfer of the color data from the window to the memory 
    LPVOID addr; 
    HBITMAP memBM = CreateDIBSection(memDC, &bmpInfo, DIB_RGB_COLORS, &addr, 0, 0); 

    HGDIOBJ stdBM = SelectObject(memDC, memBM); 
    BOOL OK  = BitBlt(memDC, 0, 0, bmpInfo.bmiHeader.biWidth, bmpInfo.bmiHeader.biHeight, hDC, 0, 0, SRCCOPY); 
    ReleaseDC(prm.hwnd, hDC); 

    SetWindowPos(prm.hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); 

    // Initialize GDI+. 
    GdiplusStartupInput gdiplusStartupInput; 
    ULONG_PTR   gdiplusToken; 
    if(GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL) != Ok) 
    { 
     ermsg.Format("couldn't start GDI+"); 
     return false; 
    } 

    // Create a Bitmap object for work with images defined by pixel data from the GDI HBitmap and the GDI HPalette. 
    Bitmap* bmp = ::new Bitmap(memBM, DIB_RGB_COLORS); 
    SelectObject(memDC, stdBM); 
    DeleteObject(memBM); 
    DeleteDC(memDC); 

    // Find the encoder for "image/png" mime type 
    CLSID encoderClsid; 
    EncoderParameters encoderParameters; 

    GetEncoderClsid(L"image/png", &encoderClsid); 

    encoderParameters.Count = 0; 

    // Convert file name to Unicode (wide-char) string. 
    WCHAR fn[_MAX_PATH]; 
    MultiByteToWideChar(CP_THREAD_ACP, MB_PRECOMPOSED, file, file.GetLength() + 1, fn, _MAX_PATH); 
    // Save the screen shot into the specified file using image encoder with the mime style "image/png" 
    if(bmp->Save(fn, &encoderClsid, &encoderParameters) != Ok) 
    { 
     ermsg.Format("couldn't save image file \"%s\"", file); 
     return false; 
    } 

    ::delete bmp; 
    GdiplusShutdown(gdiplusToken); 

    return true; 
} 

回答

0

win7将不会接受encoderParameters.Count == 0出于某种原因。设置== 1,你应该全部设置。

你大概也可以只删除保存(该参数)(重载)

+0

这就是它。谢谢。 – brad 2012-09-24 17:31:39

+0

我应该补充说,这解决了上面的问题......但与win7相关的新问题提出了自己的代码:opengl应用程序的屏幕截图只会得到框架,而不是子窗口。 – brad 2012-09-24 17:39:31

1

错误消息意味着您正试图将文件保存到您无权写入的文件夹。许多文件夹(如Program Files)现在都受到保护。由于您未在示例代码中包含路径,因此无法确定这是否是实际问题。

编辑:另一种可能性是位图构造不当导致保存失败。构造函数的第二个参数应该是调色板的句柄,我认为DIB_RGB_COLORS在这里是无效的,你应该使用NULL。也有几个需要注意的地方在Microsoft documentation指出,也许不同的操作系统版本,当你打破规则产生不同的反应:

您有责任删除GDI的位图和GDI调色板。但是,直到GDI + Bitmap :: Bitmap对象被删除或超出范围之后,才能删除GDI位图或GDI调色板。

不要传递给GDI +位图::位图构造函数当前(或之前)已选择到设备上下文中的GDI位图或GDI调色板。

+0

赞赏,但我只是保存到C上的通用文件夹:前驱动,我的程序实际上会为我取屏幕截图(以存储屏幕截图以及日志).....所以我绝对有权限... – brad 2011-05-24 21:53:25

+0

如果您的应用程序未升级,它可能没有创建文件夹的权限。尝试手动创建文件夹,然后查看它是否有效。或者,尝试在AppData下创建文件夹(每个用户的存储空间)。 – 2011-05-25 16:53:16

+0

所有提升......似乎XP和win7之间有区别。一个文件会在正确的文件夹中使用正确的名称创建,但该文件为0kb并且内容未被填充。 – brad 2011-06-07 13:57:39