Witam,
mam problem z robieniem screenów na Windowsie Vista i 7. Na starszych wersjach bez problemowo programowo mogę robić screeny grom uruchamianym w OpenGL, natomiast na nowych systemach albo robi mi czarnego screena, albo na zrzucie ekranu widzę pulpit w rozdzielczości z jaką uruchomiłem grę.
Próbowałem między innymi takich funkcji, jak widać poniżej, ale żadna nie działa :( Screeny z pulpitu wychodzą dobre, ale z gier nie działają.
void Screeny::Get24BitBmp ( const int &nWidth, const int &nHeight,const HBITMAP &hBitmap , BYTE *lpDesBits)
{
HDC hDC = ::GetDC( 0 );
HDC memDC1 = ::CreateCompatibleDC ( hDC );
HDC memDC2 = ::CreateCompatibleDC ( hDC );
BYTE *lpBits = NULL;
BITMAPINFO bmi;
::ZeroMemory( &bmi, sizeof(BITMAPINFO) );
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = nWidth;
bmi.bmiHeader.biHeight = nHeight;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
HBITMAP hDIBMemBM = ::CreateDIBSection( 0, &bmi, DIB_RGB_COLORS, (void**)&lpBits, NULL, NULL );
HBITMAP hOldBmp1 = (HBITMAP)::SelectObject(memDC1, hDIBMemBM );
HBITMAP hOldBmp2 = (HBITMAP) ::SelectObject ( memDC2,hBitmap);
::BitBlt( memDC1, 0, 0, nWidth, nHeight, memDC2, 0, 0, SRCCOPY );
for ( int i = 0 ; i < nHeight ; i++)
::CopyMemory(&lpDesBits[i*3*nWidth],&lpBits[nWidth*3*(nHeight-1-i)],nWidth*3);
// clean up
::SelectObject ( memDC1, hOldBmp1 );
::SelectObject ( memDC2,hOldBmp2 );
::ReleaseDC ( 0, hDC );
::DeleteObject ( hDIBMemBM );
::DeleteObject ( hOldBmp1 );
::DeleteObject ( hOldBmp2 );
::DeleteDC ( memDC1 );
::DeleteDC ( memDC2 );
}
//-------------------------------------------------------------------------------
BOOL Screeny::CaptureWindow( HWND hWndSrc,double fPreviewRatio,char *lpszFileName,BOOL bSaveToFile)
{
RECT rc={0};
::GetWindowRect(hWndSrc,&rc);
int Width = rc.right-rc.left;
int Height = rc.bottom-rc.top;
Width = (Width/4)*4;
HDC hdc = ::GetDC(0);
HDC memDC = ::CreateCompatibleDC ( hdc );
HBITMAP memBM = ::CreateCompatibleBitmap ( hdc, Width, Height );
HBITMAP hOld = (HBITMAP)::SelectObject ( memDC, memBM );
int Bpp = ::GetDeviceCaps(hdc,BITSPIXEL);
int size = (Bpp/8) * ( Width * Height );
BYTE *lpBits1 = new BYTE[size];
BYTE *lpBits2 = new BYTE[Width * Height*3];
BYTE *lpBits3 = new BYTE[Width * Height*3];
BOOL Ret=TRUE;
HBITMAP hBmp=0;
int MinBlackPixels=Width * Height*10;
int Count =0;
int Size24 = Width * Height*3;
while ( Count < 5 )
{
Ret = Capture(hWndSrc,memDC);
::GetBitmapBits( memBM, size, lpBits1 );
hBmp = ::CreateBitmap(Width,Height,1,Bpp,lpBits1);
Get24BitBmp (Width,Height,hBmp,lpBits2);
int BlackPixels=0;
for (int i=0;i<Size24;i+=3)
{
if ( lpBits2[i+2]==0 && lpBits2[i+1]==0 && lpBits2[i+0] == 0)
BlackPixels++;
}
if ( BlackPixels < MinBlackPixels )
{
MinBlackPixels = BlackPixels;
::memcpy(lpBits3,lpBits2,Size24);
Count=0;
}
Count++;
::DeleteObject(hBmp);
}
::memcpy(lpBits2,lpBits3,Size24);
if (bSaveToFile)
SaveBmpToFile(lpszFileName, Width, Height,24, (int*)lpBits2);
delete [] lpBits1;
delete [] lpBits2;
delete [] lpBits3;
::SelectObject(memDC,hOld);
::DeleteObject(memBM);
::DeleteObject(hBmp);
::DeleteDC(memDC);
::ReleaseDC( 0, hdc );
return Ret;
}
BOOL Screeny::Capture( HWND hwnd,HDC memDC)
{
typedef BOOL (WINAPI *tPrintWindow)( HWND, HDC,UINT);
tPrintWindow pPrintWindow = 0;
HINSTANCE handle = ::LoadLibraryA("gdi32.dll");
if ( handle == 0 )
return FALSE;
pPrintWindow = (tPrintWindow)::GetProcAddress(handle, "PrintWindow");
int Ret = TRUE;
if ( pPrintWindow )
Ret = pPrintWindow(hwnd, memDC,0 );
else
{
Ret = FALSE;
}
::FreeLibrary(handle);
return (Ret? TRUE: FALSE);
}