Sign in to follow this  
TheSkywise

Bitmap Questions: Copy, cutting, etc...

Recommended Posts

TheSkywise    122
Ok, I am learning bitmaps using windows. I have a couple of questions: 1) If I have a HBITMAP varible, can I copy it using something like this? hBitmap1 = hBitmap2; // Will this make 2 identical bitmaps or two // pointers to same bitmap object? Or do I need to make a "new" HBITMAP and dereference it (is it a pointer or not)? Basically, is HBITMAP a pointer? Also, don't just tell me the answer, also tell me where I could look for it myself (for future reference). I tried using F12 to go to the defination (using msvc++ 6.0), but it does not take me to the actual definition... 2) I am making my own bitmap class. I have a working function to load a bitmap from a file. I would also like to have a member function that takes a resource id, and loads it. How do you pass resource IDs as parameter (I'm sure it's possible, but I don't know how. Maybe once I find out how to copy HBITMAPS, I can use that as a member function). 3) I have a bitmap that I want to cut/copy into smaller bitmaps (tiles, ships, etc...). What functions should I look at to accomplish this goal, or how should I do it (or even tell me "Look at such-and-such article, you bonehead" hee hee). By the way, I have searched the forum, and checked my books, but I can't find the answer in plain english (my game book describes doing something like this, but it uses DirectX, which I am not quite ready to tackle yet till I learn the basics). Any help with these problems would be great. Thank you. Skywise. (I also tried asking the C++ newsgroups, but they get their panties in a knot whenever I ask them anything that is not "STANDARD" C++).

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by TheSkywise
1) If I have a HBITMAP varible, can I copy it using something like this?

hBitmap1 = hBitmap2; // Will this make 2 identical bitmaps or two
// pointers to same bitmap object?

Or do I need to make a "new" HBITMAP and dereference it (is it a pointer or not)? Basically, is HBITMAP a pointer? Also, don't just tell me the answer, also tell me where I could look for it myself (for future reference). I tried using F12 to go to the defination (using msvc++ 6.0), but it does not take me to the actual definition...
A HBITMAP is a handle. Its a unique ID that windows uses to refer to a bitmap. Its not a pointer (actually, its typef'ed as a void*, but just ignore that, it could just as easily be an integer), so you can't dereference it. In the above code, it gives you 2 handles to one object.
To copy the bitmap, I think the only way is to create a new bitmap of the same size, and copy the contents over (see below on how to do this)

Quote:
Original post by TheSkywise
2) I am making my own bitmap class. I have a working function to load a bitmap from a file. I would also like to have a member function that takes a resource id, and loads it. How do you pass resource IDs as parameter (I'm sure it's possible, but I don't know how. Maybe once I find out how to copy HBITMAPS, I can use that as a member function).
LoadImage() is the function you want. It allows you to load bitmaps from resoruces or files. Example, assuming hInstance is the HINSTANCE to your app, and the bitmap is a resource as IDB_BITMAP:
HBITMAP hBmp = (HBITMAP)LoadImage(hInstance,MAKEINTRESOURCE(IDB_BITMAP),IMAGE_BITMAP,0,0,LR_DEFAULTSIZE);

Quote:
Original post by TheSkywise
3) I have a bitmap that I want to cut/copy into smaller bitmaps (tiles, ships, etc...). What functions should I look at to accomplish this goal, or how should I do it (or even tell me "Look at such-and-such article, you bonehead" hee hee).
This is the difficult part :P You need to create a device context with CreateDC(), select the HBITMAP into it with SelectObject(), and use BitBlt to blit the image to another device context, which should contain your target bitmap.

EDIT: Here's some example code for duplicating a bitmap. This is off the top if my head, so don't expect it to work first time :P

HBITMAP DuplicateBitmap(HBITMAP hBmp)
{
HBITMAP hBmpRet;
BITMAP bmpInfo;
HDC hdcSource, hdcDest;
HBITMAP hbmpSrcOld, hbmpDestOld;

// First, see what size the input image is //
if(!GetObject(hBmp,sizeof(bmpInfo),(void*)&bmpInfo))
return NULL;

// Create the target image //
hBmpRet = CreateBitmapIndirect(&bmpInfo);
if(!hBmpRet)
return NULL;

// Create source DC //
hdcSource = CreateCompatibleDC(NULL);
if(!hdcSource)
{
DeleteObject(hBmpRet);
return NULL;
}

// Create destination DC //
hdcDest = CreateCompatibleDC(NULL);
if(!hdcDest)
{
DeleteDC(hdcSource);
DeleteObject(hBmpRet);
return NULL;
}

// Select bitmaps into DCs //
hbmpSrcOld = (HBITMAP)SelectObject(hdcSource,hBmp);
hbmpDestOld = (HBITMAP)SelectObject(hdcDest,hBmpRet);

// BitBlt from the source to destination DCs //
BitBlt(hdcDest,0,0,bmpInfo.bmWidth,bmpInfo.bmHeight,hdcSource,0,0,SRCCOPY);

// Put the old HBITMAPS back into the DCs and free them - IMPORTANT! //
SelectObject(hdcSource,hbmpSrcOld);
SelectObject(hdcDest,hbmpDestOld);
DeleteDC(hdcDest);
DeleteDC(hdcSource);

// Return the copied bitmap //
return hBmpRet;
}





EDIT 2: I'm not sure if you know this already, but anyway... A device context is like a board. A HBITMAP is like a piece of paper. Using SelectObject(), you pin the paper to the board (the HBITMAP to the HDC), and you take the old piece of paper off (the return value of SelectObject()). You can then draw on it however you like (with BitBlt() in this case).
When you're done, you need to put the old bit of paper back on the board, and take your piece off. If you don't do this, you'll end up with a spare piece of paper (which is a resource leak).
Then you can get rid of the board all together (DeleteDC), and you have your image drawn on your paper (HBITMAP).

Share this post


Link to post
Share on other sites
Evil Steve    2017
A resource ID is just an integer. So you'd have your function take an integer. E.g:

HBITMAP LoadBitmap(HINSTANCE hInstance, int nResource)
{
return (HBITMAP)LoadImage(hInstance,MAKEINTRESOURCE(nResource),IMAGE_BITMAP,0,0,LR_DEFAULTSIZE);
}


Its often a good idea to pass an HINSTANCE to any function that loads resources, because this way you can pass a different HINSTANCE than the application one, so you can easily load resources from DLLs.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
Not to say that Evil Steve didn't do a good job explaining things, but for completeness sake, there's already an API function, CopyImage, that will create a duplicate bitmap for you.

Also, the LoadImage example isn't quite right: using LR_DEFAULTSIZE will not get you a correctly sized bitmap; you'll want to use LR_DEFAULTCOLOR or 0 instead, or possibly one or more of the other available flags, depending upon your exact requirements.

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