窗口向左无闪烁扩展(调整大小)

2023-12-03

假设您有一个可以向左展开以显示其他控件的表单:

折叠:

Collapsed form

扩展:

Expanded form

在 Delphi 中实现这一点的最简单方法是使用alRight作为所有控件的主要锚点(而不是alLeft),然后只需调整表单的宽度和 X 坐标即可。您可以设置Width and Left单独属性,或者您可以使用同时设置它们的函数,例如

if FCollapsed then
  SetWindowPos(Handle, 0, Left - Width, Top, 2 * Width, Height, 0)
else
  SetWindowPos(Handle, 0, Left + Width div 2, Top, Width div 2, Height, 0)

问题问题是,在展开或折叠时,表单始终可见的部分(在本例中为按钮)存在相当明显的闪烁。自己尝试一下吧!

操作系统可以将窗体的大小向左调整而不会出现任何闪烁——只需使用鼠标抓住窗体的左边缘并向左或向右拖动鼠标即可——但我找不到任何闪烁Windows API 中的函数公开了这种大小调整。

我尝试过使用几种不同的 Windows API 函数来调整表单的大小和位置,尝试了它们的各种参数(例如,SWP_*标志),尝试过LockWindowUpdate, WM_SETREDRAW, TForm.DoubleBuffered等等都无济于事。我还研究了使用的可能性WM_SYSCOMMAND SC_SIZE方法。

我还不确定问题是出在操作系统层面还是VCL层面。

有什么建议么?

Edit:我很惊讶地看到这个问题获得了接近的票数。让我尝试澄清一下:

  1. 创建一个新的 VCL 表单应用程序。

  2. 在主窗体的右侧添加一些按钮,并在左侧添加一个备忘录。放Anchors to [alTop, alRight] on all控制。上OnClick按钮的处理程序,添加以下代码:

    if FCollapsed then
      SetWindowPos(Handle, 0, Left - Width, Top, 2 * Width, Height, 0)
    else
      SetWindowPos(Handle, 0, Left + Width div 2, Top, Width div 2, Height, 0);
    
    FCollapsed := not FCollapsed;
    

    where FCollapsed是表单的私有布尔字段(初始化为false).

  3. Now, click the buttons repeatedly. (Or give one of them keyboard focus and hold the Enter key for a few seconds.) You will probably notice that the region with the buttons on your monitor will not display a perfect still image, but will flicker. In addition, you might actually see 'ghosts' of the buttons to the left of the actual column of buttons.

我无法使用屏幕捕获来捕获这种毫秒闪烁,因此我使用数码相机来记录我的屏幕:

https://privat.rejbrand.se/VCLFormExpandFlicker.mp4

在此视频剪辑中,很明显,按钮列不是屏幕上的静态图像;而是一列按钮。相反,每次调整表单大小时都会有几毫秒的时间,该区域会出现不正常的情况。同样明显的是,左侧有一列“幽灵”按钮。

我的问题是是否有任何相当简单的方法来消除这些视觉伪影(至少对我来说,即使您一次展开/折叠表单,这些视觉伪影也是非常明显的)。

在我工作的 Windows 10/Delphi 10.1 计算机上,当我使用鼠标拖动窗体的最左边缘时,窗体会以完美的方式调整大小:窗体的未受影响的客户区域在显示器上完全静态。然而,在我家里的 Windows 7/Delphi 2009 PC 上,我确实看到当我执行此操作时会发生很多重新定位。


我可以提供一些关于为什么您会看到 UI 另一半的重影的见解,以及可能的阻止它的方法。重影图像表明有人正在复制您的客户区像素(并将它们复制到错误的位置,始终在窗口中左对齐),然后您才有机会使用正确的像素重新绘制它们。

这些鬼象像素可能有两个不同的、重叠的来源。

第一层适用于所有 Windows 操作系统,来自BitBlt inside SetWindowPos。你可以摆脱它BitBlt在几个方面。您可以创建自己的自定义实现WM_NCCALCSIZE告诉 Windows 不传输任何内容(或者在自身之上传输一个像素),或者您可以拦截WM_WINDOWPOSCHANGING(首先将其传递给DefWindowProc)并设置WINDOWPOS.flags |= SWP_NOCOPYBITS,这会禁用BitBlt在内部调用中SetWindowPos()Windows 在调整窗口大小期间执行的操作。这与跳过的最终效果相同BitBlt.

然而,Windows 8/10 aero 添加了另一个更麻烦的层。应用程序现在绘制到离屏缓冲区中,然后由新的、邪恶的 DWM.exe 窗口管理器合成。事实证明 DWM.exe 有时会自己做BitBlt类型操作是在旧版 XP/Vista/7 代码已经完成的操作之上进行的。阻止 DWM 进行 blit 则要困难得多;到目前为止我还没有看到任何完整的解决方案。

将突破XP/Vista/7层并至少提升8/10层性能的示例代码请参见:

如何在调整窗口大小时平滑丑陋的抖动/闪烁/跳跃,特别是拖动左/上边框(Win 7-10;bg、bitblt 和 DWM)?

由于你有多个子窗口,情况就更复杂了。这BitBlt我上面提到的类型操作发生在整个顶级窗口上(它们将窗口视为一组像素,无论下面有多少个窗口,也不管CLIPCHILDREN)。但是您需要让窗口自动移动,以便在下一次重绘时它们都正确定位。你可能会发现BeginDeferWindowPos/DeferWindowPos/EndDeferWindowPos对此很有用(但只有在上述技巧不起作用时才去那里)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

窗口向左无闪烁扩展(调整大小) 的相关文章

  • 为什么我只能用管理员权限才能导入Python中的某些模块?

    我正在努力解决 Python 2 7 中的一些奇怪问题 我写了一个很长的工具 在其中导入不同的模块 我必须首先使用它安装pip 该工具将在公司内部共享 不同的用户在其特定机器上拥有不同的权限 当另一个用户登录我的计算机 我在那里拥有管理员权
  • TObjectList.Contains 导致 Delphi 2009 中的访问冲突

    在 Delphi 2009 中 到目前为止 我在泛型方面没有遇到大问题 使用 Generics Collections 列表 没有特殊的泛型功能 现在我发现这段代码会在访问的行中导致AVMyList Contains 如果我声明 TMyLi
  • 如何更改 TPageControl 上标签的方向?

    我是 Delphi 的新手 再次强调 我在 1994 年就使用过 Delphi 我现在有 Delphi 2009 Pro 来自Java 我发现对象继承非常晦涩 我的用户想要选项卡位于左侧的选项卡式页面 但是 TPageControl 不允许
  • Delphi 5 中的 Oracle 数据库连接

    我正在使用 Delphi 5 版本 我想连接到 Oracle 数据库 我有 TDatabase 组件 我不知道如何通过 Delphi 连接到数据库 请提供连接数据库的步骤 谢谢 The TDatabase http docwiki emba
  • 发送用户注册密码,django-allauth

    我在 django 应用程序上使用 django alluth 进行身份验证 注册 我需要创建一个自定义注册表单 其中只有一个字段 电子邮件 密码将在服务器上生成 这是我创建的表格 from django import forms from
  • 在 Qt 中自动调整标签文本大小 - 奇怪的行为

    在 Qt 中 我有一个复合小部件 它由排列在 QBoxLayouts 内的多个 QLabels 组成 当小部件调整大小时 我希望标签文本缩放以填充标签区域 并且我已经在 resizeEvent 中实现了文本大小的调整 这可行 但似乎发生了某
  • Windows 目录永远不会包含临时文件的非 ASCII 字符?

    在 Windows 上使用 MinGW 7 3 0 由于 Windows 限制 Hunspell 无法从包含非 ASCII 字符的位置加载字典文件 我已经尝试了所有方法 1 现在我将文件复制到没有 ASCII 字符的路径 然后再将其交给 H
  • Delphi 6 命令行编译:无 DCU

    当对 dpr 文件使用 dcc32 时 它会生成一个 dll 但不会生成 dcu 项目级别 cfg 使用 N 开关设置路径 但指定的目录中没有任何内容 当 E 开关正在工作时 它必须看到 cfg 我尝试在调用 dcc32 之前对 dpr 文
  • 从 Mailgun 表单 Post PHP 中检索附件

    如何检索并保存通过 Mailgun 的 POST 表单发送给我的附件 下面是一些参数 attachment 1 filename gt crabby gif type gt image gif name gt attachment 1 te
  • 关闭有效句柄时,AppVerifier 报告“无效句柄 - 代码 c0000008”

    我有一个简单的测试程序 在运行时会失败并出现异常AppVerifier 程序重复STD INPUT HANDLE然后尝试使用关闭它CloseHandle 该程序运行良好 无需AppVerifier返回TRUE for CloseHandle
  • Rails 中多个模型的最佳实践 - 嵌套/非嵌套和验证

    笔记 根据布莱恩的评论 来自如何以 Rails 形式处理多个模型 https stackoverflow com questions 892624 how to handle multiple models in a rails form
  • 用于创建计划任务的 VBScript

    我正在尝试创建一个 VBScript 它创建一个批处理文件 然后创建一个计划任务来运行该批处理文件 到目前为止 我尝试过的所有操作都创建了批处理文件 但没有创建计划任务 并且我没有收到任何错误 这是我到目前为止所拥有的 Option Exp
  • TListView 中的中心子项目图像

    Is it possible to fix the drawing of subitem images in a TListView so that they are not cut off on the left hand side as
  • 防止按下回车键时提交表单[重复]

    这个问题在这里已经有答案了 我们如何防止按下回车键时提交表单 实际上我有一个文本框 在该文本框中输入一个值并单击输入时 textbox2 将获得焦点 默认情况下 单击输入按钮后将提交表单 所以我无法得到输出 我在提交按钮的 onclick
  • 如何在自托管 WCF 中获取多部分表单数据?

    我已经搜索了很长一段时间 但没有找到我要找的东西 我在 Windows 应用程序中自行托管了一个 http WCF 现在 在我的服务方法之一中 我需要接收一个文件和一些表单数据字段 在类似的问题中 情况要么发送一个文件 这是通过流数据然后转
  • 命名管道性能问题

    我使用命名管道进行 C 和 Delphi 之间的过程间通信 C 使用System IO Pipes包 而 Delphi 使用Libby s pipes pas 不幸的是 通信几乎是高性能的 分析显示通信占用了整个运行时间的 72 其余的用于
  • 将 value 转换为 bool 的魔法

    今天我意识到将值转换为 bool 是一种魔法 int value 0x100 unsigned char uc static cast
  • Mac OS X 上的 /proc/self/cmdline / GetCommandLine 等效项是什么?

    如何在不使用 argc argv 的情况下访问 Mac OS X 上的命令行 在 Linux 上 我会简单地阅读 proc self cmdline or use GetCommandLine在 Windows 上 但我找不到 Mac OS
  • 将 [字节数组] 分配给没有 Unicode 转换的 Variant

    考虑以下代码片段 在 Delphi XE2 中 function PrepData StrVal string Base64Val AnsiString OleVariant begin Result VarArrayCreate 0 1
  • PHP 如何判断用户是否按下了 Enter 键或 Submit 按钮?

    我遇到的问题是我在一个表单中有多个提交输入 每个提交输入都有不同的值 我更愿意将它们保留为提交 Whenever the user presses Enter it is as though the topmost submit input

