Link to home
Start Free TrialLog in
Avatar of Unimatrix_001
Unimatrix_001Flag for United Kingdom of Great Britain and Northern Ireland

asked on

Problems with Bitmap and HBITMAP

Hi,

I'm getting a runtime error on the indicated line in the code below, the problem is that p is NULL as is data.Scan0. Below is the debug output of the variable data members:

Width            3435973836      unsigned int
Height            3435973836      unsigned int
Stride            -858993460      int
PixelFormat      -858993460      int
Scan0            0xcccccccc      void *
Reserved      3435973836      unsigned int

I'm guessing that somewhere down the line that data isn't being assigned to the BitmapData correctly. Anybody care to help?

Thanks,
Uni
void CScreenCapture::initialise(unsigned int aWidth, unsigned int aHeight, unsigned int aPosX, unsigned int aPosY){
	width=aWidth;
	height=aHeight;
	posX=aPosX;
	posY=aPosY;
	hDC=CreateCompatibleDC(NULL);
	hCapturedScreen=CreateCompatibleBitmap(GetDC(NULL), width, height);
}
 
void CScreenCapture::captureScreen(){
	SelectObject(hDC, hCapturedScreen);
	BitBlt(hDC, 0, 0, width, height, GetDC(NULL), posX, posY, SRCCOPY);
	convertPixels();
}
 
void CScreenCapture::convertPixels(){
	Bitmap bitmap(hCapturedScreen, NULL);
	BitmapData data;
	Rect rect(0, 0, bitmap.GetWidth(), bitmap.GetHeight());
	if(bitmap.LockBits(&rect, ImageLockModeRead, PixelFormat24bppRGB, &data)){
		LPBYTE pPixelData=(LPBYTE)data.Scan0;
		unsigned char *p;
		pixels.clear();
		for(unsigned int y=0;y<data.Height;y++){
			p=((unsigned char*)data.Scan0)+(y*data.Stride);
			vector<COLORREF> temp;
			for(unsigned int x=0;x<data.Width;x++,p+=3)
				temp.push_back(RGB(p[2], p[1], p[0])); /////////////////// ERROR HERE.
			pixels.push_back(temp);
		}
		bitmap.UnlockBits(&data);
	}
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of JohnGaby
JohnGaby
Flag of Afghanistan image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Unimatrix_001

ASKER

Ahh... Yes, that seems to be it. :)
10/10. Thank you. :)
There is another possible problem.  In the documentation for the Bitmap constructor that takes a HBITMAP, it says:

Do not pass to the GDI+ Bitmap constructor a GDI bitmap or a GDI palette that is currently (or was previously) selected into a device context.

And it seems that you are passing in a HBITMAP that is still selected into DC.  You need to save the return from your SelectObject(hDC, hCapturedScreen) and then select that back into the DC after you do your BitBlt.

Also, as a final note, you are using CreateCompatibleBitmap to create your bitmap.  I am not sure that that will yield a Device Independent bitmap.  If you have trouble with it, you might consider using CreateDIBSection instead.

http://msdn.microsoft.com/en-us/library/ms536314(VS.85).aspx
http://msdn.microsoft.com/en-us/library/dd183494(VS.85).aspx
Hm, to be honest I'm not too clever with this sort of windows programming, I've just cobbled things together from things I've picked up over the net, although it seems to be working fine for now. Nevertheless, I'll see about making the changes you've proposed.

Thank you,
Uni.
If your CreateCompatibleBitmap is working, I see not need to change that.  I only mentioned it in case you had problems.

However, I would fix the issue with the bitmap being selected into the DC when you create the Bitmap, since the documentation specifically tells you not to do that.