Sign in to follow this  
noNchaoTic

spot the problem...

Recommended Posts

Can anyone see why this isn't working?
HBITMAP	CopyBitmap(HBITMAP hbm, int Width, int Height, int BlitX, int BlitY)
{
	HDC Source = CreateCompatibleDC(NULL);
	HDC Destin = CreateCompatibleDC(NULL);
	
	HBITMAP	hbmOld, hbmOld2, hbmNew;
	BITMAP	bm;
			
	GetObject(hbm, sizeof(bm), &bm);

	hbmOld = (HBITMAP)SelectObject(Source, hbm);
	hbmNew = CreateBitmap(Width, Height, bm.bmPlanes, bm.bmBitsPixel, NULL);
	hbmOld2 = (HBITMAP)SelectObject(Destin, hbmNew);

	BitBlt(Destin, 0, 0, Width, Height, Source, BlitX, BlitY, SRCCOPY);
	
	SelectObject(Source, hbmOld);
	DeleteDC(Source);
	SelectObject(Destin, hbmOld2);
	DeleteDC(Destin);

	return hbmNew;
}
Im stumped :-(

Share this post


Link to post
Share on other sites
I can't see anything obviously wrong, but from experience, when something like this doesn't work, it's due to incompatible DCs and bitmaps.

Try specifying a DC in CreateCompatibleDC() and use CreateCompatibleBitmap() rather than create bitmap.

Use GetDC(GetDesktopWindow()) as your DC for these functions, just to be on the safe side.

Share this post


Link to post
Share on other sites
Quote:
Original post by noNchaoTic
So use the windows handle to get the handle to DC, and then use CreateCompatibleBitmap increate of just CreateBitmap?


Yes. Make sure you use the original DC and NOT the compatible DC in the call to CreateCompatibleBitmap though.

I'm not 100% sure this will fix your problem though. GDI can be kind of annoying in that things just silently fail with little or no useful feedback as to *why* they've failed, so it can take a bit of fiddling around and trial and error to get things working.

Share this post


Link to post
Share on other sites
Re-read your post, and am now using GetDesktopWindow(), getting a DC for that, and then using that to obtain a compatible DC. Its succeeding to obtain DCs for these, but still nothing... :-(

Share this post


Link to post
Share on other sites
Thats just it, the function returns propertly, all the pointers !NULL. And in theory it worked... but in practice, i have no idea wtf is up. lol, Cheers for your time :-) If anyone else has any ideas i'd be very grateful for the suggestions.

Share this post


Link to post
Share on other sites
Quote:
Original post by noNchaoTic
Thats just it, the function returns propertly, all the pointers !NULL. And in theory it worked... but in practice, i have no idea wtf is up. lol, Cheers for your time :-) If anyone else has any ideas i'd be very grateful for the suggestions.


Yes, this is one of the annoying things about GDI, it gives you no feedback as to what's wrong.

I don't really know what to suggest beyond trial and error with different DCs and so on. Or if you like, post a zip of your project and I'll see if I can fix it when I've got a minute.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sandman
Yes, this is one of the annoying things about GDI, it gives you no feedback as to what's wrong.



Actually on NT/XP/2K a call to GetLastError() generally gives enough information to figure out why the call failed.

Share this post


Link to post
Share on other sites
Quote:
Original post by noNchaoTic
Can anyone see why this isn't working?




1. Do not switch to GetDC() as suggested. The operation you are attempting to perform is not associated with a window DC. CreateCompatibleDC() should be used as it will create a memory DC compatible with the display (rather than being directly owned/associated with the display).

2. You should still use the CreateCompatibleBitmap() as already suggested.

3. If the source bitmap is palettized (256) you may need to set (realize) the palette in the source device context in order for it to be rendered (otherwise the result may be blank or discolored).

4. Since the dimensions of the bitmap are accessible in the BITMAP data structure there's really no reason to pass the width and height - UNLESS you are resizing the image (i.e. 16x16 to 32x32) in which case you need to call StretchBlt

5. Make sure that (BlitX + Width) and (BlitY + Height) do NOT go past the boundries of the source bitmap. Windows only clips against the destination device context.

6. If the bit depth of the image used by Destin does not match the DC the blt calls may fail.

Share this post


Link to post
Share on other sites
Quote:
1. Do not switch to GetDC() as suggested. The operation you are attempting to perform is not associated with a window DC. CreateCompatibleDC() should be used as it will create a memory DC compatible with the display (rather than being directly owned/associated with the display).


I've tried both, and creating a DC from NULL.

Quote:
2. You should still use the CreateCompatibleBitmap() as already suggested.


Already done.

Quote:
3. If the source bitmap is palettized (256) you may need to set (realize) the palette in the source device context in order for it to be rendered (otherwise the result may be blank or discolored).


Source image is 24 bit, and the destination is using the

Quote:
4. Since the dimensions of the bitmap are accessible in the BITMAP data structure there's really no reason to pass the width and height - UNLESS you are resizing the image (i.e. 16x16 to 32x32) in which case you need to call StretchBlt.


Well, I want the function to support copying a portion of the image, so I think thats the best way of doing that? I.e.: copy a rectangle 64x64, starting a BlitX, BlitY... But if you know a better way im open to that for sure. :-)

Quote:
5. Make sure that (BlitX + Width) and (BlitY + Height) do NOT go past the boundries of the source bitmap. Windows only clips against the destination device context.


I will add this check, thanks for the info, but I am trying to Copy a chunk 64x64 starting from 0, 0, out of an image 256x256... so shouldn't be this causing the issue.

Quote:
6. If the bit depth of the image used by Destin does not match the DC the blt calls may fail.


As the image is being created with the same bitsPerPixel as the original I dont think its this? At least it was, CreateCompatibleBitmap should create a 24 bit image right? If not how can I ensure this?


Thanks.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this