0

I have some problem with my designs for function, and I do not find a proper solution (I am quite a beginner in C++).

Some days ago, I ask another question which is linked to this one.

So, I have a function that makes a screen capture. It works perfectly. The fact is that I want this function to return an Image object from a class I implemented.

Basically, it is:

class Image {
public:
    BYTE *bitPointer;
    int width;
    int height;
};

And my function is like this one:

Image screenCapture(int width, int height) {

    HDC hdcTemp, hdc;
    BYTE* bitPointer;

    hdc = GetDC(HWND_DESKTOP);
    hdcTemp = CreateCompatibleDC(hdc);

    BITMAPINFO bitmap;
    bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader);
    bitmap.bmiHeader.biWidth = width;
    bitmap.bmiHeader.biHeight = -height;
    bitmap.bmiHeader.biPlanes = 1;
    bitmap.bmiHeader.biBitCount = 24;
    bitmap.bmiHeader.biCompression = BI_RGB;
    bitmap.bmiHeader.biSizeImage = 0;
    bitmap.bmiHeader.biClrUsed = 0;
    bitmap.bmiHeader.biClrImportant = 0;
    HBITMAP hBitmap = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)(&bitPointer), NULL, NULL);
    SelectObject(hdcTemp, hBitmap);
    BitBlt(hdcTemp, 0, 0, width, height, hdc, 0, 0, SRCCOPY);
    ReleaseDC(HWND_DESKTOP, hdc);
    DeleteDC(hdcTemp);

    Image screen;
    screen.bitPointer = bitPointer;
    screen.width = width;
    screen.height = height;

    return screen;
}

The bitPointer created using CreateDIBSection is actually a pointer to the value of my first pixel (if I understood well).

Then, I can use a simple loop:

for (int i = 0; i >= 0; i++) {
        cout << i << ": " << (int)screenCapture(1366, 768).bitPointer[0] << endl;
    }

Here is my issue.

I have to free up the hBitmap by calling DeleteObject(hBitmap) otherwise I would have no more memory space (and the loop finally crash).

However, I do not know where to do it.

I would like to do it within my function but if I call DeleteObject(), then it will destroy my bitPointer too and therefore I will not be able to access pixels from my Image object returned. In fact, I am a little confused with the fact that my bitPointer variable is a pointer. It means that I can not copy it to prevent it being destroyed after. I can not find the solution.

Two solutions I have tried:

  • Create a destructor calling DeleteObject() for my class Image.
    It did not work because the destructor is call from the function and not only from inside my loop.
  • Add an attribute HBITMAP hBitmap to my class Image, and call DeleteObject() from inside my loop.
    It is not really convenient, moreover I have to declare a new Image object, I can not do it anonymously like in the loop I writed.

So, I am stuck, could anyone help me please?

Community
  • 1
  • 1
Delgan
  • 18,571
  • 11
  • 90
  • 141
  • You are doing nothing with the local `BYTE* bitPointer;` but assigning it to `screen.bitPointer = bitPointer;` –  Oct 09 '14 at 19:05
  • Why are you returning an 'Image' type as an integer? – Martin James Oct 09 '14 at 19:06
  • You can add the HBITMAP hBitmap member and return 'screen' by value. It's not very big, so should be fine. Like @DieterLücking says, why bother with the local? Just 'CreateDIBSection' straight into screen. If the bitmap and the HBITMAP handle are bound to each other, they should be in the same struct/instance and the 'Image' dtor can do away with them both. – Martin James Oct 09 '14 at 19:21
  • @MartinJames The int returned was an copy/paste mistake. And @DieterLücking and you are right, my local bitPointer was useless, thank you. However, could you please submit an answer with what you are talking about? Because I am not sure to completly understand... Actually, I do not understand how the `Image` destructor can be useful because it will never call `DeleteObject()` by itself, I have to do it. Finally, I can not see any other solution than @VAndrei's one. – Delgan Oct 09 '14 at 20:52

1 Answers1

1

You can pass hBitmap as an argument to screenCapture function.

screenCapture(int width, int height, HBITMAP& hBitmap)

This way you get to destroy it when you want without interfering with Image members. You declare an "empty" hBitmap outside screenCapture function and pass it as argument. The function will use the reference to create the object and you will be able to destroy it outside of screenCapture after you are done with using bitPointer values.

If you need storing all screenshots, you need to implement a working buffer as you have finite amount of memory.

VAndrei
  • 5,420
  • 18
  • 43