Click here to Skip to main content
15,887,946 members
Articles / Desktop Programming

Draw Behind Desktop Icons in Windows 8+

Rate me:
Please Sign up or sign in to vote.
4.97/5 (58 votes)
22 Dec 2014CPOL6 min read 192.6K   3.9K   70   86
Draw or render a Windows Form directly over the Wallpaper, behind the Desktop Icons in Windows 8+10

Introduction

Those who read this article probably know DreamScene, that Windows Vista feature, that allows to render video sequences (in .dream format) as desktop background. There is also a tool called rainmeter, that allows you to place widgets/gadgets/whatever on your desktop in a top most, top and bottom position. Also there is winamp, the first program, where I saw directx rendering in action behind the desktop icons.

These tools have one thing in common, they cannot do it in Windows 8, at least the "draw under the desktop icons" part they don't.

EDIT:

The approach described in this article also works for Windows 10. 

How It Used To Work (Windows XP, Vista, 7)

There is the window tree. This tree contains all windows that are currently displayed/or hidden on the current desktop and then there is a tool called Spy++ (Visual Studio -> Tools -> Spy++), that can be used to display and navigate that tree. That tool is part of Visual Studio.

The last leaf of this tree is the Program Manager. This window represents the whole shell. In Windows XP, Vista and 7 (Aero turned off) this Program Manager (Progman) contained a window (SysListView32), that rendered the desktop icons. So if you set that Program Manager as your parent window, you could position yourself right behind those desktop icons. EDIT: Scroll to the comments section below, there is a comment from Kristjan Skutta, that describes how to do it in windows 7 with aero turned on: http://www.codeproject.com/Messages/5164145/Re-Windows.aspx

There is a great article on drawing to the desktop (in front of and behind desktop icons) here on CodeProject:

But for the life of me, I could not find an approach that worked for Windows 8.

The Problem with Windows 8+

Windows 7 and Windows 8 are very similar. To make the Windows XP approach work for Windows 7, you had to turn off aero desktop. With Windows 8, you cannot turn aero off, so there has to be another way.

The following image shows how the window tree is structured in Windows 8.

Spy++ showing the bottom section of the window tree

The SysListView32 is now separated from the Program Manager. This alone is not that big of a problem.
The problem is the desktop background. It is now fused with the Desktop Icons. So we can only draw over everything including the icons, or draw under everything including the background. It is not possible to position a window in the Z-Order so it is between the desktop icons and the desktop wallpaper. I tried every position.

A Way to Find a Solution

What led me to the solution presented in this article was the personalization dialog. When you set a wallpaper manually, you do not see a sudden change, instead the wallpaper is set using a smooth fade animation. In my opinion, such an animation is only possible if the system can somehow draw behind the desktop icons, since setting a wallpaper in rapid succession would be very slow and ugly.

So I set up Spy++, opened the personalization dialog and changed the wallpaper. It turns out, that when you change the desktop wallpaper, a new WorkerW window between the WorkerW instance that holds the Desktop Icons (SysListView32) and the Desktop Manager is created.

Spy++ showing the bottom section of the window tree

I took the handle of that new WorkerW window and put it into my test program and it was finally able to draw behind the desktop icons, directly above the wallpaper!

One problem remained. When I closed the personalization dialog, it took down that new WorkerW window with it.

I had to find a way to trigger the creation of this WorkerW window.

Spy++ reports the window as a sibling and child of the Program Manager, so it looks like the Program Manager creates it. I turned on message monitoring for the Program Manager using Spy++ and found what I was looking for.

Spy++ showing the bottom section of the window tree

Right after the click to change the desktop wallpaper, the Program Manager receives a bunch of messages. The first one being a user defined and undocumented message. This reeks after being "recently" added.

I extended the test program to send exactly this user defined message (0x052C) to the Program Manager. And it caused exactly what I was hoping for. After receiving the message, the Program Manager creates the WorkerW window.

With all ingredients ready, I wrote a small demo application that illustrates how to draw on the desktop (behind the icons) and how to put a window behind the desktop icons.

The Code

Obtain Program Manager Handle

First, we begin by finding the handle of the Progman window. We can use the <a href="http://www.pinvoke.net/default.aspx/user32/FindWindow.html">FindWindow</a> function provided by the Windows API to accomplish this task.

C#
// Fetch the Progman window
IntPtr progman = W32.FindWindow("Progman", null);

