• 关于对 DeferWindowPos 的理解


    DeferWindowPos 这个 API 的目标是:同一时间,移动多个子窗口。这在一定程度上减少了窗户移动时进行的重绘工作量。

    修改我们之前的例子代码,如下图所示:

    >> 请移步至 topomel.com 查看图片 <<

    请注意,我正在使用控件 ID 来保存所需的颜色,我们在选择背景颜色时在获取它。

    >> 请移步至 topomel.com 查看图片 <<

    我特意调用了 Sleep,这样就可以看到实际的绘制效果。

    >> 请移步至 topomel.com 查看图片 <<

    我们将两个子窗口并排放置在工作区中。对于我们的第一次测试,我们将使用 SetWindowPos 函数用来移动窗口。

    编译并运行此程序,一旦启动,单击最大化框。仔细观察绿色矩形的哪些部分被重新绘制。

    现在让我们修改移动窗口的代码以使用 DeferWindowPos 函数。DeferWindowPos 的使用模式如下:

    >> 请移步至 topomel.com 查看图片 <<

    要点如下

    > 传递给 BeginDeferWindowPos 函数的值是要移动的窗口数量。如果弄错了这个值也没关系,但正确的处理会减少内部重新分配的数量。
    > 来自 DeferWindowPos 的返回值将存储回 hdwp 中,因为返回值不一定与最初传入的值相同。如果延迟记录需要执行重新分配,则 DeferWindowPos 函数返回新延迟信息的句柄;旧的延迟信息不再有效。更重要的是,如果延迟失败,旧的延迟信息将被销毁。这与 realloc 函数不同,如果重新分配失败,则原始对象保持不变。模式 p = realloc(p, …) 是内存泄漏,但模式 hdwp = DeferWindowPos(hdwp, …) 不是。

    上述第二个要点很重要,有很多人经常容易忽略它。

    好的,现在你们可能都害怕这个函数,让我们修改窗口移动代码以利用延迟窗口定位。真的一点也不难。(不过,将这些更改保存到新文件中。我们希望并排运行旧版本和新版本。

    >> 请移步至 topomel.com 查看图片 <<

    编译并运行此程序,一旦启动,再次最大化窗口并观察哪些区域重新绘制。请注意,与旧版本相比,新版本中的重绘量会减少。

    总结

    完美主义者有福了。
    如果你一直纠结于为什么你的窗口控件会闪烁,则不妨试试 DeferWindowPos 。
    它的存在,一定是有原因的。

    最后

    Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
    本文来自:《What’s the point of DeferWindowPos?》

     

  • 相关阅读:
    大数据存储ClickHouse
    V 神:Rollup 二层网络的三个阶段
    面试用-常用注解
    基于springboot+vue的戒毒所人员管理系统毕业设计源码251514
    C++学习记录——삼십이 C++IO流
    CCF编程能力等级认证GESP—C++3级—样题1
    【数据结构】单链表之--无头单向非循环链表
    【自监督论文阅读笔记】Self-Supervised Learning with Swin Transformers
    推荐系统:冷启动问题【用户冷启动、物品冷启动、系统冷启动】
    【目标检测】英雄联盟能用YOLOv5实时目标检测了 支持onnx推理
  • 原文地址:https://blog.csdn.net/mmxida/article/details/128031412