【发布时间】:2013-09-11 07:07:08
【问题描述】:
创建一个具有 WS_EX_COMPOSITED 样式的窗口:
hWnd = CreateWindowEx(WS_EX_COMPOSITED, szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
为窗口设置插入符号:
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;
启动应用程序,什么都不做。在隐藏插入符号或破坏插入符号之前,它们将是无限的 WM_PAINT。
Spy++ 显示: 每个闪烁插入符号的 0x118(WM_SYSTIMER) 后跟一条 WM_PAINT 消息。
BeginPaint 返回的绘制结构是
WM_PAINT : invaliate rect width = 2, height = 12
这只是插入符号的宽度和高度。总之,WM_PAINT 用于闪烁插入符号。
但如果我从窗口的额外样式中删除 WM_EX_COMPOSITED 样式,则不再有无限的 WM_PAINT。
这是windows的bug吗?
PS:测试环境 windows 7 64bit + visual studio 2012。
【问题讨论】:
-
您的 WndProc 是否返回 0 以表明它处理了 WM_PAINT?
-
@selbie: 是的,我的项目是从visual studio 2012 win32 应用程序模板派生的,它肯定返回0。实际上,我只是添加了以上几行。
-
WS_EX_COMPOSITED 对窗口的呈现方式具有大 效果。顶层窗口及其所有子控件都是双缓冲的。您不希望重新绘制整个窗口堆栈以仅更新插入符号。所以这几乎可以肯定是设计使然。这应该不是问题。
-
如果您只是在调整大小时使用复合来防止闪烁,一种可能的解决方案是仅在您进入大小循环时打开样式,然后再将其关闭。
标签: c windows winapi user-interface