小编Lou*_*ini的帖子

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

问题:当我抓住我的Windows应用程序的调整大小边框,特别是顶部或左边框,并调整窗口大小时,窗口的内容会在我拖动时调整"实时"大小,但是它们会以一种看似像的丑陋方式调整大小即使是最新手的用户也是一个明显的错误:窗口相对边缘的内容从边缘拖动抖动/闪烁/来回跳跃.视情况而定,现象可能如下:

  • 似乎从窗口边缘走出的内容,当我们减速或停止拖动时快速回弹
  • 似乎拉入窗户的内容,间歇性地被不同颜色的边界移位,通常是黑色或白色
  • 一个严重丑陋的"双重图像",内容的两个重叠副本被移动的距离与我们拖动的速度/速度成正比

一旦我停止拖动,丑陋的现象就会停止,但在拖动过程中,它会使应用程序看起来很业余和不专业.

说这个Windows问题已经让成千上万的应用程序开发人员疯狂,这并不是轻描淡写的.

以下是现象,友好地准备了两个实例图片一个相关的问题罗马Starkov:

例1:抖动

例2:边界

另一个例子展示了Kenny Liu的邪恶"双重图像"现象(请注意快速闪光):

例2:双重图像

有关任务管理器现象的另一个示例视频就在这里.

这个问题的目的: 任何遇到这个问题的开发人员都会发现至少有30个StackOverflow问题,其中一些是最近的,有些是从2008年开始的,充满了很有希望的答案很少有效.现实情况是,这一个问题有很多原因,而现有的StackOverflow问题/答案从未使更广泛的背景清晰.这个问题试图回答:

  • 什么是这种丑陋的抖动/闪烁/跳跃的最可能的原因?
  • 我怎么知道我看到的原因?
  • 这是特定于特定图形驱动程序或Windows常规的原因吗?
  • 我该如何解决每个原因?应用程序可以修复它吗?

本问题的范围:对于StackOverflow问题的范围,这种现象发生在:

  • 本机Win32和托管.NET/WPF/Windows窗体应用程序
  • 正常的Win32窗口和Win32对话窗口
  • Windows版本包括XP,Vista,7,8和10(但请参阅下面的多个原因的黑暗真相)

请勿标记为广泛或DUP:在标记为复制或标记为广泛之前,请阅读以下完整答案.我们已经经历了这个循环,SO用户在理解了以下内容之后经常重新打开这个问题:这个问题有益于社区,是第一个解释窗口调整大小抖动的所有不同原因的问答,以便用户可以识别哪个原因导致他们的问题并解决它.下面的答案很长,只是因为解释为什么一般发生抖动是很棘手的,不是因为这个问题涵盖了许多单独的问题和问题,这些错误/问题可以通过单独的问答得到更好的服务.正如您将看到的,上面的所有排列(本机/托管,窗口/对话框,XP-10)都归结为只有两个根本原因,但识别您所拥有的是棘手的部分.这就是这个问题的意义所在.将问题分开将完全否定这一好处.我们在下一节中进一步限制了问题的范围......

不在本问题的范围内:

  • 如果您的应用程序有一个或多个子窗口(子HWND),则此问题中的信息对您很有用(因为BitBlts我们将描述的引起混蛋的内容与父窗口一起应用于您的子窗口),但在窗口调整大小时还有另外一个问题需要处理,这超出了这个问题的范围:你需要让你的所有子窗口以原子方式移动并与父窗口同步.对于这项任务,你可能会想要 BeginDeferWindowPos/DeferWindowPos/EndDeferWindowPos,你可以在这里这里找到它们.

  • 这个问题假设如果你的应用程序使用GDI,DirectX或OpenGL绘制到一个窗口,那么你已经WM_ERASEBKGND在你的应用程序中实现了一个wndproc简单的返回1. WM_ERASEBKGND是来自Windows 3.1的一个神秘的Windows残余,以前WM_PAINT给你的应用程序一个机会在你画窗户之前"擦掉窗户的背景"......嗯.如果你让WM_ERASEBKGND消息进入DefWindowProc(),那将导致你的整个窗口在每次重绘时被涂成纯色,通常是白色,包括在实时窗口大小调整期间发生的重绘.结果是一个丑陋的全窗口闪烁是粗略的,但不是我们在这个问题中讨论的抖动/闪烁/跳跃的类型.拦截WM_ERASEBKGND立即解决了这个问题.

  • 此问题主要是通过使用鼠标拖动窗口边框来实时调整大小.但是,此处编写的大部分内容也适用于当应用程序手动执行一次性窗口调整时可以看到的丑陋工件SetWindowPos().这些不太明显,因为它们只在屏幕上轻弹一瞬间,而不是长时间的拖动.

  • 这个问题不是关于如何使你的特定于应用程序的绘图代码更快,即使这样做可能是许多情况下丑陋的调整大小问题的解决方案.如果您的应用确实需要花费大量时间在实时窗口调整大小期间重新显示其内容,请考虑优化绘图代码,或者至少在调整大小期间切换到更快,质量更低的绘图模式,方法是拦截WM_ENTERSIZEMOVE/WM_EXITSIZEMOVE消息以检测调整大小.

  • 如果您的应用程序在应用程序调整大小期间根本无法调整大小(例如,在调整大小期间它"挂起",特别是如果它是使用GLFW或其他库的OpenGL),请参阅这些其他问题,这些问题解释了WM_SYSCOMMAND在拖动过程中Microsoft内部隐藏的嵌套/模态事件循环:这里特别是这个好的答案,这里,这里 …

