TheLegendaryCopyCoder
TheLegendaryCopyCoder

Reputation: 1842

WinForm ZIndex to Desktop

As a fun office project we are building a cool transitional background Winform's app to replace the standard windows desktop background.

One of the challenges is that we need our WinForm window to sit on top of the desktop background and icons but not the taskbar.

Is there some way to precisely adjust the Z-Index of a winform window so that it sits on top of the windows desktop but still allows the taskbar and other windows to sit on top of it?


Thank you for the assistance in getting this working. The following worked for us.

[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
    public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);

    const short SWP_NOMOVE = 0X2;
    const short SWP_NOSIZE = 1;
    const short SWP_NOZORDER = 0X4;
    const int SWP_SHOWWINDOW = 0x0040;

Usage as follows.

        // Our desktop is the top most window.  
        IntPtr desktop = new IntPtr(0);
        // The running form we are testing this code with.
        IntPtr form1 = System.Windows.Forms.Application.OpenForms[0].Handle;
        // So we're setting our window Z-index to that of the desktop, 
        // but we setting flags for showing the window and then not not moving and resizing it.            
        SetWindowPos(form1, desktop, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);

The Spy++ is really a great tool to learn about the structure of windows and child windows. We found out that setting the IntPtr to Zero will automatically make it select the Desktop (most top) window.

Upvotes: 3

Views: 1499

Answers (1)

Mihail Shishkov
Mihail Shishkov

Reputation: 15857

Download spy++ http://mdb-blog.blogspot.com/2010/11/microsoft-spy-or-spyxx-for-download.html then check what's the desktop handle and the start menu handle respectively. This is just to make the proof of concept later you have to find out a better way of taking the handles. Using P\Invoke calls you can get those windows z-order

int GetZOrder(IntPtr hWnd)
{
    var z = 0;
    for (IntPtr h = hWnd; h != IntPtr.Zero; h = GetWindow(h, 3)) z++;
    return z;
} 

That code was copied from this question How to get the z-order in windows?

Then you can use SetWindowPos https://msdn.microsoft.com/en-us/library/windows/desktop/ms633545%28v=vs.85%29.aspx to position your own windows exactly where you want it to be. If you are using windows 8 have in mind that a lot of folks have ClassicShell installed on their machines. Good luck.

Upvotes: 2

Related Questions