Reputation: 41845
Create a window with WS_EX_COMPOSITED style:
hWnd = CreateWindowEx(WS_EX_COMPOSITED, szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
Set caret for the window:
case WM_PAINT:
OutputDebugStringA("WM_PAINT");
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_SETFOCUS:
::DestroyCaret();
::CreateCaret(hWnd, NULL, 2, 12);
::SetCaretPos(200, 200);
::ShowCaret(hWnd);
break;
case WM_KILLFOCUS:
::DestroyCaret();
break;
case WM_CHAR:
::DestroyCaret();
::CreateCaret(hWnd, NULL, 2, 12);
::SetCaretPos(200, 200);
::ShowCaret(hWnd);
break;
Start the application, and do nothing. they will be a infinite WM_PAINT until hide the caret or destory the caret.
Spy++ shows: every 0x118(WM_SYSTIMER) which blink the caret is followed by a WM_PAINT message.
The paint structure returned by BeginPaint is
WM_PAINT : invaliate rect width = 2, height = 12
which is just the width and height of the caret. In conclusion, WM_PAINT is for blinking the caret.
But if I remove the WM_EX_COMPOSITED style from the extra styles for the window, there is no infinite WM_PAINT anymore.
Is this a bug of windows?
PS: test enviroment windows 7 64bit + visual studio 2012.
Upvotes: 5
Views: 1332
Reputation: 814
A caret is also considered a control. Do not use WS_EX_COMPOSITED for top level windows. Either use it for the specific problematic control.
Or ignore WM_ERASEBACKGROUND in WndProc of a control which has foreground content covering it's whole client area, and the control flickers when you resize.
Upvotes: 2