Alpaca
Alpaca

Reputation: 3

InvalidateRect in Windows API, Charles Petzold checker4.c program

Full program is here:

http://examples.oreilly.com/9781572319950/cd_contents/Chap07/Checker4/Checker4.c

The code in ChildWndProc that confuses me:

 case WM_LBUTTONDOWN :
      SetWindowLong (hwnd, 0, 1 ^ GetWindowLong (hwnd, 0)) ;
      SetFocus (hwnd) ;
      InvalidateRect (hwnd, NULL, FALSE) ;
      return 0 ;

           // For focus messages, invalidate the window for repaint

 case WM_SETFOCUS:
      idFocus = GetWindowLong (hwnd, GWL_ID) ;

           // Fall through

 case WM_KILLFOCUS:
      InvalidateRect (hwnd, NULL, TRUE) ;
      return 0 ;

Why in ChildWndProc in the case of message WM_LBUTTONDOWN:

the last statement before return 0 is InvalidateRect, since right before it the program sends WM_SETFOCUS message to itself with the SetFocus function, which falls through to WM_KILLFOCUS, which also has InvalidateRect, only the last argument is TRUE, instead of FALSE.

In my understanding the program should work properly without InvalidateRect in WM_LBUTTONDOWN since it calls SetFocus, which then makes it to invalidate the window, however when I comment out the InvalidateRect from WM_LBUTTONDOWN, the program doesn't repaint the window properly after mouse clicks or button presses.

Why is this and why in the WM_LBUTTONDOWN InvalidateRect the last argument is FALSE and in WM_KILLFOCUS it is TRUE?

I am running MS Visual Studio C++ 2010 Express in Windows XP 32bit.

Upvotes: 0

Views: 379

Answers (1)

Christian Aichinger
Christian Aichinger

Reputation: 7227

Calling SetFocus() doesn't unconditionally send an WM_SETFOCUS message. If the window already has the focus before the call, SetFocus() will not do anything.

Put another way, a WM_SETFOCUS message is only sent if the focus was changed.

As for the TRUE/FALSE parameter, that's bErase, whether to erase the whole window before re-drawing it, or whether to paint over what's already there. It is, in my book, a performance hack. If you know you can get away with not erasing the window (because you are just updating a small part of it), you can pass TRUE here.

I don't think that in 2015 there's much value in this optimization. If you need high performance display updates, you'd use OpenGL or DirectX anyway.

Upvotes: 1

Related Questions