簡體   English   中英

WPF 中的 Windows 小工具 - 在“顯示桌面”激活時顯示

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

我正在嘗試使用 WPF 創建一個“小工具”之類的應用程序。 目標是獲得與普通 Windows 7 小工具相同的行為:

  • 沒有任務欄條目
  • 當你 alt+tab 窗口時不顯示
  • 不總是在最前面,應用程序可以在最前面
  • 執行“Aero Peek”時可見
  • 使用“顯示桌面”/Windows+D 時可見

我已經能夠完成前四個目標,但一直無法找到解決第五個問題的方法。 我最接近的是使用WPF 中如何執行 AppBar 停靠(到屏幕邊緣,如 WinAmp)中的實用程序類 ,但這會將應用程序變成“工具欄”,從而將應用程序從放置我的小工具 GUI 的屏幕部分排除。

我可以看到之前在 Stackoverflow 上也有人問過類似的問題,但是在找到解決方案之前這些問題就消失了。 無論如何發布,希望現在有人有知識來解決這個問題=)

嘗試將 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# 中為窗口做了這個:

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

您可以通過創建 XBAP 使用 WPF 實現實際的 Windows 小工具。 只需添加一個 gadget.xml 文件和一個僅包含加載 XBAP 的 IFRAME 的 .html 文件。 這樣您的 WPF 應用程序實際上將成為一個小工具,並會自動遵循所有規則。

另一種選擇是使用Windows Sidebar Styler 這需要與您的軟件一起安裝額外的軟件,但也允許您在沒有代碼簽名證書、用戶授權等的情況下執行在 XBAP 沙箱中無法執行的操作。

第三種選擇是創建一個使用 HTML 中可識別的東西(例如特定的背景顏色)的小工具,然后當您的 .exe 啟動時,在資源管理器下掃描具有您正在尋找的屬性的 hWnd,將自己注入Explorer.exe 進程,並將您的窗口設置為它的子窗口。

第三個選項的變體是不注入 Explorer.exe 而是維護您的 Z 索引和位置(使用 SetWindowPos)來跟蹤 Z 索引和您找到的 hWnd 的位置。

這么多選擇...

我將把它留在這里以備將來參考。

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

    }

實現類似“小工具”行為的一種解決方案是使您的窗口成為桌面的子窗口。 這樣,即使您按 Windows+D,您的窗口也始終在桌面上可見。 你可以在這里看到它是如何完成的: Window "on desktop"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM