I'm trying to get a window, whose HWND I know, grab it's DC, and essentially take a screenshot of it (into an HBITMAP) and then crop a section of it out.
However, the code I've had for this is giving me an access denied 0xC00005 error because SOME pointer is NULL...
If it helps, the debugger breaks in strlen.c... but I don't use strlen anywhere, so... yeah.
Here's all my relevant code:
- Code: Select all
RGBQUAD* CaptureScreen(HWND window)
{
HDC WinDC;
HDC CopyDC;
HBITMAP hBitmap;
ULONG bWidth, bHeight;
WinDC = GetDC (window);
CopyDC = CreateCompatibleDC (WinDC);
RECT rect;
GetWindowRect(window, &rect);
bWidth = abs(rect.right-rect.left);
bHeight = abs(rect.bottom - rect.top);
hBitmap = CreateCompatibleBitmap(WinDC, bWidth, bHeight);
SelectObject(CopyDC, hBitmap);
BitBlt(CopyDC, 0, 0, bWidth, bHeight, WinDC, 0, 0, SRCCOPY);
ReleaseDC(window, WinDC);
DeleteDC(CopyDC);
RGBQUAD *image;
try{
image = new RGBQUAD[bWidth*bHeight];
}
catch(std::bad_alloc)
{
return NULL;
}
GetBitmapBits(hBitmap, bWidth*bHeight*4, image);
DeleteObject(hBitmap);
return image;
}//I know this isn't returning NULL because I can see the pointer value in my debugger
RECT GetTheBox(HWND hwnd)
{
RECT returnval;
POINT pt1, pt2;
pt2.x = pt1.x = 0;//rect.left;
pt2.y = pt1.y = 0;//rect.top;
pt1.x += 450;
pt1.y += 319;
pt2.x += 558;
pt2.y += 338;
returnval.bottom = pt2.y;
returnval.left = pt1.x;
returnval.right = pt2.x;
returnval.top = pt1.y;
return returnval;
}
RGBTRIPLE *Crop(RGBQUAD *image, unsigned int width, unsigned int height, RECT crop)
{
RGBTRIPLE *newimage;
try{
newimage = new RGBTRIPLE[abs(crop.bottom-crop.top)*abs(crop.right-crop.left) + 4];
}
catch(std::bad_alloc)
{
return NULL;
}
unsigned int j = 0;
for(unsigned int i = 0; i < width*height; ++i)
{
int curx, cury;
curx = i % width;
cury = i / width;
if(curx >= crop.left && curx <= crop.right)
{
if(cury >= crop.top && cury <= crop.bottom)
{
newimage[j].rgbtBlue = image[i].rgbBlue;
newimage[j].rgbtRed = image[i].rgbRed;
newimage[j].rgbtGreen = image[i].rgbGreen;
++j;
}
}
}
return newimage;
}
RGBTRIPLE Average(RGBTRIPLE *image, unsigned int height, unsigned int width)
{
unsigned int red = 0, green = 0, blue = 0;
for(unsigned int i = 0; i < height*width; ++i)
{
red += image[i].rgbtRed;
green += image[i].rgbtGreen;
blue += image[i].rgbtBlue;
}
red /= (height*width);
green /= (height*width);
blue /= (height*width);
RGBTRIPLE rgbt;
rgbt.rgbtRed = red;
rgbt.rgbtBlue = blue;
rgbt.rgbtGreen = green;
return rgbt;
}
RGBTRIPLE GetAverageBoxColor(HWND hwnd)
{
RGBTRIPLE *rgbq;
RGBTRIPLE *rgbt;
RGBTRIPLE avg;
rgbq = CaptureScreen(hwnd);
rgbt = Crop(rgbq, 1024, 715, GetMyBox(hwnd));
avg = Average(rgbt, 19, 108);
delete [] rgbq;
delete [] rgbt;
std::cout << "Average: (" << (int)avg.rgbtRed << ", " << (int)avg.rgbtGreen << ", " << (int)avg.rgbtBlue << ")." << std::endl;
return avg;
}
Any help?
Thanks!
