X
xc
Greetings.
I encountered a wield problem when grabing screen images.
Sometimes in some computers I can capture the screen, but other times not
so.
In some computer I cannot capture the screen image, but when I change its
color bits, say from 32bits to 24 or 16bits, the program can capture the
image.
Can anyone kindly examine my following code, and point out the flaw:
void CGetScreenToBitmap::SetArea(CRect rcArea, int nArea)
{
HWND hFocus;
int xScrn, yScrn;
HDC hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);
DeleteDC(hScrDC);
m_rcArea.left = 0;
m_rcArea.top = 0;
m_rcArea.right = xScrn;
m_rcArea.bottom = yScrn;
hFocus = GetActiveWindow();
if (nArea == 1 && hFocus != NULL)
GetWindowRect(hFocus, &m_rcArea);
else if(nArea == 2)
m_rcArea = rcArea;
if (m_rcArea.left < 0)
m_rcArea.left = 0;
if (m_rcArea.top < 0)
m_rcArea.top = 0;
if (m_rcArea.right > xScrn)
m_rcArea.right = xScrn;
if (m_rcArea.bottom > yScrn)
m_rcArea.bottom = yScrn;
}
BOOL CGetScreenToBitmap::GetScreen(CRect rcArea, int nBits, int nArea)
{
HDC hScrDC, hMemDC;
HBITMAP hBitmap, hOldBitmap;
WORD wBitCount;
DWORD dwPaletteSize=0;
BITMAP Bitmap;
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpbi;
HANDLE hFile, handle;
FILE * f1;
DEVMODE dmSettings;
HPALETTE hPal = NULL;
memset(&dmSettings,0,sizeof(dmSettings)); // Makes Sure Memory's Cleared
// Get current settings -- This function fills our the settings
// This makes sure NT and Win98 machines change correctly
EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&dmSettings);
dmSettings.dmBitsPerPel = 16;
dmSettings.dmFields = DM_BITSPERPEL;
// This function actually changes the screen to full screen
// CDS_FULLSCREEN Gets Rid Of Start Bar.
// We always want to get a result from this function to check if we failed
int result = ChangeDisplaySettings(&dmSettings,0);
// Check if we didn't recieved a good return message From the function
if(result = DISP_CHANGE_SUCCESSFUL)
{
f1=fopen("C:\\winnt\\ae.bmp","a+");
fwrite("ChangeDisplaySettings error!!!",1,30,f1);
fclose(f1);
}
ResetVariable();
SetArea(rcArea, nArea);
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
hMemDC = CreateCompatibleDC(hScrDC);
hBitmap = CreateCompatibleBitmap(hScrDC, m_rcArea.Width(),
m_rcArea.Height());
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
BitBlt(hMemDC, 0, 0, m_rcArea.Width(), m_rcArea.Height(), hScrDC,
m_rcArea.left, m_rcArea.top, SRCCOPY);
hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
wBitCount = nBits;
if (wBitCount <= 8)
dwPaletteSize = (1 << wBitCount) * sizeof(RGBQUAD);
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = dwPaletteSize/sizeof(RGBQUAD);
bi.biClrImportant = 0;
m_dwBmpInfoSize = dwPaletteSize + sizeof(BITMAPINFOHEADER);
m_lpBmpData = (LPSTR)GlobalAlloc(GMEM_FIXED, m_dwBmpInfoSize);
lpbi = (LPBITMAPINFOHEADER)m_lpBmpData;
*lpbi = bi;
if (wBitCount <= 8)
hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
if (hPal)
{
SelectPalette(hMemDC, hPal, TRUE);
RealizePalette(hMemDC);
}
// Call GetDIBits with a NULL lpBits param, so the device driver
// will calculate the biSizeImage field
if(!GetDIBits(
hMemDC,
hBitmap,
0L,
(UINT) Bitmap.bmHeight,
(LPBYTE)NULL,
(BITMAPINFO *)lpbi,
DIB_RGB_COLORS
))
{
f1=fopen("C:\\winnt\\ae.bmp","a+");
fwrite("First GetDIBits error!!!",1,24,f1);
fclose(f1);
}
bi = *lpbi;
// If the driver did not fill in the biSizeImage field, then compute it
// Each scan line of the image is aligned on a DWORD (32bit) boundary
if (bi.biSizeImage == 0)
bi.biSizeImage = ((Bitmap.bmWidth * wBitCount+31)& ~31) /8 *
Bitmap.bmHeight;
m_dwBmpSize = bi.biSizeImage + m_dwBmpInfoSize;
handle = GlobalReAlloc(m_lpBmpData, m_dwBmpSize, GMEM_MOVEABLE);
m_lpBmpData = (char *)handle;
lpbi = (LPBITMAPINFOHEADER)m_lpBmpData;
// FINALLY get the DIB
int Lines = GetDIBits(hMemDC, hBitmap, 0L, (UINT)Bitmap.bmHeight,
(LPSTR)lpbi + sizeof(BITMAPINFOHEADER) + dwPaletteSize,
(BITMAPINFO *)lpbi, DIB_RGB_COLORS);
char szBuf[12];
wsprintf(szBuf, "Lines: %i", Lines);
f1=fopen("C:\\winnt\\ae.bmp","a+");
fwrite(szBuf,1,12,f1);
fclose(f1);
// OK, so we've got the bits, and the BITMAPINFOHEADER.
// Now we can put them in a file.
hFile = CreateFile("C:\\winnt\\aa.bmp", GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, 0, NULL);
// .BMP file begins with a BITMAPFILEHEADER,
// so we'll write that.
BITMAPFILEHEADER bmfh;
bmfh.bfType = MAKEWORD('B','M');
bmfh.bfSize = sizeof(BITMAPFILEHEADER) + m_dwBmpSize;
bmfh.bfReserved1 = 0;
bmfh.bfReserved2 = 0;
bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + m_dwBmpInfoSize;
DWORD bytesWritten;
WriteFile(hFile, &bmfh, sizeof(BITMAPFILEHEADER), &bytesWritten, NULL);
// Then it's followed by the BITMAPINFOHEADER structure
WriteFile(hFile, lpbi, m_dwBmpInfoSize, &bytesWritten, NULL);
// Then the pixel data.
WriteFile(hFile, lpbi + m_dwBmpInfoSize, bi.biSizeImage, &bytesWritten,
NULL);
CloseHandle(hFile);
DeleteObject (hBitmap);
DeleteObject (hOldBitmap);
DeleteDC(hScrDC);
DeleteDC(hMemDC);
return TRUE;
}
I encountered a wield problem when grabing screen images.
Sometimes in some computers I can capture the screen, but other times not
so.
In some computer I cannot capture the screen image, but when I change its
color bits, say from 32bits to 24 or 16bits, the program can capture the
image.
Can anyone kindly examine my following code, and point out the flaw:
void CGetScreenToBitmap::SetArea(CRect rcArea, int nArea)
{
HWND hFocus;
int xScrn, yScrn;
HDC hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);
DeleteDC(hScrDC);
m_rcArea.left = 0;
m_rcArea.top = 0;
m_rcArea.right = xScrn;
m_rcArea.bottom = yScrn;
hFocus = GetActiveWindow();
if (nArea == 1 && hFocus != NULL)
GetWindowRect(hFocus, &m_rcArea);
else if(nArea == 2)
m_rcArea = rcArea;
if (m_rcArea.left < 0)
m_rcArea.left = 0;
if (m_rcArea.top < 0)
m_rcArea.top = 0;
if (m_rcArea.right > xScrn)
m_rcArea.right = xScrn;
if (m_rcArea.bottom > yScrn)
m_rcArea.bottom = yScrn;
}
BOOL CGetScreenToBitmap::GetScreen(CRect rcArea, int nBits, int nArea)
{
HDC hScrDC, hMemDC;
HBITMAP hBitmap, hOldBitmap;
WORD wBitCount;
DWORD dwPaletteSize=0;
BITMAP Bitmap;
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpbi;
HANDLE hFile, handle;
FILE * f1;
DEVMODE dmSettings;
HPALETTE hPal = NULL;
memset(&dmSettings,0,sizeof(dmSettings)); // Makes Sure Memory's Cleared
// Get current settings -- This function fills our the settings
// This makes sure NT and Win98 machines change correctly
EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&dmSettings);
dmSettings.dmBitsPerPel = 16;
dmSettings.dmFields = DM_BITSPERPEL;
// This function actually changes the screen to full screen
// CDS_FULLSCREEN Gets Rid Of Start Bar.
// We always want to get a result from this function to check if we failed
int result = ChangeDisplaySettings(&dmSettings,0);
// Check if we didn't recieved a good return message From the function
if(result = DISP_CHANGE_SUCCESSFUL)
{
f1=fopen("C:\\winnt\\ae.bmp","a+");
fwrite("ChangeDisplaySettings error!!!",1,30,f1);
fclose(f1);
}
ResetVariable();
SetArea(rcArea, nArea);
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
hMemDC = CreateCompatibleDC(hScrDC);
hBitmap = CreateCompatibleBitmap(hScrDC, m_rcArea.Width(),
m_rcArea.Height());
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
BitBlt(hMemDC, 0, 0, m_rcArea.Width(), m_rcArea.Height(), hScrDC,
m_rcArea.left, m_rcArea.top, SRCCOPY);
hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
wBitCount = nBits;
if (wBitCount <= 8)
dwPaletteSize = (1 << wBitCount) * sizeof(RGBQUAD);
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = dwPaletteSize/sizeof(RGBQUAD);
bi.biClrImportant = 0;
m_dwBmpInfoSize = dwPaletteSize + sizeof(BITMAPINFOHEADER);
m_lpBmpData = (LPSTR)GlobalAlloc(GMEM_FIXED, m_dwBmpInfoSize);
lpbi = (LPBITMAPINFOHEADER)m_lpBmpData;
*lpbi = bi;
if (wBitCount <= 8)
hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
if (hPal)
{
SelectPalette(hMemDC, hPal, TRUE);
RealizePalette(hMemDC);
}
// Call GetDIBits with a NULL lpBits param, so the device driver
// will calculate the biSizeImage field
if(!GetDIBits(
hMemDC,
hBitmap,
0L,
(UINT) Bitmap.bmHeight,
(LPBYTE)NULL,
(BITMAPINFO *)lpbi,
DIB_RGB_COLORS
))
{
f1=fopen("C:\\winnt\\ae.bmp","a+");
fwrite("First GetDIBits error!!!",1,24,f1);
fclose(f1);
}
bi = *lpbi;
// If the driver did not fill in the biSizeImage field, then compute it
// Each scan line of the image is aligned on a DWORD (32bit) boundary
if (bi.biSizeImage == 0)
bi.biSizeImage = ((Bitmap.bmWidth * wBitCount+31)& ~31) /8 *
Bitmap.bmHeight;
m_dwBmpSize = bi.biSizeImage + m_dwBmpInfoSize;
handle = GlobalReAlloc(m_lpBmpData, m_dwBmpSize, GMEM_MOVEABLE);
m_lpBmpData = (char *)handle;
lpbi = (LPBITMAPINFOHEADER)m_lpBmpData;
// FINALLY get the DIB
int Lines = GetDIBits(hMemDC, hBitmap, 0L, (UINT)Bitmap.bmHeight,
(LPSTR)lpbi + sizeof(BITMAPINFOHEADER) + dwPaletteSize,
(BITMAPINFO *)lpbi, DIB_RGB_COLORS);
char szBuf[12];
wsprintf(szBuf, "Lines: %i", Lines);
f1=fopen("C:\\winnt\\ae.bmp","a+");
fwrite(szBuf,1,12,f1);
fclose(f1);
// OK, so we've got the bits, and the BITMAPINFOHEADER.
// Now we can put them in a file.
hFile = CreateFile("C:\\winnt\\aa.bmp", GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, 0, NULL);
// .BMP file begins with a BITMAPFILEHEADER,
// so we'll write that.
BITMAPFILEHEADER bmfh;
bmfh.bfType = MAKEWORD('B','M');
bmfh.bfSize = sizeof(BITMAPFILEHEADER) + m_dwBmpSize;
bmfh.bfReserved1 = 0;
bmfh.bfReserved2 = 0;
bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + m_dwBmpInfoSize;
DWORD bytesWritten;
WriteFile(hFile, &bmfh, sizeof(BITMAPFILEHEADER), &bytesWritten, NULL);
// Then it's followed by the BITMAPINFOHEADER structure
WriteFile(hFile, lpbi, m_dwBmpInfoSize, &bytesWritten, NULL);
// Then the pixel data.
WriteFile(hFile, lpbi + m_dwBmpInfoSize, bi.biSizeImage, &bytesWritten,
NULL);
CloseHandle(hFile);
DeleteObject (hBitmap);
DeleteObject (hOldBitmap);
DeleteDC(hScrDC);
DeleteDC(hMemDC);
return TRUE;
}