Jump to content
  • Advertisement
Sign in to follow this  
Boltimus

Device Context has a memory???

This topic is 4769 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm drawing on a window I created with text using the textout function. Basically if one event occurs, then one thing is written to the screen (via textout) and if another occurs then another text should be output. The thing is, I would think that once I called DeleteDC to delete the temp DC and EndPaint, that any memory of what was written would be erased. Thr problem is, when one event is over and I write to the screen the next event occuring, it still shows event 1. below is a code snippet....
case WM_PAINT:

/* display the main window first --------------------------*/
	hdc  = BeginPaint(hWnd, &ps);
	hdc2 = CreateCompatibleDC(hdc);
	SelectObject(hdc2, MainWindow_SCREEN);
	SetBkColor(hdc2, RGB(167,167,167));

	switch (event_mode){

	  case EVENT1: // display event 1

		TextOut(hdc2, 295, 100, "EVENT1", 6);

		break;

	  case EVENT2: // display event 2

		TextOut(hdc2, 344, 30, "EVENT2", 6);

		break;

	} // end switch

	// now blt everything from the back buffer hdc2 to the main display hdc
	BitBlt(hdc, 0, 0, 806, 632, hdc2, 0, 0, SRCCOPY);

	/* Cleanup DC's and any other stuff---------------------*/
	EndPaint(hWnd, &ps);
	DeleteDC(hdc);
	DeleteDC(hdc2);

	return 0;


basically the screen should print "event 1" then when event2 occurs it should print "event 2" each event is exclusive, meaning only one printing should occur. The problem is that when event2 is printed, event1 is still showing on the screen, i thought by just eliminating it from the printing of event2, that event 1 would not be printed, but it still is.... any ideas??? Thx!! [Edited by - Andrew Russell on July 27, 2005 9:23:56 AM]

Share this post


Link to post
Share on other sites
Advertisement
The BeginPaint exludes areas that's not in the update region, to update the whole dc you could use the InvalidateRgn or something similiar.
I don't understand why you use the CreateCompatibleDC each time the WM_PAINT message are called, you already have your dc:)

Share this post


Link to post
Share on other sites
You're making this call:
SelectObject(hdc2, MainWindow_SCREEN);

I'm not really sure of what the MainWindow_SCREEN represents, but I guess it is a bitmap, however you never unselect it from the dc before you delete the dc. Which I think you must do...


Also I can't see that you're clearing the bitmap in the backbuffer dc.

Share this post


Link to post
Share on other sites
I don't see where your copy the stuff of your temp dc into you regular one?


LRESULT CALLBACK WindowProc(HWND hwnd,message
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg)
{
case WM_CLOSE:
PostQuitMessage(0);
return 0;
break;
case WM_KEYDOWN:
{
if(wParam == VK_LEFT)
{
g_Event = 1;
InvalidateRgn(hwnd,NULL,TRUE);
}
else
if(wParam == VK_RIGHT)
{
g_Event = 2;
InvalidateRgn(hwnd,NULL,TRUE);
}

return 0;
} break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd,&ps);
if(g_Event == 1)
{
TextOut(hdc,10,10,"EVENT ONE",9);
} else
if(g_Event == 2)
{
TextOut(hdc,10,10,"EVENT TWO",9);
}
EndPaint(hwnd,&ps);
return 0;
} break;
default:
break;
}
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}



Share this post


Link to post
Share on other sites
I got it to finally work, here's what I did that was different:

1.) I created to "helper" hdc's from createcompatibledc, and then I loaded them with bitmaps, using createcompatiblebitmap.

2.) I then loaded the "helper" hdc's with the bitmaps i needed and then blitted them to the main hdc (hdc2)

3.) I then textout to hdc2

4.) I then bitblt from hdc2 to hdc


/* display the main window first --------------------------*/
hdc = BeginPaint(hWnd, &ps);
hdc2 = CreateCompatibleDC(hdc);
hdc3 = CreateCompatibleDC(hdc);
SelectObject(hdc2, CreateCompatibleBitmap(hdc, 800, 600));
SelectObject(hdc3, CreateCompatibleBitmap(hdc, 800, 600));
SelectObject(hdc3, MainWindow_HANDLE);
BitBlt(hdc2, 0, 0, 800, 600, hdc3, 0, 0, SRCCOPY);

switch (display_mode){

case EVENT1:

// display event1
TextOut(hdc2, 295, 100, "EVENT1", 6);

break;

case EVENT2:

TextOut(hdc2, 344, 30, "EVENT2", 6);

break;

}// end switch

// now blt everything from the back buffer hdc2 to the main display hdc
BitBlt(hdc, 0, 0, 800, 600, hdc2, 0, 0, SRCCOPY);

/* Cleanup DC's and any other stuff---------------------*/
EndPaint(hWnd, &ps);
DeleteDC(hdc2);
DeleteDC(hdc3);

return 0;


Share this post


Link to post
Share on other sites
A tip is not to recreate your buffer surface every time you receive a WM_PAINT message.


HWND g_hwnd = NULL;
HDC g_hDC = NULL;
HDC g_hOffscreen = NULL;

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,nCmdLine)
{
...
...
...
g_hDC = GetDC(g_hwnd);
// Create a buffer
g_hOffscreen = CreateCompatibleDC(g_hDC);
HBITMAP hbmp = CreateCompatibleBitmap(g_hOffscreen,SCREEN_WIDTH,SCREEN_HEIGHT);
SelectObject(g_hOffscreen,hbmp);
DeleteObject(hbmp);
...
...
...
if(g_hOffscreen)
{
DeleteDC(g_hOffscreen);
g_hOffscreen = NULL;
}
}


Share this post


Link to post
Share on other sites
Quote:
Original post by Boltimus
I got it to finally work, here's what I did that was different:

1.) I created to "helper" hdc's from createcompatibledc, and then I loaded them with bitmaps, using createcompatiblebitmap.

2.) I then loaded the "helper" hdc's with the bitmaps i needed and then blitted them to the main hdc (hdc2)

3.) I then textout to hdc2

4.) I then bitblt from hdc2 to hdc

*** Source Snippet Removed ***
That's no good. Now you have a couple of resource leaks (via CreateCompatibleBitmap).
I'd excpect your program to run out of memory or resources pretty fast and crash with it like that. [sick]

You also must listen to 'angry's advice and unselect the things you select into the dc.
This means that you need to store the results of CreateCompatibleBitmap and SelectObject into variables so that you can cleanup and restore stuff after the drawing.

I'm also quite sure that you don't need to create two large bitmaps for every WM_PAINT message!!!

Share this post


Link to post
Share on other sites
Hmmm... I think you want something like this:

//... in WM_PAINT
HDC hdcBack = CreateCompatibleDC(hdc);
HBITMAP hbmBack = CreateCompatibleBitmap(hdc, 800, 600);
HBITMAP hbmPrev = (HBITMAP)SelectObject(hdcBack, hbmBack);

TextOut(hdcBack, 100, 100, "Hello World!", 12);

BitBlt(hdc, 0, 0, 800, 600, hdcBack, 0, 0, SRCCOPY);

// unselect the backbuffer bitmap from the backbuffer dc
// otherwise you can't delete it.
SelectObject(hdcBack, hbmPrev);
DeleteObject(hbmBack);

// delete the backbuffer dc
DeleteDC(hdcBack);






Also I can see that you're deleting the device context which is returned by the BeginPaint() function, and this is something I think you should not do. I think EndPaint() does this for you. Remember the BeginPaint() returns a device context of a window. And a device context retrieved from a window must be released with ReleaseDC(), however as I said earlier, I think EndPaint() does this for you.

And what does this do?
SelectObject(hdc3, MainWindow_HANDLE);
What type is MainWindow_HANDLE? And what is it?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!