windows directx winapi resize window-resize

25
推荐指数
5
解决办法
1964
查看次数

iOS OpenGL Catch-22:OpenGL后台规则和App Switcher的"应用程序快照"

像许多开发人员一样,我有一个通过UIView子类使用OpenGL的应用程序,该子类的layerClass:方法返回[CAEAGLLayer class].

注意我没有使用GLKitGLKViewGLKViewController

当我点击Home将应用程序放入后台时applicationDidEnterBackground,iOS调用我的视图layoutSubviews两次,使用纵向和横向大小,尝试生成"应用程序快照",如此处所述(请参阅"准备应用程序快照"):

https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/StrategiesforHandlingAppStateTransitions/StrategiesforHandlingAppStateTransitions.html#//apple_ref/doc/uid/TP40007072-CH8-SW10

这怎么可能有效呢?

这里似乎有一个直接的矛盾与此页面上非常明确的建议(请参阅"后台应用程序可能无法在图形硬件上执行命令"):

https://developer.apple.com/library/ios/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/ImplementingaMultitasking-awareOpenGLESApplication/ImplementingaMultitasking-awareOpenGLESApplication.html#//apple_ref/doc/uid/TP40008793-CH5-SW1

以后我们不能用OpenGL绘制任何东西 applicationDidEnterBackground

如果我们不绘制,我们就无法生成快照.我们必须违反一条规则或另一条规则.

但我们也希望在两个方向都有很好的快照,这样当用户双击主页并转到App Switcher时,他们会看到合理的快照图像.

即使我暂时改变我的代码以通过创建OpenGL表面和绘图(这与Apple dox相反,不会崩溃)完全实现layoutSubviewsafter applicationDidEnterBackground,然后我双击home并以不同方向查看快照,仅我之前所处方向的快照是正确的.另一个是另一个快照的超级丑陋的重新缩放.Apple似乎正在经历拍摄快照的动作,但实际上没有拍摄它们.

我在iPad Mini上看到iOS 9.3.2上的这种行为.大多数/所有iPhone设备都没有显示该行为,因为它们不支持横向App切换器.

更新:问题也发生了,并且更糟糕的是,当使用新的iOS 9"幻灯片"多任务处理功能并在正常的全屏应用程序与在另一个应用程序上滑动的应用程序之间切换相同的应用程序时.iOS似乎只捕获最后一个应用程序大小的快照,所以在使用640px宽的应用程序然后尝试使用App Switcher进入应用程序全屏后,我们在应用程序中看到一个奇怪的像素超出比例的快照切换器也在发射的第一秒.必须有一些方法来解决这个问题!

更新2:我见过几个iOS应用程序,我知道这些应用程序是OpenGL专用的应用程序,如果你以纵向方式使用它们,那么回到Home并旋转到横向,然后双击Home,你会看到纵向启动图像而不是像我所看到的那种可怕的,扭曲的,不对称的图像.虽然我更喜欢渲染快照图像,但我甚至很乐意看到启动图像.但选择大家提到了,ignoreSnapshotOnNextApplicationLaunch,不工作,因为它不仅影响你在实际的应用程序启动时间看,没有什么是在应用程序切换时看到您双击主页,并为许多在计算器上,它实际上甚至没有工作完全(甚至在发射时).

我们如何绕过这个Catch-22?

这个StackOverflow线程(与我不同,OP在这里使用GLKit,但症状是相同的):

iOS OpenGL ES屏幕旋转,而后台应用栏可见

确认iOS 上的一些OpenGL应用程序能够在Home双按应用切换器中为两个方向都拥有正确的预览图像.他们是如何做到的呢?

如何在App Switcher中以两个方向显示正确的快照?

这是一个来自iOS 的AppDelegate(appdel),ViewController(eaglc)和View(eaglv)调用的日志,当我单击Home按钮一次退出应用程序时.您可以在以下情况下看到快照的尝试didEnterBackground:

+  189.57ms      appdel appWillResignActive
+    0.74ms        appdel appWillResignActive between_view_os_callbacks 0
+ …

opengl-es objective-c ipad ios layoutsubviews

9
推荐指数
0
解决办法
352
查看次数