Sign in to follow this  
phil05

Weird GetDC() issue with bitmap disapearing when switching screens

Recommended Posts

phil05    100
This is really odd. I have this source code instructing the dialog to show a bitmap. When I change screens, and go back to the dialog, the picture is gone! What the heck? Bitmaps stay in place if I use BeginPaint(). But using GetDC() is causing the bitmap to disapear. This happened in a previous paint program I made too. Any idea why this is happening?
				// Bitmap
				hDC = GetDC(dWnd);
				bmpPic = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_PIC));
				hDCPic = CreateCompatibleDC(hDC);
				SelectObject(hDCPic, bmpPic);
				BitBlt(hDC, 0, 72, 400, 400, hDCPic, 0, 0, SRCCOPY);
				DeleteObject(bmpPic);
				DeleteDC(hDCPic);

				ReleaseDC(dWnd, hDC);

Doesn't the picture need to update itself every time the window is moved?

Share this post


Link to post
Share on other sites
Red Ghost    368
Your bitmap will be blitted if you InvalidateRect(). This function calculates the update region for Windows. This function is automatically called by BeginPaint(), so if you don't use BeginPaint() you must InvalidateRect().
Hope that helps.

Share this post


Link to post
Share on other sites
phil05    100
Do I call it like this? Right now its not showing the bitmap. Like before I heard of this function, I had no idea where to put it on the source code. Still not sure here.


case WM_LBUTTONDOWN:
{
dWnd = CreateDialog(NULL, "IDD_ABOUT", hWnd, (DLGPROC)About);
ShowWindow(dWnd, SW_SHOWNORMAL);

// Combo Box Window
cbWnd = GetDlgItem(dWnd, IDD_SIZE_CBO);

const char *LIST[] = { "Item1", "Item2", "Item3" };

for (int i = 0; i < 3; i++)
{
SendMessage(cbWnd, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(LIST[i]));
}

// Bitmap
hDC = GetDC(dWnd);
InvalidateRect(dWnd, NULL, true);
bmpPic = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_PIC));
hDCPic = CreateCompatibleDC(hDC);
SelectObject(hDCPic, bmpPic);
BitBlt(hDC, 0, 72, 400, 400, hDCPic, 0, 0, SRCCOPY);
DeleteObject(bmpPic);
DeleteDC(hDCPic);

ReleaseDC(dWnd, hDC);

}
break;




[Edited by - philvaira on August 5, 2004 2:39:20 AM]

Share this post


Link to post
Share on other sites
phil05    100
I tried this source code. The window moves fine with the picture now, but when another window overlaps the one with the picture, the picture disapears. Any idea why?


hDC = GetDC(dWnd);
InvalidateRect(hWnd, NULL, TRUE);
bmpPic = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_PIC));
hDCPic = CreateCompatibleDC(hDC);
SelectObject(hDCPic, bmpPic);
BitBlt(hDC, 0, 72, 400, 400, hDCPic, 0, 0, SRCCOPY);
DeleteObject(bmpPic);
DeleteDC(hDCPic);

ReleaseDC(dWnd, hDC);

Share this post


Link to post
Share on other sites
Red Ghost    368
Sorry for the delay since I am at work.
In your code, you seem to draw your bitmap whenever you press the left mouse button.
When another window is selected, you lose focus and the mouse messages are handled by the overlapping window.
Two solutions to solve your problem:
1- either you draw the bitmap each time your window receives a WM_PAINT message.
2- or you move your drawing code out of the main message pump:

if (PeekMessage(&_Msg, _hwnd, 0, 0, PM_REMOVE))
{
TranslateMessage(&_Msg);
DispatchMessage(&_Msg);
}
else
{
//Drawing code here
}


Hope that helps.

Share this post


Link to post
Share on other sites
phil05    100
You mean like this? The window flashes and quits.


// Message Loop
if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
else
{
hDC = GetDC(dWnd);
bmpPic = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_PIC));
hDCPic = CreateCompatibleDC(hDC);
SelectObject(hDCPic, bmpPic);
BitBlt(hDC, 0, 0, 400, 400, hDCPic, 0, 0, SRCCOPY);
DeleteObject(bmpPic);
DeleteDC(hDC);
ReleaseDC(dWnd, hDC);

}


return Msg.wParam;
}





EDIT:
I made a WM_PAINT message in the dialog's window procedure and dumped the drawing on there. It seems to be working now. Thanks for your advice.

Share this post


Link to post
Share on other sites
Red Ghost    368
For the second solution, you just need to enclose the if...else statement in a while statement:

while (Running == true) {
if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
.....
}


You set the Running var to false when there is a call to WM_CLOSE message.

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