如何在Windows 7中触发屏幕重绘

时间:2014-05-01 21:36:08

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

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

artefacts_1 artefacts_2 artefacts_3

我可以暂时解决这个问题,方法是选择和取消选择文字,或者将窗口移到屏幕外再重新打开(不能一直工作),但它会变得非常令人沮丧。 我的想法是让一些代码(我熟悉VB.Net和Java)在后台运行并每隔200ms左右触发整个屏幕的重绘。我已经搜索了一下,并且只找到了可以在.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

这不起作用的一个例子是Google Chrome。我以不同的方式解决了这个问题,但我在书签栏上做了一个书签:

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 ms后将其删除。这会在Chrome中触发重新绘制,并且(我也会假设)在其他浏览器中也是如此。

1 个答案:

答案 0 :(得分:1)

Raymond Chen讨论了传递IvalidateRect null here

我不确定重绘是否适用于Windows 7.(博客上的评论询问它是否适用于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调用。