Send Message to Program Manager

To trigger the creation of a WorkerW window between the desktop icons and the wallpaper, we have to send the Program Manager a message. That message is an undocumented one, so there is no fancy Windows API name for it, except 0x052C. In order to send the message, we use the Windows API method <a href="http://www.pinvoke.net/default.aspx/user32/SendMessageTimeout.html">SendMessageTimeout</a>.

C#
IntPtr result = IntPtr.Zero;

// Send 0x052C to Progman. This message directs Progman to spawn a 
// WorkerW behind the desktop icons. If it is already there, nothing 
// happens.
W32.SendMessageTimeout(progman, 
                       0x052C, 
                       new IntPtr(0), 
                       IntPtr.Zero, 
                       W32.SendMessageTimeoutFlags.SMTO_NORMAL, 
                       1000, 
                       out result);

Obtain Handle to Newly Created Window

Now, we have to obtain a handle to that newly created WorkerW window. Since there is more than one window with title "" and class "WorkerW", we have to go through the window tree sequentially. This can be done using the <a href="http://www.pinvoke.net/default.aspx/user32/EnumWindows.html">EnumWindows</a> function.

<a href="http://www.pinvoke.net/default.aspx/user32/EnumWindows.html">EnumWindows</a> calls supplied EnumWindowProc for every top level window. From there, we can check if the current window contains a child named "SHELLDLL_DefView", which indicates that the current window represents the desktop icons. We then take the next sibling of that window.

C#
// Spy++ output
// .....
// 0x00010190 "" WorkerW
//   ...
//   0x000100EE "" SHELLDLL_DefView
//     0x000100F0 "FolderView" SysListView32
// 0x00100B8A "" WorkerW       <-- This is the WorkerW instance we are after!
// 0x000100EC "Program Manager" Progman

IntPtr workerw = IntPtr.Zero;

// We enumerate all Windows, until we find one, that has the SHELLDLL_DefView 
// as a child. 
// If we found that window, we take its next sibling and assign it to workerw.
W32.EnumWindows(new W32.EnumWindowsProc((tophandle, topparamhandle) =>
{
    IntPtr p = W32.FindWindowEx(tophandle, 
                                IntPtr.Zero, 
                                "SHELLDLL_DefView", 
                                IntPtr.Zero);

    if (p != IntPtr.Zero)
    {
        // Gets the WorkerW Window after the current one.
        workerw = W32.FindWindowEx(IntPtr.Zero, 
                                   tophandle, 
                                   "WorkerW", 
                                   IntPtr.Zero);
    }

    return true;
}), IntPtr.Zero);

Demo 1: Draw Graphics Between Icons and Wallpaper

With the workerw handle in hand, the fun stuff begins. The first demo is about using the System.Drawing classes to just draw something.

This demo draws a rectangle in the upper left corner of the desktop. If you use multiple monitors, be aware, that the desktop area spans a rectangle across all monitors, so make sure your left monitor is turned on and your monitor placement actually maps the top left corner to a monitor, in case you have four of them, with one atop the other three.

Note: Everything you draw onto this layer will stay there until you paint over it, invalidate it, or reset your wallpaper.

C#
// Get the Device Context of the WorkerW
IntPtr dc = W32.GetDCEx(workerw, IntPtr.Zero, (W32.DeviceContextValues)0x403);
if (dc != IntPtr.Zero)
{
    // Create a Graphics instance from the Device Context
    using (Graphics g = Graphics.FromHdc(dc))
    {

        // Use the Graphics instance to draw a white rectangle in the upper 
        // left corner. In case you have more than one monitor think of the 
        // drawing area as a rectangle that spans across all monitors, and 
        // the 0,0 coordinate being in the upper left corner.
        g.FillRectangle(new SolidBrush(Color.White), 0, 0, 500, 500);

    }
    // make sure to release the device context after use.
    W32.ReleaseDC(workerw, dc);
}

Demo 2: Put a Windows Form behind desktop icons

This demo shows how to put a normal Windows Form behind desktop icons. In essence, this can be done by setting the parent of a Windows Form to our WorkerW window. To set the parent of a form, we can use the <a href="http://www.pinvoke.net/default.aspx/user32/SetParent.html">SetParent</a> Windows API function.

Note: For this function to work, the form has to be already created. The form.Load event seems to be the right place for it.

For the sake of a short example, I created the Form in place, without the "Project->Add Windows Form..." dialog and the designer.

C#
Form form = new Form();
form.Text = "Test Window";

form.Load += new EventHandler((s, e) =>
{
    // Move the form right next to the in demo 1 drawn rectangle
    form.Width = 500;
    form.Height = 500;
    form.Left = 500;
    form.Top = 0;

    // Add a randomly moving button to the form
    Button button = new Button() { Text = "Catch Me" };
    form.Controls.Add(button);
    Random rnd = new Random();
    System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
    timer.Interval = 100;
    timer.Tick += new EventHandler((sender, eventArgs) =>
    {
        button.Left = rnd.Next(0, form.Width - button.Width);
        button.Top = rnd.Next(0, form.Height - button.Height);
    });
    timer.Start();

    // This line makes the form a child of the WorkerW window, 
    // thus putting it behind the desktop icons and out of reach 
    // for any user input. The form will just be rendered, no 
    // keyboard or mouse input will reach it. You would have to use 
    // WH_KEYBOARD_LL and WH_MOUSE_LL hooks to capture mouse and 
    // keyboard input and redirect it to the windows form manually, 
    // but that's another story, to be told at a later time.
    W32.SetParent(form.Handle, workerw);
});

// Start the Application Loop for the Form.
Application.Run(form);

You will probably notice that there is no way to interact with the form, once its parent is set to the WorkerW window. The desktop is not designed to have interactive children, so all events regarding mouse movement, keyboard input, etc. will not reach our Form.

There is a way around that. You can subscribe to the low level WH_KEYBOARD_LL and WH_MOUSE_LL events, also known from key loggers and mouse capture software. Via those events, you can receive mouse movements, clicks and key presses regardless of where they occur. You would have to forward those messages to your form and perform your own hit testing.

Conclusion

One command to rule them all ;)

C#
W32.SendMessageTimeout(W32.FindWindow("Progman", null), 
                       0x052C, 
                       new IntPtr(0), 
                       IntPtr.Zero, 
                       W32.SendMessageTimeoutFlags.SMTO_NORMAL, 
                       1000, 
                       out result);

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) SecureGUARD GmbH
Austria Austria
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionHow to prevent a new workerw to spawn when wallper is changed Pin
Member 1327764215-Mar-24 9:17
Member 1327764215-Mar-24 9:17 
Suggestionabout mouse Pin
Rankor 20248-Jan-24 4:06
Rankor 20248-Jan-24 4:06 
QuestionMarshal::GetLastWin32Error have unpredictable result Pin
RoninZhao8-Feb-23 21:18
RoninZhao8-Feb-23 21:18 
SuggestionI converted to VB.NET and it works great Pin
Member 137929308-May-22 19:47
Member 137929308-May-22 19:47 
Your main group for WPF VB.NET

<pre>
    Public Shared Sub EmbedDesktop()
        PrintVisibleWindowHandles(2)
        Dim progman As IntPtr = W32.FindWindow("Progman", Nothing)
        Dim result = IntPtr.Zero
        W32.SendMessageTimeout(progman, &H52C, New IntPtr(0), IntPtr.Zero, W32.SendMessageTimeoutFlags.SMTO_NORMAL, 1000, result)
        PrintVisibleWindowHandles(2)
        Dim workerw = IntPtr.Zero
        W32.EnumWindows(New W32.EnumWindowsProc(Function(tophandle, topparamhandle)
                                                    Dim p As IntPtr = W32.FindWindowEx(tophandle, IntPtr.Zero, "SHELLDLL_DefView", IntPtr.Zero)
                                                    If p <> IntPtr.Zero Then
                                                        workerw = W32.FindWindowEx(IntPtr.Zero, tophandle, "WorkerW", IntPtr.Zero)
                                                    End If
                                                    Return True
                                                End Function), IntPtr.Zero)

        Dim DrawBetweenDesktopInstance As DrawBetweenDesktop = New DrawBetweenDesktop()
        DrawBetweenDesktopInstance.Title = "Test Window"
        DrawBetweenDesktopInstance.Show()
        Dim windowHandle As IntPtr = New WindowInteropHelper(DrawBetweenDesktopInstance).Handle

        W32.SetParent(windowHandle, workerw)


    End Sub
    Public Shared Sub PrintVisibleWindowHandles(ByVal hwnd As IntPtr, ByVal Optional maxLevel As Integer = -1, ByVal Optional level As Integer = 0)
        Dim isVisible As Boolean = W32.IsWindowVisible(hwnd)
        If isVisible AndAlso (maxLevel = -1 OrElse level <= maxLevel) Then
            Dim className As StringBuilder = New StringBuilder(256)
            W32.GetClassName(hwnd, className, className.Capacity)
            Dim windowTitle As StringBuilder = New StringBuilder(256)
            W32.GetWindowText(hwnd, windowTitle, className.Capacity)
            Console.WriteLine("".PadLeft(level * 2) & "0x{0:X8} ""{1}"" {2}", hwnd.ToInt64(), windowTitle, className)
            level += 1
            W32.EnumChildWindows(hwnd, New W32.EnumWindowsProc(Function(childhandle, childparamhandle)
                                                                   PrintVisibleWindowHandles(childhandle, maxLevel, level)
                                                                   Return True
                                                               End Function), IntPtr.Zero)
        End If
    End Sub
    Private Shared Sub PrintVisibleWindowHandles(ByVal Optional maxLevel As Integer = -1)
        W32.EnumWindows(New W32.EnumWindowsProc(Function(tophandle, topparamhandle)
                                                    PrintVisibleWindowHandles(tophandle, maxLevel)
                                                    Return True
                                                End Function), IntPtr.Zero)
    End Sub




Imports System
Imports System.Runtime.InteropServices
Imports System.Text

Public Class W32
    Public Const SM_CXSCREEN As Integer = 0
    Public Const SM_CYSCREEN As Integer = 1
    Public Const SPI_SETDESKWALLPAPER As Integer = 20
    Public Const SPIF_SENDWININICHANGE As Integer = &H2
    Public Const SPIF_UPDATEINIFILE As Integer = &H1
    Public Const SRCCOPY As Integer = 13369376
    Public Const WM_GETICON As Integer = &H7F
    Public Delegate Function EnumWindowsProc(ByVal hwnd As IntPtr, ByVal lParam As IntPtr) As Boolean
    <Flags>
    Public Enum BbFlags As Byte 'Blur Behind Flags
        DwmBbEnable = 1
        DwmBbBlurregion = 2
        DwmBbTransitiononmaximized = 4
    End Enum
    <Flags()>
    Public Enum DeviceContextValues As UInteger
        Window = &H1
        Cache = &H2
        NoResetAttrs = &H4
        ClipChildren = &H8
        ClipSiblings = &H10
        ParentClip = &H20
        ExcludeRgn = &H40
        IntersectRgn = &H80
        ExcludeUpdate = &H100
        IntersectUpdate = &H200
        LockWindowUpdate = &H400
        UseStyle = &H10000
        Validate = &H200000
    End Enum
    <Flags>
    Public Enum RedrawWindowFlags As UInteger
        Invalidate = &H1
        InternalPaint = &H2
        [Erase] = &H4
        Validate = &H8
        NoInternalPaint = &H10
        NoErase = &H20
        NoChildren = &H40
        AllChildren = &H80
        UpdateNow = &H100
        EraseNow = &H200
        Frame = &H400
        NoFrame = &H800
    End Enum
    <Flags()>
    Public Enum SetWindowPosFlags As UInteger
        AsynWindowPos = &H4000
        DeferErase = &H2000
        DrawFrame = &H20
        FrameChanged = &H20
        HideWindow = &H80
        NoActivate = &H10
        NoCopyBits = &H100
        NoMove = &H2
        NoOwnerZOrder = &H200
        NoRedraw = &H8
        NoReposition = &H200
        NoSendChanging = &H400
        NoSize = &H1
        NoZOrder = &H4
        ShowWindow = &H40
    End Enum
    Public Enum WindowLongFlags As Integer
        GWL_EXSTYLE = -20
        GWLP_HINSTANCE = -6
        GWLP_HWNDPARENT = -8
        GWL_ID = -12
        GWL_STYLE = -16
        GWL_USERDATA = -21
        GWL_WNDPROC = -4
        DWLP_USER = &H8
        DWLP_MSGRESULT = &H0
        DWLP_DLGPROC = &H4
    End Enum
    <Flags>
    Public Enum WindowStyles As UInteger
        WS_BORDER = &H800000
        WS_CAPTION = &HC00000
        WS_CHILD = &H40000000
        WS_CLIPCHILDREN = &H2000000
        WS_CLIPSIBLINGS = &H4000000
        WS_DISABLED = &H8000000
        WS_DLGFRAME = &H400000
        WS_GROUP = &H20000
        WS_HSCROLL = &H100000
        WS_MAXIMIZE = &H1000000
        WS_MAXIMIZEBOX = &H10000
        WS_MINIMIZE = &H20000000
        WS_MINIMIZEBOX = &H20000
        WS_OVERLAPPED = &H0
        WS_POPUP = &H80000000UI
        WS_SIZEFRAME = &H40000
        WS_SYSMENU = &H80000
        WS_TABSTOP = &H10000
        WS_VISIBLE = &H10000000
        WS_VSCROLL = &H200000
    End Enum
    <Flags>
    Public Enum WindowStylesEx As UInteger
        WS_EX_ACCEPTFILES = &H10
        WS_EX_APPWINDOW = &H40000
        WS_EX_CLIENTEDGE = &H200
        WS_EX_COMPOSITED = &H2000000
        WS_EX_CONTEXTHELP = &H400
        WS_EX_CONTROLPARENT = &H10000
        WS_EX_DLGMODALFRAME = &H1
        WS_EX_LAYERED = &H80000
        WS_EX_LAYOUTRTL = &H400000
        WS_EX_LEFT = &H0
        WS_EX_LEFTSCROLLBAR = &H4000
        WS_EX_LTRREADING = &H0
        WS_EX_MDICHILD = &H40
        WS_EX_NOACTIVATE = &H8000000
        WS_EX_NOINHERITLAYOUT = &H100000
        WS_EX_NOPARENTNOTIFY = &H4
        WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE Or WS_EX_CLIENTEDGE
        WS_EX_PALETTEWINDOW = WS_EX_WINDOWEDGE Or WS_EX_TOOLWINDOW Or WS_EX_TOPMOST
        WS_EX_RIGHT = &H1000
        WS_EX_RIGHTSCROLLBAR = &H0
        WS_EX_RTLREADING = &H2000
        WS_EX_STATICEDGE = &H20000
        WS_EX_TOOLWINDOW = &H80
        WS_EX_TOPMOST = &H8
        WS_EX_TRANSPARENT = &H20
        WS_EX_WINDOWEDGE = &H100
    End Enum
    <Flags>
    Public Enum SendMessageTimeoutFlags As UInteger
        SMTO_NORMAL = &H0
        SMTO_BLOCK = &H1
        SMTO_ABORTIFHUNG = &H2
        SMTO_NOTIMEOUTIFNOTHUNG = &H8
        SMTO_ERRORONEXIT = &H20
    End Enum
    <DllImport("gdi32.dll", EntryPoint:="BitBlt")>
    Public Shared Function BitBlt(ByVal hdcDest As IntPtr, ByVal xDest As Integer, ByVal yDest As Integer, ByVal wDest As Integer, ByVal hDest As Integer, ByVal hdcSource As IntPtr, ByVal xSrc As Integer, ByVal ySrc As Integer, ByVal RasterOp As Integer) As Boolean
    End Function
    <DllImport("gdi32.dll", EntryPoint:="CreateCompatibleBitmap")>
    Public Shared Function CreateCompatibleBitmap(ByVal hdc As IntPtr, ByVal nWidth As Integer, ByVal nHeight As Integer) As IntPtr
    End Function
    <DllImport("gdi32.dll", EntryPoint:="CreateCompatibleDC")>
    Public Shared Function CreateCompatibleDC(ByVal hdc As IntPtr) As IntPtr
    End Function
    <DllImport("gdi32.dll", EntryPoint:="DeleteDC")>
    Public Shared Function DeleteDC(ByVal hDc As IntPtr) As IntPtr
    End Function
    <DllImport("gdi32.dll", EntryPoint:="DeleteObject")>
    Public Shared Function DeleteObject(ByVal hDc As IntPtr) As IntPtr
    End Function
    '[DllImport("dwmapi.dll")] public static extern int DwmEnableBlurBehindWindow(IntPtr hWnd, ref BbStruct blurBehind);
    '[DllImport("DwmApi.dll")] public static extern int DwmExtendFrameIntoClientArea(IntPtr hwnd, ref Margins pMarInset);
    '[DllImport("dwmapi.dll", EntryPoint = "#127", PreserveSig = false)] public static extern void DwmGetColorizationParameters(out DWM_COLORIZATION_PARAMS parameters);
    '[DllImport("dwmapi.dll", PreserveSig = false)] public static extern bool DwmIsCompositionEnabled();
    '[DllImport("dwmapi.dll")] public static extern int DwmIsCompositionEnabled(out bool enabled);
    '[DllImport("dwmapi.dll", EntryPoint = "#131", PreserveSig = false)] public static extern void DwmSetColorizationParameters(ref DWM_COLORIZATION_PARAMS parameters, long uUnknown);
    '[DllImport("dwmapi.dll")] public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
    <DllImport("user32.dll")>
    Public Shared Function EnumWindows(ByVal lpEnumFunc As EnumWindowsProc, ByVal lParam As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    <DllImport("user32.dll")>
    Public Shared Function EnumChildWindows(ByVal parentHandle As IntPtr, ByVal lpEnumFunc As EnumWindowsProc, ByVal lParam As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    <DllImport("user32.dll", SetLastError:=True)>
    Public Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    End Function
    <DllImport("user32.dll", SetLastError:=True)>
    Public Shared Function FindWindowEx(ByVal parentHandle As IntPtr, ByVal childAfter As IntPtr, ByVal className As String, ByVal windowTitle As IntPtr) As IntPtr
    End Function
    <DllImport("user32.dll")>
    Public Shared Function GetClassLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer) As UInteger
    End Function
    <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
    Public Shared Function GetClassName(ByVal hWnd As IntPtr, ByVal lpClassName As StringBuilder, ByVal nMaxCount As Integer) As Integer
    End Function
    <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
    Public Shared Function GetWindowText(ByVal hWnd As IntPtr, ByVal lpWindowText As StringBuilder, ByVal nMaxCount As Integer) As Integer
    End Function
    <DllImport("user32.dll", EntryPoint:="GetDC")>
    Public Shared Function GetDC(ByVal ptr As IntPtr) As IntPtr
    End Function
    <DllImport("user32.dll")>
    Public Shared Function GetDCEx(ByVal hWnd As IntPtr, ByVal hrgnClip As IntPtr, ByVal flags As DeviceContextValues) As IntPtr
    End Function
    <DllImport("user32.dll", EntryPoint:="GetDesktopWindow")>
    Public Shared Function GetDesktopWindow() As IntPtr
    End Function
    <DllImport("user32.dll")>
    Public Shared Function GetForegroundWindow() As IntPtr
    End Function
    <DllImport("user32.dll", ExactSpelling:=True, CharSet:=CharSet.Auto)>
    Public Shared Function GetParent(ByVal hWnd As IntPtr) As IntPtr
    End Function
    <DllImport("user32.dll")>
    Public Shared Function GetShellWindow() As IntPtr
    End Function
    <DllImport("user32.dll", EntryPoint:="GetSystemMetrics")>
    Public Shared Function GetSystemMetrics(ByVal abc As Integer) As Integer
    End Function
    <DllImport("user32.dll", EntryPoint:="GetWindowDC")>
    Public Shared Function GetWindowDC(ByVal ptr As Integer) As IntPtr
    End Function
    <DllImport("user32.dll")>
    Public Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As Boolean
    End Function
    '[DllImport("user32.dll")] public static extern bool RedrawWindow(IntPtr hWnd, [In] ref RECT lprcUpdate, IntPtr hrgnUpdate, RedrawWindowFlags flags);
    <DllImport("user32.dll")>
    Public Shared Function RedrawWindow(ByVal hWnd As IntPtr, ByVal lprcUpdate As IntPtr, ByVal hrgnUpdate As IntPtr, ByVal flags As RedrawWindowFlags) As Boolean
    End Function
    <DllImport("user32.dll", EntryPoint:="ReleaseDC")>
    Public Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDc As IntPtr) As IntPtr
    End Function
    <DllImport("gdi32.dll", EntryPoint:="SelectObject")>
    Public Shared Function SelectObject(ByVal hdc As IntPtr, ByVal bmp As IntPtr) As IntPtr
    End Function
    <DllImport("user32.dll", CharSet:=CharSet.Auto)>
    Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As IntPtr) As IntPtr
    End Function
    <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
    Public Shared Function SendMessageTimeout(ByVal windowHandle As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr, ByVal flags As SendMessageTimeoutFlags, ByVal timeout As UInteger, <Out> ByRef result As IntPtr) As IntPtr
    End Function
    <DllImport("user32.dll", SetLastError:=True)>
    Public Shared Function SetParent(ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr
    End Function
    <DllImport("kernel32.dll")>
    Public Shared Function SetProcessWorkingSetSize(ByVal handle As IntPtr, ByVal minimumWorkingSetSize As Integer, ByVal maximumWorkingSetSize As Integer) As Boolean
    End Function
    <DllImport("user32.dll")>
    Public Shared Function EnableWindow(ByVal hWnd As IntPtr, ByVal bEnable As Boolean) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    <DllImport("user32.dll")>
    Public Shared Function SetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As WindowLongFlags, ByVal dwNewLong As Integer) As Integer
    End Function
    <DllImport("user32.dll")>
    Public Shared Function SetWindowPos(ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As SetWindowPosFlags) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    <DllImport("user32.dll", CharSet:=CharSet.Auto)>
    Public Shared Function SystemParametersInfo(ByVal action As UInteger, ByVal uParam As UInteger, ByVal vParam As String, ByVal winIni As UInteger) As Integer
    End Function


End Class


QuestionFor Windows 7 without Aero Pin
dsg mjf18-Mar-22 20:44
dsg mjf18-Mar-22 20:44 
QuestionHow to move the window consistently if the Primary Monitor is not the first one on the left) Pin
Z3N1G4T418-Feb-22 3:03
Z3N1G4T418-Feb-22 3:03 
GeneralMy vote of 5 Pin
a5nb11-Feb-22 6:39
a5nb11-Feb-22 6:39 
QuestionTransparent Canvas look Pin
Gerry Lindsay21-Apr-21 10:35
Gerry Lindsay21-Apr-21 10:35 
GeneralMy vote of 5 Pin
Armand124-Mar-21 8:14
Armand124-Mar-21 8:14 
QuestionAmazing stuff man Pin
StargazeR Weerakkody10-Jul-20 8:36
StargazeR Weerakkody10-Jul-20 8:36 
QuestionVery Slow Bitmap Drawing Pin
Erik Turner4-Jul-20 5:16
Erik Turner4-Jul-20 5:16 
AnswerRe: Very Slow Bitmap Drawing Pin
Gerald Degeneve15-Apr-21 17:45
professionalGerald Degeneve15-Apr-21 17:45 
SuggestionBetter parameters for SendMessage 0x52C to support high-contrast mode Pin
Kristjan Skutta2-Jul-20 10:30
Kristjan Skutta2-Jul-20 10:30 
GeneralGreat Article and I've created a project to show videos and images on your desktop wallpaper Pin
AlexanderPro27-Aug-19 4:56
AlexanderPro27-Aug-19 4:56 
GeneralThe Graphics stops working after about 20 seconds Pin
datvm10-Aug-19 17:00
datvm10-Aug-19 17:00 
SuggestionHow It Used To Work Pin
Konstantin Pandipulovich24-May-19 9:56
Konstantin Pandipulovich24-May-19 9:56 
QuestionThank you Pin
Sandro Dzaganishvili9-Mar-19 1:10
Sandro Dzaganishvili9-Mar-19 1:10 
QuestionHow to disable it and add other winform apps to behind the desktop icons Pin
dddrrr5-Sep-18 13:04
dddrrr5-Sep-18 13:04 
QuestionClear drawed objects Pin
Member 1330553810-Jun-18 0:49
Member 1330553810-Jun-18 0:49 
AnswerRe: Clear drawed objects Pin
Gerald Degeneve1-Aug-18 10:30
professionalGerald Degeneve1-Aug-18 10:30 
GeneralRe: Clear drawed objects Pin
Member 144800594-Jun-19 0:25
Member 144800594-Jun-19 0:25 
AnswerRe: Clear drawed objects Pin
Member 1066863228-Apr-20 15:36
Member 1066863228-Apr-20 15:36 
GeneralRe: Clear drawed objects Pin
Armand127-Mar-21 6:39
Armand127-Mar-21 6:39 
QuestionHow to redirect WH_MOUSE_LL to form? Pin
KimNeutral10-Dec-17 20:32
KimNeutral10-Dec-17 20:32 
AnswerRe: How to redirect WH_MOUSE_LL to form? Pin
Gerald Degeneve1-Aug-18 10:32
professionalGerald Degeneve1-Aug-18 10:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.