views:

90

answers:

2

How could I achieve "pin to desktop" effect (i.e immune against "Show Desktop" command) in Win 7, using FindWindow + SetParent approach, or any other approach that would work in XP as well ? I know I could create a gadget, but I'd like to have backwards compatibility with XP, where I have this code doing it fine:

IntPtr hWnd = FindWindow(null, "Untitled - Notepad");
IntPtr hDesktop = FindWindow("ProgMan", "Program Manager");
SetParent(hWnd, hDesktop);
A: 

The answers to this question should help:

If not, you could implement it as an active desktop application in XP. Or if it's a simple view-only application, you could actually draw on the desktop wallpaper.

Colin Pickard
thanks this was an useful link. Anyway that simple "SetParent" way working in XP seems to be gone forever, right?
Andres
A: 

in my WPF app, I was able to solve it using a timer, it's working both in XP and Win 7.

public MainWindow()
{
    InitializeComponent();

    // have some timer to fire in every 1 second
    DispatcherTimer detectShowDesktopTimer = new DispatcherTimer();
    detectShowDesktopTimer.Tick += new EventHandler(detectShowDesktopTimer_Tick);
    detectShowDesktopTimer.Interval = new TimeSpan(0, 0, 1);
    detectShowDesktopTimer.Start();
}

#region support immunizing against "Show Desktop"
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);

private string GetWindowText(IntPtr handle)
{
    int chars = 256;
    StringBuilder buff = new StringBuilder(chars);
    if (GetWindowText(handle, buff, chars) > 0)
        return buff.ToString();
    else
        return string.Empty;
}
#endregion

private void detectShowDesktopTimer_Tick(object sender, EventArgs e)
{
    IntPtr fore = GetForegroundWindow();
    if (string.IsNullOrWhiteSpace(GetWindowText(fore)))
        ShowDesktopDetected();
}

private void ShowDesktopDetected()
{
    WindowInteropHelper wndHelper = new WindowInteropHelper(this);
    SetForegroundWindow(wndHelper.Handle);
}
Andres