WPF中的Windows小工具 - 激活“显示桌面”时显示

时间:2010-03-08 22:12:48

标签: c# wpf windows-desktop-gadgets

我正在尝试使用WPF创建一个类似应用程序的“小工具”。目标是获得与普通Windows 7小工具相同的行为:

  • 没有任务栏条目
  • 当您使用alt +标签窗口时不显示
  • 并不总是在顶部,应用程序可以在顶部
  • 在表演'Aero Peek'时可见
  • 使用“显示桌面”/ Windows + D
  • 时可见

我已经能够完成前四个目标,但一直无法找到第五个问题的解决方案。我最接近的是使用How do you do AppBar docking (to screen edge, like WinAmp) in WPF?中的实用程序类,但这会将应用程序变成“工具栏”,从而将应用程序从放置我的小工具GUI的屏幕部分中驱逐出去。

我可以看到之前在Stackoverflow上已经提出了类似的问题,但是在找到解决方案之前,这些问题已经消失。无论如何发布,希望现在有人在那里有解决这个问题的知识=)

4 个答案:

答案 0 :(得分:1)

尝试将Topmost设置为true,当应用程序失去焦点时,可以将Opacity设置为0。

我做了这个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>

我在C#中为Window做了这个:

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

    Opacity = 1;
}

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

    Opacity = 0;
}

这会让你成为那里的一部分;您需要一种方法来了解桌面是否获得焦点。

我打赌你可以通过挂钩桌面窗口的WndProc事件并寻找WM_ACTIVATE来做到这一点。

你可以:

  • 调用GetDesktopWindow获取桌面窗口的句柄
  • 使用p / invoke调用为WndProc设置回调
  • 处理WM_ACTIVATE或相应的窗口消息,并将不透明度设置为1

答案 1 :(得分:1)

您可以通过创建XBAP来使用WPF实现实际的Windows小工具。只需添加一个gadget.xml文件和一个仅包含加载XBAP的IFRAME的.html文件。这样,您的WPF应用程序实际上将成为一个小工具,并将自动遵循所有规则。

另一种选择是使用Windows Sidebar Styler。这需要与您的软件一起安装其他软件,但也允许您在没有代码签名证书,用户授权等的情况下执行XBAP沙箱中无法执行的操作。

第三个选项是创建一个使用HTML中可识别的内容的小工具(例如特定的背景颜色),然后当.exe启动时,在资源管理器下扫描具有您正在寻找的属性的hWnd,将自己注入Explorer.exe进程,并将您的窗口设置为它的子窗口。

第三个选项的变体是不注入Explorer.exe,而是保持您的Z索引和位置(使用SetWindowPos)来跟踪Z索引和您找到的hWnd的位置。

这么多选择......

答案 2 :(得分:0)

实现“小工具”行为的一个解决方案是让您的窗口成为桌面的孩子。这样,即使按Windows + D,您的窗口也始终在桌面上可见。 你可以在这里看到它是如何完成的:Window "on desktop"

答案 3 :(得分:0)

我将其留在此处以供将来参考。

在Windows 10中,使用p / invoke将小工具窗口作为桌面的父项。将与peek,显示桌面和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);

    }