15

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

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

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

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

4

4 回答 4

1

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

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

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

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

这么多选择...

于 2010-03-11T20:50:32.627 回答
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 获取桌面窗口的句柄
  • 使用 ap/invoke 调用为 WndProc 设置回调
  • 处理 WM_ACTIVATE 或适当的 Windows 消息并将您的不透明度设置回 1
于 2010-03-11T19:59:07.410 回答
1

我将把它留在这里以供将来参考。

在 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);

    }
于 2020-08-16T08:44:08.407 回答
0

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

于 2011-04-23T16:53:48.470 回答