Sign in to follow this  

win32/WM_PAINT collision

This topic is 4844 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 making a small graphic editor/display program using basic Win32 and GDI functions. I have a menu item 'Color' with three radio options inside: Red, Green, and Blue. Also, below those, there is the option 'Other...', which opens a dialogue box that allows the user to enter any combination of RGB to get a unique 24-bit color. My dialog box was working when I initially implemented the GUI aspect of the program, but since I've been processing the WM_PAINT message, the dialogue box doesn't get displayed (nor does the default 'About' window that VC++ 7.1 creates), and the program locks up. I tried to set a boolean whenever the user clicks the menu option, telling it to process nothing within the WM_PAINT message, but to no avail. Is there any standardized way to display dialogue boxes while paint messages are being processed?

Share this post


Link to post
Share on other sites
WM_PAINT should not interfere with dialog boxes or menus in any way. Show the code of the WM_PAINT part or the whole window/dialog proc.

Did you perchance miss the break statement at the end of WM_PAINT?
Are you using BeginPaint and EndPaint during WM_PAINT?
If you don't, are you validating the client area?

Share this post


Link to post
Share on other sites
Ok, I've commented out all of the code in WM_PAINT, as well as several other message handlers, but the program still freezes. Using some basic debugging, it seems as though the process handler for the dialog box is being called repeatedly. Here is the relevant code:


			
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;

switch (message)
{
case WM_CREATE:
...
break;


case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
...
// this is the menu item that opens the dialog box
case ID_COLOR_OTHER32780:
paintEnabled = false;
DialogBox(hInst, (LPCTSTR)IDD_PROPPAGE_MEDIUM, Global::Instance()->GetMainHwnd(), (DLGPROC)SetRGBMenuProc);
break;
...
// this dialog box doesn't work either
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
break;
case WM_PAINT:
/* //commented to find problem
if( paintEnabled ){
hdc = BeginPaint(hWnd, &ps);

...
// (some drawing stuff here)
InvalidateRect( hWnd, NULL, true );
Sleep(1);



EndPaint(hWnd, &ps);
}
*/
break;


case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

Share this post


Link to post
Share on other sites
A couple of points: Firstly, could you post the code for SetRGBMenuProc. Secondly, I don't see why you need the paintEnabled flag - try removing that and put the WM_PAINT back in (without the paintEnabled check).

Skizz

Share this post


Link to post
Share on other sites
A) Move the "return DefWindowProc" outside the switch statement, replace the "return 0" with it.
My guess with your problem is, that since WM_PAINT gets not handled (painting commented out) the client area is still invalid, but noones validating it. So you'll receive WM_PAINT again and again.

B) As theNestruo said, remove the InvalidateRect inside the BeginPaint/EndPaint. It won't change anything, as EndPaint will validate the invalid client area anyway.

C) After handling WM_PAINT return TRUE. No need to pass it on to the DefWindowProc (after changing as in step A).

D) Minor nitpick: Move the local vars inside the window proc (hdc, paintstruct) into the right case; maybe add a scope {} to make local vars possible there.

Share this post


Link to post
Share on other sites
Quote:
Original post by Endurion
C) After handling WM_PAINT return TRUE. No need to pass it on to the DefWindowProc (after changing as in step A).
This is key. Each window message requires a different return value, so don't assume you can just break... return 0 for all of them. The appropriate return value, depending on how you want Windows to respond after your own code, is indicated in the documentation for each message.

Share this post


Link to post
Share on other sites

This topic is 4844 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.

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