在窗口位置变化过程的早期,系统会发送 WM_WINDOWPOSCHANGING 消息。
这个和 WM_WINDOWPOSCHANGED 消息不同,WM_WINDOWPOSCHANGED 消息发生在窗口位置变化之后。
一个关键的区别(除了时间之外)是,您可以通过处理 WM_WINDOWPOSCHANGING 消息和修改 WINDOWPOS 结构来影响窗口的状态更改。
在下面的例子代码中,我们可以通过处理 WM_WINDOWPOSCHANGING 消息,实现禁止窗口更改大小。
BOOL OnWindowPosChanging(HWND hwnd, WINDOWPOS *pwp)
{
pwp->flags |= SWP_NOSIZE;
/* Continue with default handling */
return FORWARD_WM_WINDOWPOSCHANGING(hwnd, pwp, DefWindowProc);
}
HANDLE_MSG(hwnd, WM_WINDOWPOSCHANGING, OnWindowPosChanging);
在引入 WM_WINDOWPOSCHANGING 消息之前,程序必须在其 WM_SIZE 和 WM_MOVE 处理程序中强制执行窗口大小约束,但由于这些消息是在窗口变化完成后发送的,因此当窗口更改为一个大小时,我们会发现窗口在会闪烁,然后 WM_SIZE 处理程序将其调整为更好的大小。通过截获 WM_WINDOWPOSCHANGING 窗口大小的变化,可以在调整大小之前强制执行约束,从而避免闪烁。
WM_WINDOWPOSCHANGING 和 WM_WINDOWPOSCHANGED 这对兄弟只是更通用的 *CHANGING / *CHANGED 模式的一个示例。(其他示例包括 WM_STYLECHANGING / WM_STYLECHANGED 和 LVN_ITEMCHANGING / LVN_ITEMCHANGED。
*CHANGING 一半在变化发生之前发送,作为一般规则,您可以更改通知的参数以强制实施某种类型的约束。
从 *CHANGING 通知返回后,将发生实际更改,然后您会收到 *CHANGED 以指示更改已完成。
如果你明白了这个规律,则可以融会贯通,将所有此类消息”一网打尽”。
总结
Windows 客户端开发过程中,如果处理不当,则容易发生用户界面闪烁的情况。
完美主义者会绞尽脑汁研究各种做法消除闪烁,我们在 拓扑梅尔智慧办公平台 (Topomel Box) 的开发阶段就花费了大量的时间,采用了各种奇淫技巧来最大化减少闪烁。
正所谓:慢工,出细活,我们只是想给您带来最好的东西。
最后
Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《Use WM_WINDOWPOSCHANGING to intercept window state changes》
最近我写了个东西
正如你们所知道的,拓扑梅尔智慧办公平台(TopomelBox)是一款绿色软件,主要面向经常使用电脑的朋友。它提供了各种提升办公效率的小功能,同时操作上尽可能地简单方便。
我想:你值得拥有。