2011-05-24 78 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