Reputation: 315
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);
Upvotes: 4
Views: 2813
Reputation: 51
While working on a calendar "glued to the desktop", I ran into the same problem. Here is my solution:
/************ win32 interop stuff ****************/
[DllImport( "user32.dll", SetLastError = true )]
static extern int SetWindowLong( IntPtr hWnd, int nIndex, IntPtr dwNewLong );
[DllImport( "user32.dll", SetLastError = true )]
static extern IntPtr FindWindow( string lpWindowClass, string lpWindowName );
[DllImport( "user32.dll", SetLastError = true )]
static extern IntPtr FindWindowEx( IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle );
const int GWL_HWNDPARENT = -8;
/************* in Form_Load or equivalent ***************/
IntPtr hprog = FindWindowEx(
FindWindowEx(
FindWindow( "Progman", "Program Manager" ),
IntPtr.Zero, "SHELLDLL_DefView", ""
),
IntPtr.Zero, "SysListView32", "FolderView"
);
SetWindowLong( this.Handle, GWL_HWNDPARENT, hprog );
The tricky part was to set the form's owner (SetWindowLong + GWL_HWNDPARENT) instead of the form's parent (SetParent). This fixed the form not being rendered on an aero desktop.
Upvotes: 2
Reputation: 315
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);
}
Upvotes: 2
Reputation: 46653
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.
Upvotes: 0