简体   繁体   中英

Windows gadget in WPF - show while “Show desktop” is activated

I'm trying to create a "gadget" like application using WPF. The goal is to get the same behavior as a normal Windows 7 gadget:

  • No task-bar entry
  • Doesn't show up when you alt+tab windows
  • NOT always on top, applications can be on top
  • Visible while performing 'Aero Peek'
  • Visible while using 'Show desktop' / Windows+D

I've been able to accomplish the first four goals, but have been unable to find a solution to the fifth problem. The closest I've come is by using the utility class from How do you do AppBar docking (to screen edge, like WinAmp) in WPF? , but this turns the app into a "toolbar", thereby banishing applications from the part of the screen where my gadget GUI is placed.

I can see that similar questions has been asked previously on Stackoverflow, but those have died out before a solution was found. Posting anyway in the hope that there is now someone out there with the knowledge to solve this =)

Try setting Topmost to true, and when your application loses focus you could set Opacity to 0.

I did this Xaml:

<Window x:Class="OpacTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Topmost="True" Background="Transparent" ShowInTaskbar="False" AllowsTransparency="True" WindowStyle="None" Width="400" Height="300">
    <Grid>
       <Border Background="Black" CornerRadius="5" />
    </Grid>
</Window>

I did this in C# for the Window:

protected override void OnActivated(EventArgs e)
{
    base.OnActivated(e);

    Opacity = 1;
}

protected override void OnDeactivated(EventArgs e)
{
    base.OnDeactivated(e);

    Opacity = 0;
}

This gets you part of the way there; you need a way to know if the desktop gets focus.

I bet you could do this by hooking into the WndProc event of the desktop window and looking for WM_ACTIVATE.

You could:

  • Call GetDesktopWindow to get the handle of the desktop window
  • Use ap/invoke call to set a callback for the WndProc
  • Handle WM_ACTIVATE or the appropriate windows message and set your Opacity back to 1

You can implement an actual Windows Gadget using WPF by creating an XBAP. Just add a gadget.xml file and an .html file that contains only an IFRAME that loads the XBAP. That way your WPF application will actually be a gadget and will automatically follow all the rules.

Another option is to use Windows Sidebar Styler . This requires additional software to be installed alongside yours but also allows you to do things you can't do inside the XBAP sandbox without code signing certificates, user authorizaiton, etc.

A third option is to create a gadget that uses something recognizable in the HTML (such as a particular background color), then when your .exe starts up, scan for a hWnd under Explorer that has the attributes you are looking for, inject yourself into the Explorer.exe process, and set your window as a child of it.

A variation of the third option is to not inject into Explorer.exe but rather maintain your Z Index and location (using SetWindowPos) to track the Z Index and location of the hWnd you found.

So many choices...

I'll leave this here for future reference.

In Windows 10, parent your gadget window to Desktop using p/invoke. Will work with peek, show desktop and Win + D

    [DllImport("user32.dll")]
    static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    public static void SetOnDesktop(Window window)
    {
        IntPtr hWnd = new WindowInteropHelper(window).Handle;
        IntPtr hWndProgMan = FindWindow("Progman", "Program Manager");
        SetParent(hWnd, hWndProgMan);

    }

One solution to do achieve "gadget" like behavior, is to make your window a child of the desktop. In this way, your window is always visible on desktop even if you press Windows+D. You can see how it's done here: Window "on desktop" .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM