Skip to main content
GameDev.net gamedev.net
🔒 Locked

Static Control

Started by Progames25 Feb 21, 2009 at 7:47 PM 7 replies 1.8k views
Original Post
Progames25
Progames25
Hello, In the Win32 API C++, I was trying to create a Static control to show a bitmap image, but I could not get it to work right and it messed up my window(bitmaps). Can anyone shoe me an example or give me a URL to an example of how to correctly do this if the bitmap if defined as a resource (IDB_IMAGE)? What I am currently doing to show bitmaps is using a PAINTSTRUCTURE and HBITMAP, HDC, CreateObject, BitBlt, all that stuff in the WM_PAINT, but becuase of the way my program is the entire window is filled with bitmaps (a large background image, a large header and two others) and sometimes the window will flicker when doing thigns and im hoping using a static control to show the bitmap might help take some of that away... (PS. Any reason why Visual Studio 2008 won't compile bitmaps that are not 4bit or lower? I'm trying to include some 8bit and higher bitmaps in my reosurces but the compiler does not like them becuase they are not 4bit...) Thanks, Progames25
-----------------------------I use C++ and DirectX.I'm new to game programming.
CrazyCdn
CrazyCdn
I love the catch22.net site, likely one of the best out there for Win32 stuff...

You should find what your looking for in one of the tutorials or try this site (under code he has a lot of Win32 stuff, check out the source code).

Also if you check out the MSDN page on static controls it says you can use the SS_ICON style to assign a bitmap to it... Or use SendMessage with STM_SETICON and a handle to the icon (HICON) in the wParam...

Hope that helps...
"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin
Colin Jeanne
Colin Jeanne
Quote:
Original post by Mike2343
Also if you check out the MSDN page on static controls it says you can use the SS_ICON style to assign a bitmap to it... Or use SendMessage with STM_SETICON and a handle to the icon (HICON) in the wParam...


SS_ICON is for icons only. You want SS_BITMAP and then to use STM_SETIMAGE.

To reduce flicker without needing a static control make sure to render your bitmap (and the entire window) on a memory DC rather than directly onto your window. There is a brief tutorial on double buffering in Win32 is here and I have a showcase entry which uses double buffering here.
CrazyCdn
CrazyCdn
Doh! I even knew that (someplace in the void I call a brain) too, which makes it that much worse. Thanks for the catch.
"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin
Progames25
Progames25
Ok, so im looking at the double buffering tutorial on catch22.net.
It shows this source for making a double buffr, but I honestly don't see how it will copy all the bitmaps I have into it, I don't see anything doing that type of thing, so i'm a little confused. This is what the sample code is from catch22.net:
[source = cpp]HDC          hdcMem;HBITMAP      hbmMem;HANDLE       hOld;PAINTSTRUCT  ps;HDC          hdc;....case WM_PAINT:    // Get DC for window    hdc = BeginPaint(hwnd, &ps);    // Create an off-screen DC for double-buffering    hdcMem = CreateCompatibleDC(hdc);    hbmMem = CreateCompatibleBitmap(hdc, win_width, win_height);    hOld   = SelectObject(hdcMem, hbmMem);    // Draw into hdcMem    // Transfer the off-screen DC to the screen    BitBlt(hdc, 0, 0, win_width, win_height, hdcMem, 0, 0, SRCCOPY);    // Free-up the off-screen DC    SelectObject(hdcMem, hOld);    DeleteObject(hbmMem);    DeleteDC    (hdcMem);    EndPaint(hwnd, &ps);    return 0; 

