質問

The problem
I have this really weird problem on my laptop (Windows 7 x64) in that it randomly (both in time and position on screen) scrambles parts of my screen. Here's some examples:

artefacts_1 artefacts_2 artefacts_3

I can temporarily solve this by selecting and unselecting text or by moving a window offscreen and back on again (doesn't always work), but it's become fairly frustrating. My idea is to have some code (I'm familiar with VB.Net and Java) run in the background and trigger a repaint of the entire screen every 200ms or so. I've googled a bit, and have only found code that can trigger a repaint of a control or form in .Net. Can this even be done?

The reason I'm looking for a fix-the-symptoms-solution is twofold: I'm looking for an easier solution than a re-install and I'm curious to see if what I'm trying to is possible. (I'm guessing it's going to be some WMI or user32.dll import stuff, but I have no idea where/how to begin.)

PS: I know this could look like a question for superuser, but I'm looking for a coding-solution, so I hope I'm correct in asking it here.

The solution
@jo0ls solution works for about 90% of what's not rendered by the gpu, which is great. Here's my version of the code:

'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

An example of where this doesn't work is Google Chrome. I've solved this in a different way however, I made a bookmark on the bookmarks bar:

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)
})();

This essentially creates a transparent overlay, adds it to the DOM, and removes it after 3 ms. This triggers a repaint in Chrome, and (I'm assuming) in other browsers too.

役に立ちましたか?

解決

Raymond Chen discusses passing IvalidateRect null here.

I'm not sure if the redraw will work with windows 7. (The comments on the blog ask whether it works with DWM). You can try it and find out. On server 2012, some of my screen flickers - e.g. items in the tray.

You can call it from vb.net with:

<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

You could also try sending false, and skipping the UpdateWindow call.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top