triumphost 120 Posting Whiz

I have the following code to take a bitmap of a portion of the screen specified by the Box Area.

Area is just a struct that holds Width, Height, X1, Y1, X2, Y2 and represents a box. Basically a RECT with additional features.

For some reason, if Box is (0, 0, 100, 100); It will take a perfect screenshot of the 100x100 area. If Box's X1 or Y1 is more than 0 (Ex: (10, 10, 110, 110); It will take a screenshot that is 100x100, except that the first 10 rows and columns will be black! It also does this for any window that I specify that is not the desktop. I cannot figure out why! I tried everything from changing Bitblt to the correct area and offsets, etc.

Any Ideas?

Bitmaps::Bitmaps(HWND Window, Box Area, uint32_t BitsPerPixel) : Pixels(nullptr), width(Area.W), height(Area.H), size(0), TransparentColor(Rgb(0)), DC(0), Image(0)
{
    memset(&Info, 0, sizeof(BITMAPINFO));
    HDC hdc = GetDC(Window);
    BITMAP bmp;
    HBITMAP hbmp = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);

    if (GetObject(hbmp, sizeof(BITMAP), &bmp) == 0)
        ErrorMessage(ERROR_INVALID_WINDOW_HANDLE);

    width = (Area.W == 0) ? bmp.bmWidth : Area.W;
    height = (Area.H == 0) ? bmp.bmHeight : Area.H;

    HDC MemDC = GetDC(0);
    HDC bufferDC = CreateCompatibleDC(MemDC);
    HBITMAP bufferBitmap = CreateCompatibleBitmap(MemDC, width, height);
    DeleteObject(SelectObject(bufferDC, bufferBitmap));

    BitBlt(bufferDC, Area.X1, Area.Y1, width, height, hdc, Area.X1, Area.Y1, SRCCOPY);
    size = ((width * BitsPerPixel + 31) / 32) * 4 * height;

    Info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    Info.bmiHeader.biWidth = width;
    Info.bmiHeader.biHeight = height;
    Info.bmiHeader.biPlanes = 1;
    Info.bmiHeader.biBitCount = BitsPerPixel;
    Info.bmiHeader.biCompression = BI_RGB;
    Info.bmiHeader.biSizeImage = size;
    bFileHeader.bfType = 0x4D42;
    bFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(Info.bmiHeader);
    bFileHeader.bfSize = bFileHeader.bfOffBits + size;

    unsigned char* TEMP = new unsigned char[size];
    GetDIBits(bufferDC, bufferBitmap, 0, height, TEMP, &Info, DIB_RGB_COLORS);

    DeleteDC(bufferDC);
    DeleteObject(bufferBitmap);
    ReleaseDC(0, MemDC);
    ReleaseDC(Window, hdc);

    unsigned char* BuffPos = TEMP;
    height = (height < 0 ? -height : height);
    Pixels = new RGB[width * height];
    for (int I = 0; I < height; I++)
    {
        for (int J = 0; J < width; J++)
        {
            Pixels[(height - 1 - I) * width + J].RGBA.B = *(BuffPos++);
            Pixels[(height - 1 - I) * width + J].RGBA.G = *(BuffPos++);
            Pixels[(height - 1 - I) * width + J].RGBA.R = *(BuffPos++);
            Pixels[(height - 1 - I) * width + J].RGBA.A = (Info.bmiHeader.biBitCount > 24 ? *(BuffPos++) : 0);
        }
        if(Info.bmiHeader.biBitCount == 24)
            BuffPos += width % 4;
    }
    delete[] TEMP;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of 1.21 million developers, IT pros, digital marketers, and technology enthusiasts learning and sharing knowledge.