【问题标题】:How to trigger screen repaint in Windows 7如何在 Windows 7 中触发屏幕重绘
【发布时间】:2014-05-01 21:36:08
【问题描述】:

问题
我在我的笔记本电脑(Windows 7 x64)上遇到了这个非常奇怪的问题,因为它随机(在屏幕上的时间和位置)扰乱了我的屏幕部分。下面是一些例子:

我可以通过选择和取消选择文本或将窗口移出屏幕然后重新打开来暂时解决此问题(并不总是有效),但这变得相当令人沮丧。 我的想法是让一些代码(我熟悉 VB.Net 和 Java)在后台运行,并每隔 200 毫秒左右触发整个屏幕的重绘。我用谷歌搜索了一下,只找到了可以在 .Net 中触发重绘控件或表单的代码。这也能做到吗?

我正在寻找修复症状解决方案的原因有两个:我正在寻找一种比重新安装更简单的解决方案,我很好奇我正在尝试的解决方案是否可行. (我猜这将是一些 WMI 或 user32.dll 导入的东西,但我不知道从哪里/如何开始。)

PS:我知道这看起来像是超级用户的问题,但我正在寻找一个编码解决方案,所以我希望我在这里提问是正确的。

解决方案
@jo0ls 解决方案适用于 gpu 未渲染的大约 90% 的内容,这很棒。这是我的代码版本:

'DLL import stuff
<DllImport("user32.dll")>
Private Shared Function InvalidateRect(hWnd As IntPtr, rect As IntPtr, clear As Boolean) As Boolean
End Function

<DllImport("user32.dll")>
Private Shared Function UpdateWindow(hWnd As IntPtr) As Boolean
End Function

'Core refresh function, which calls dll-imported-functions
Private Sub _Refresh()
    InvalidateRect(IntPtr.Zero, IntPtr.Zero, True)
    UpdateWindow(IntPtr.Zero)
End Sub

这不起作用的一个例子是谷歌浏览器。我已经用不同的方式解决了这个问题,但是我在书签栏上做了一个书签:

javascript:(function(){
    var _d=document;
    var _b=_d.body;
    var _el=_d.createElement("div");
    _el.style.cssText="
        background-color: rgba(157, 250, 149, 0);
        position: fixed;
        top: 0px;
        left: 0px;
        box-sizing: border-box;
        width: 100%;
        height: 100%;
        z-index: 9999;
        display: block;
    ";
    _b.appendChild(_el);
    setTimeout(function(){
        _b.removeChild(_el)
    },3)
})();

这实际上创建了一个透明覆盖,将其添加到 DOM,并在 3 毫秒后将其移除。这会在 Chrome 中触发重绘,并且(我假设)在其他浏览器中也会触发。

【问题讨论】:

  • 不是编程问题。您很可能有一个坏的视频驱动程序,应该用一个正常工作的驱动程序替换它。
  • 阅读倒数第二段。而且我已经尝试安装不同的驱动程序(实际上是几个)等等。我正在寻找一种方法来通过任何必要的方式触发 Windows 的 GUI 重绘,所以这是一个编程问题..
  • 您可能会使用GetDesktopWindow()InvalidateRect 的组合(请参阅MSDN),但这似乎是一个非常糟糕的主意。 “我想每秒浪费 5 次我的 CPU/GPU 的相当一部分来解决与显示驱动程序相关的问题”是一种消耗笔记本电脑电池寿命的杂物。您避免尝试通过联系笔记本电脑或显示器供应商来实际解决问题,但您的下一个问题将是“我可以做些什么来延长笔记本电脑的电池寿命?我必须每小时充电一次!”
  • 我一定会查一下,我知道你认为这是一个糟糕的主意(我同意)。就像我说的那样,我正在寻找一种治疗症状的解决方案,而不是实际的问题。您需要知道几件事:它是一台较旧的二手笔记本电脑(它是我唯一的计算机),我需要它来工作和赚钱,而且我目前没有时间进行全新安装,这可以明确告诉我它是否是硬件或驱动程序问题。哦,电池没电了,所以别担心;)我没有钱买新的,所以我不打算冒险破坏一台(半)工作的机器..

标签: vb.net windows google-chrome wmi dllimport


【解决方案1】:

Raymond Chen 讨论传递 IvalidateRect null here

我不确定重绘是否适用于 Windows 7。(博客上的 cmets 询问它是否适用于 DWM)。您可以尝试一下并找出答案。在服务器 2012 上,我的一些屏幕闪烁 - 例如托盘中的物品。

你可以从 vb.net 调用它:

<DllImport("user32.dll")>
Public Function InvalidateRect(hWnd As IntPtr, rect As IntPtr, clear As Boolean) As Boolean
End Function

<DllImport("user32.dll")>
Public Function UpdateWindow(hWnd As IntPtr) As Boolean
End Function

Sub Main()
    Dim result As Boolean = InvalidateRect(IntPtr.Zero, IntPtr.Zero, True)
    result = UpdateWindow(IntPtr.Zero)
End Sub

您也可以尝试发送 false,然后跳过 UpdateWindow 调用。

【讨论】:

  • 感谢您回答实际问题 :) 它显然似乎只对窗口的某些部分(菜单栏、一些标签等)有影响,例如没有影响在 Chrome 上。看起来这不适用于由 gpu 渲染的东西。必须让 InvalidateRect 和 UpdateWindow 函数共享 btw (让它们不会引发错误)。我想知道为什么你存储两者的结果而不使用它?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-14
  • 1970-01-01
  • 1970-01-01
  • 2010-10-24
  • 1970-01-01
相关资源
最近更新 更多