Taking a screenshot (winapi)

I need some help with winapi
I already posted this in the windows forum, but in my experience this one is more active^^
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
HDC hScreenDC = CreateDC(L"DISPLAY", NULL, NULL, NULL);
HDC hMemoryDC = CreateCompatibleDC(hScreenDC);

int x = GetDeviceCaps(hScreenDC, HORZRES);
int y = GetDeviceCaps(hScreenDC, VERTRES);

HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, x, y);

HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, hBitmap);      

BitBlt(hMemoryDC, 0, 0, x, y, hScreenDC, 0, 0, SRCCOPY);
hBitmap = (HBITMAP)SelectObject(hMemoryDC, hOldBitmap);               

DeleteDC(hMemoryDC);
DeleteDC(hScreenDC);


HDC hdc=CreateCompatibleDC(NULL);


BITMAPINFO bmi;
bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth=x;
bmi.bmiHeader.biHeight=y;
bmi.bmiHeader.biPlanes=1; 
bmi.bmiHeader.biBitCount=32;
bmi.bmiHeader.biCompression=BI_RGB;
bmi.bmiHeader.biSizeImage=0;
bmi.bmiHeader.biXPelsPerMeter = 0;
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;

BYTE values[3*1280*200];

int lines=GetDIBits(hdc,hBitmap,1,200,values,&bmi,DIB_RGB_COLORS);

I'm trying to take a screenshot, and then get the rgb values for each pixel from the bitmap.

I copied the first part from http://stackoverflow.com/questions/3291167/how-to-make-screen-screenshot-with-win32-in-c and tried to somehow come up with the rest myself.. and as expected it didn't turn out as I had hoped.

Converting the values results in a mostly black picture with a few lines of randomly coloured pixels at the bottom.

Help would be appreciated a lot
bump
BYTE values[3*1280*200];

This looks very wrong to me.

You have a 32-bit bitmap which means 4 bytes per pixel (not 3) and you are hardcoding dims there. Wouldn't this make more sense?

 
BYTE values[4*x*200];


EDIT: right, but x isn't constant. Oh well, something this large should probably go on the heap anyway:

 
std::unique_ptr<BYTE[]> values( new BYTE[4*x*200] );
Last edited on
Thanks for the reply, Disch, got it working!

About the hardcoding, I'm gonna change all that later anyway. This was just to get the program to work.

I haven't learned dynamic memory allocation yet (well, except arrays), so I'll need to call delete[] values;, right?
Not if you use a smart pointer like unique_ptr as I did in that example. unique_ptr will automatically delete.

As time goes on, I'm more and more of the opinion that you should always use smart pointers for dynamic memory. Having to manually delete is a bad idea because it's easy to forget and can be error prone (deleting the same thing multiple times, etc).
All right, I got a lot of reading to do, didn't even know that existed ^^
Just one more thing- what can I do about
>main.cpp(182): error C2664: 'GetDIBits' : cannot convert parameter 5 from 'std::unique_ptr<_Ty>' to 'LPVOID'
1>          with
1>          [
1>              _Ty=BYTE []
1>          ]
1>          No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called


EDIT: Looked it up.. damn you VS2010
Last edited on
Just in case...

if values is a unique_ptr<BYTE[]>....

then values.get() is a BYTE*, which can be implicitly cast to a LPVOID.
Thank you again!
You should really get paid to answer these questions ^^
Topic archived. No new replies allowed.