Windows, Question about the GDI, WM_LBUTTONDOWN message and DefWindowProc

I am currently learning how to work with the GDI. In my window procedure, I have this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
case WM_LBUTTONDOWN:
			x = LOWORD(lParam);
			y = HIWORD(lParam);
			if(inl == -1) inl = 0;
			ixl[inl] = x;
			iyl[inl] = y;
			itoa(inl+1, szLineCounter, 10);
			hDC = GetDC(hWnd);
			TextOut(hDC, x, y, szLineCounter,  
                        strlen(szLineCounter));
			ReleaseDC(hWnd, hDC);
			++inl;
			return 0;


Now at one point I forgot the return 0 at the end, this caused the program to draw small circles with a radius of about 3 pixels to be drawn where I clicked my mouse, if I completely commented out this section this behaviour didn't occur anymore.

Now the only thing I can imagine causing this is me requesting the device context handle in my message handler, does this cause DefWindowProc to behave different from normal? Do similar things also apply to other situations I should be aware of?
Some of the most time wasting ignorant bugs I've had in Windows programming concern forgetting to handle device contexts correctly. You can absolutely count on all kinds of bizarre behavior by messing this up.

In the case of forgetting the return in a handler, whatever code in your handler will of course execute, then DefWindowProc() will also execute. And in the case you described I believe you failed to release a device context. So basically the sky is the limit in terms of nasty behavior you could observe.

One comment I might make is that beginning Sdk Api coders almost always get in trouble with GetDC() - ReleaseDC(). It would almost be better if those functions didn't exist!

You really, really, need to try to limit all your drawing activities to the WM_PAINT hamndler and forsake GetDC(). The way you do this is to accumulate your drawing data somewhere, then call InvalidateRect() to force a WM_PAINT - then do your drawing there.

You have to realize that any drawing you do outside of the WM_PAINT handler won't persist.
Last edited on
I actually use this for temporary drawings that are supposed to be removed by the next WM_PAINT. If you looked at my code, you'd see that I actually DID release the DC there, and there is no code after this that requests it. And yes, DefWindowProc will execute, I am just wondering whether the behaviour is defined to behave that way or it's just some random bug? Also notable would be that these circles for some reason persist after InvalidateRect(hWnd,NULL,TRUE).
Likely Microsoft would describe that scenerio as 'undefined behavior'.
Topic archived. No new replies allowed.