2009-12-23 146 views
1

我一直在寫一些代碼來做一個窗口的屏幕抓取(在Windows中)。代碼工作正常,但在屏幕抓取之前,我必須將窗口置於我想要捕獲的前端並強制重繪。屏幕抓取窗口

我強制使用InvalidateRect重繪,然後必須從消息循環中抽取一些消息才能處理WM_PAINT。這顯然有點跛腳,因爲我不知道有多少消息要泵送。

我嘗試使用RedrawWindow與RDW_ALLCHILDREN,但我抓住屏幕的應用程序是一個MDI應用程序,似乎並沒有重繪所有的孩子。

所以我的問題是,有沒有更好的方法來重新繪製窗口之前的屏幕抓取?

乾杯 豐富

+0

你是否在'InvalidateRect()'調用中將最後一個參數('bErase')設置爲true? – ThinkJet 2009-12-23 15:10:39

+0

嘗試在無效後使用'UpdateWindow()'調用 – ThinkJet 2009-12-23 15:16:27

回答

4

既然你沒有提到你所使用的語言,希望在C++下面的代碼可以幫助你!

void getScreenShot(int texWidth, int texHeight, unsigned char* pBuffer, HWND handle) 
{ 
    /* Local variables */ 
    HDC screenDC; 
    RECT screenRect; 
    int extraBytesPerRow; 
    BITMAPINFO bitmapInfo; 
    HDC bitmapDC; 
    void* bitmapDataPtr; 
    HBITMAP hBitmap; 
    HBITMAP hPrevBitmap; 
    unsigned char* pIn; 
    unsigned char* pOut; 
    int rowIndex; 
    int colIndex; 
    /* Get a DC from the desktop window */ 
    screenDC = GetDC(handle); 
    GetClientRect(handle, &screenRect); 
    /* Determine the extra bytes we need per row (each row of bitmap data must end on a 32bit boundary) */ 
    extraBytesPerRow = (texWidth * 3) % 4; 
    extraBytesPerRow = extraBytesPerRow ? 4 - extraBytesPerRow : 0; 
    /* Setup the bitmap info structure */ 
    memset(&bitmapInfo, 0, sizeof(bitmapInfo)); 
    bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
    bitmapInfo.bmiHeader.biWidth = texWidth; 
    bitmapInfo.bmiHeader.biHeight = texHeight; 
    bitmapInfo.bmiHeader.biPlanes = 1; 
    bitmapInfo.bmiHeader.biBitCount = 24; 
    bitmapInfo.bmiHeader.biCompression = BI_RGB; 
    /* Create a bitmap device context (bitmapDataPtr will be a pointer to the bits in the bitmap) */ 
    bitmapDC = CreateCompatibleDC(NULL); 
    hBitmap = CreateDIBSection(bitmapDC, (BITMAPINFO*)&bitmapInfo.bmiHeader, DIB_RGB_COLORS, &bitmapDataPtr, NULL, 0); 
    hPrevBitmap = (HBITMAP)SelectObject(bitmapDC, hBitmap); 
    /* BitBlt or StretchBlt the image from the input DC into our bitmap DC */ 
    if ((texWidth != screenRect.right) || (texHeight != screenRect.bottom)) 
    { 
     SetStretchBltMode(bitmapDC, HALFTONE); 
     StretchBlt(bitmapDC, 0, 0, texWidth, texHeight, screenDC, 0, 0, screenRect.right, screenRect.bottom, SRCCOPY); 
    } 
    else 
    { 
     BitBlt(bitmapDC, 0, 0, texWidth, texHeight, screenDC, 0, 0, SRCCOPY); 
    } 
    /* Copy the data from the bitmap to the user's buffer (bitmap data is BGR and 4 byte aligned on each row, we want tightly-packed RGB) */ 
    pIn = (unsigned char*)bitmapDataPtr; 
    pOut = pBuffer; 
    for (rowIndex = 0; rowIndex < texHeight; rowIndex++) 
    { 
     for (colIndex = 0; colIndex < texWidth; colIndex++) 
     { 
      pOut[ 0 ] = pIn[2]; 
      pOut[ 1 ] = pIn[1]; 
      pOut[ 2 ] = pIn[0]; 
      pOut += 3; 
      pIn += 3; 
     } 
     pIn += extraBytesPerRow; 
    } 
    /* Free memory used by the bitmap */ 
    SelectObject(bitmapDC, hPrevBitmap); 
    DeleteObject(hBitmap); 
    DeleteDC(bitmapDC); 
    /* Release the screen DC */ 
    ReleaseDC(handle, screenDC); 
} 

你不真正需要強制重繪。但萬一被最小化的窗口中,你可能需要把它,你調用函數與窗口句柄之前..! texWidth和texHeight是您即將捕捉的窗口的尺寸;爲了得到這個你可以使用GetWindowRect(..)或者查看這裏的鏈接:link