So this is what my current code looks like (I put it all into one function, that would be called in WM_PAINT), I cut out msot of it because some parts are 5 of the same thing, just set for a different bitmap...so you can see where I did this I will put this: //repeat
[source = cpp]PAINTSTRUCT ps;	HDC hDC = NULL, MemDCBackg = NULL, MemDCBackh = NULL, MemDCBacks = NULL, 		MemDCPicture = NULL, MemDCPMASK = NULL;	HBITMAP bmpBackg = NULL;	//repeat - 4 times	//-------------------------	hDC = BeginPaint(hWnd, &ps);		// Load the bitmap from the resource	    bmpBackg	= LoadBitmap(hInst, MAKEINTRESOURCE(IDB_Main_Background));		//repeat 4 times		// Create a memory device compatible with the above DC variables	    MemDCBackg = CreateCompatibleDC(hDC);	    //repeat 4 times        // Select the new bitmap        SelectObject(MemDCBackg, bmpBackg);		//repeat 4 times	    BitBlt(hDC, 0, 0, 671, 526, MemDCBackg, 0, 0, SRCCOPY);		//repeat 4 times	    // Restore the old bitmap	    DeleteDC(MemDCBackg);		//repeat 4 times	    DeleteObject(bmpBackg);		//repeat 4 times		EndPaint(hWnd, &ps);

So, I am not the best with Win32 API drawing, so if this is bad (doing everything practically 5 times), thats why. So I want all this to work with the double buffer code from the tutorial, but I don't see how to make all these work with that...

Thanks,
Progames25
-----------------------------I use C++ and DirectX.I'm new to game programming.
Colin Jeanne
Colin Jeanne
BeginPaint() and EndPaint() only need to be called once during WM_PAINT. You can pull those out of the loop.

The basic idea of double buffering works like this:
You make a DC in memory with a bitmap the same size as the region you're painting - in this case your client area. Use CreateCompatibleDC() and CreateCompatibleBitmap() for this passing in the DC you get from BeginPaint(). Note: CreateCompatibleBitmap() is very necessary as the default bitmap in a DC is a 1x1 monochrome bitmap and you dont want to be drawing onto that!

You'll probably have some bitmap resources that you want to draw onto the background. Each of these will need to be in its own DC so that you can use BitBlt() to copy them to your background DC. They dont all have to use a different DC, you could use one for all of them and just use SelectObject() to select the appropriate bitmap into the DC before you use BitBlt(). If you only have a handful of bitmaps then keeping them all in their own DC isnt a big deal (this is what my CBitmap class does in the showcase I posted).

Once you're done drawing everything to the background DC you need to use BitBlt() to copy the bitmap that you've finished drawing into your window's client area. To do this use BitBlt() with the source DC as your background DC and the destination DC as the one you got from BeginPaint().

Now you're done, call EndPaint().
Progames25
Progames25
ok, so this would be an example of what I would do just for one of my bitmaps?
(Between Start and End paint)
// Create an off-screen DC for double-buffering    hdcMem = CreateCompatibleDC(hdc);    hbmMem = CreateCompatibleBitmap(hdc, 677, 526);    hOld   = SelectObject(hdcMem, hbmMem);    // Draw into hdcMem    bmpBackg	= LoadBitmap(hInst, MAKEINTRESOURCE(IDB_Main_Background));    MemDCBackg = CreateCompatibleDC(hDC);        // Transfer the off-screen DC to the screen    BitBlt(hDC, 0, 0, 671, 526, MemDCBackg, 0, 0, SRCCOPY);    BitBlt(hdc, 0, 0, 677, 526, hdcMem, 0, 0, SRCCOPY);    // Free-up the off-screen DC    SelectObject(hdcMem, hOld);    SelectObject(MemDCBackg, bmpBackg);    DeleteObject(hbmMem);    DeleteObject(MemDCBackg);    DeleteDC    (bmpBackg);    DeleteDC    (hdcMem);
-----------------------------I use C++ and DirectX.I'm new to game programming.
Colin Jeanne
Colin Jeanne
You need to select bmpBackg into MemDCBackg before you blit MemDCBackg onto MemDC and you need to keep track of the old bitmap returned by that SelectObject() call so that you can return the DC to its original state before destroying it.
Progames25
Progames25
Thanks,
I think I have it all working now...I ahve not seen any big flickers.
-----------------------------I use C++ and DirectX.I'm new to game programming.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.