随机推荐

  • 使用产品风味时,每种风味中哪些文件是常见的,哪些文件是该风味特有的?

    productFlavors India USA 我们以两种产品口味为例 1 印度 2 美国 构建变体的总数将为 4 1 印度调试 2 印度发布 3 美国调试 4 美国发布 哪些文件对于所有风格都是通用的 哪些文件是特定于风格以及调试和发布
  • 如何在 Coq 中自动证明实数的简单相等?

    我正在寻找的是auto类似的策略可以证明简单的等式 例如 1 2 2 4 到目前为止 我手动尝试过的是使用ring simplify and field simplify来证明等式 即使这样效果也不好 Coq 8 5b3 下面的例子有效 R
  • 将数据从 .data 文件转换为 .csv 文件,并使用 pandas 将数据放入列中

    我想将 data 文件中的数据转换为 csv 文件 并将 data 文件中的数据放入其下带有值的列中 但是 data 文件具有特定的格式 我不知道如何将文本放入列中 data 文件如下所示 column1 column2 column3 c
  • 在提交 Ajax 时生成 CSRF 令牌 codeigniter

    您好 我正在寻找使用 ajax 提交表单时在 codeigniter 中重新生成 csrf 令牌的过程 我希望在不刷新页面的情况下重新生成令牌 有什么办法可以做到这一点吗 我根据情况在不同时间使用两种解决方案 1 方式有点乱 但推荐 获取控
  • 原始 CSS 文件中的条件 IE8 样式?

    我怎样才能只为 IE8 浏览器覆盖这个样式 我认为我不再关心 IE7 用户了 除非标记非常小 menu ul margin 0 padding 0 width 650px menu ul li display inline block wi
  • 找不到带有下划线的路由或者没有正确对待它

    我在路线中有这个 Rails application routes draw do namespace api do namespace v3 4 do 和控制器app controllers api v3 4 base controlle
  • LexResponse 输出无法理解 HTML 数据

    我在尝试让 AWS Lambda 函数在运行 SQL 查询时成功输出一系列 HTML 链接时遇到问题 private string GetEventSearchResults ILambdaContext context List
  • 如何使用 Gson 将 JSON 转换为 HashMap?

    我正在从服务器请求数据 该服务器返回 JSON 格式的数据 在发出请求时将 HashMap 转换为 JSON 一点也不难 但另一种方法似乎有点棘手 JSON 响应如下所示 header alerts AlertID 2 TSExpires
  • 如何使用 Storyboards/Cocoa 在 Swift 3.x 中引用视图的窗口

    随着 Xcode 和 Swift 中的所有更改 我无法弄清楚如何像在使用 XIB 的项目中那样处理 stotyboard 驱动的项目中的视图窗口 macOS 编程新手 如果这是基本内容 请提前道歉 使用故事板时 如何使用以下方法更改视图的窗
  • 具有 k 个部分的排序和非排序整数分区

    对于正整数n and k 让一个 k 分区n 是一个排序列表k不同的正整数加起来为n 并让给定的 等级 k 分区n是它在所有这些列表的排序列表中的位置 按字典顺序从 0 开始 例如 有两个 5 的 2 分区 n 5 k 2 1 4 和 2
  • 如何使 Eclipse Partstack 在最后一个部分关闭时不消失?

    我正在开发一个项目 该项目的主窗口由 mpartstack 组成 我在其中动态地从另一个部分添加部分 问题是 当最后一部分关闭时 mpartstack 消失 而另一部分占用所有空间 当我尝试添加新零件时 什么也没有发生 我尝试通过尝试添加新
  • 当 C 按值传递时,我的数组如何修改?

    我用 C 编写了一个简单的程序来检查两个单词是否是字谜 我的问题是 如果我传递 word one 和 word two 作为参数 这是否意味着我没有修改原始数组 我认为我正在有效地处理这些未归还的副本 这意味着我不应该能够将它们与我的 eq
  • 如何获取芒果的承运商详细信息?

    有没有API可以告诉我们手机是哪个运营商的 例如 沃达丰 祖国 当前国家 详细信息 我在 Microsoft Phone Net NetworkInformation 中找不到此类内容 我是否遗漏了某些内容 感谢帮助 您可以通过静态属性获取
  • 自定义类的比较重载方法

    我想重载个人类的比较方法 例如 如果我这样写 object1 function compare a b if a gt attribute b gt attribute return 0 else return a gt attribute
  • 用换行符绑定文本

    我绑定到带有换行符的字符串 例如 Hello nWorld 在我的模型中 现在我想使用显示模板中的值 x 但换行符未正确显示 聚合物是否为输出提供任何支持 br 用于换行 现在你最好的选择是创建一个Nl2br PolymerElement
  • Windows Phone 7 中的媒体播放器

    我正在使用 Windows Phone 7 中的媒体播放器来播放手机歌曲集中的音乐 但是当它播放音乐时 它们将是一个例外 并且错误指出 尚未调用 Framework Dispatcher Update 定期调用 Framework Disp
  • 代码不等待用户输入?

    我必须为我的计算机科学课做一个项目 问题是 图书馆的读者最多可以借三本书 因此 赞助人有一个名字和最多三本书 一本书有作者和标题 设计并实现两个类 Patron 和 Book 来表示这些对象和以下行为 客户端可以实例化一本书 并带有标题和作
  • 为什么在 Scala 中对 Option.getOrElse 的返回值使用隐式转换时类型推断失败?

    例如我有一堂课Value和一个隐式函数将字符串转换为值 case class Value v String implicit def strToValue s String Value Value s 这是一个有方法返回值的特征 trait
  • Swift:在另一个 UIView 下进行 UIView 的 hitTest

    我在RedOrGreenUIView 之上有TransparentUIView TransparentUIView 附加了一个 UILongPressGestureRecognizer 一旦用户开始长时间触摸它 我就会检查此 LongPre
  • 窗口向左无闪烁扩展(调整大小)

    假设您有一个可以向左展开以显示其他控件的表单 折叠 扩展 在 Delphi 中实现这一点的最简单方法是使用alRight作为所有控件的主要锚点 而不是alLeft 然后只需调整表单的宽度和 X 坐标即可 您可以设置Width and Lef