Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WS_EX_COMPOSITED cause unexpected WM_PAINT

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.

like image 600
Jichao Avatar asked Nov 01 '22 15:11

Jichao


1 Answers

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.

like image 153
JonPall Avatar answered Nov 15 '22 09:11

JonPall