Как я могу прикрепить окно к рабочему столу в WPF? - PullRequest
0 голосов
/ 18 марта 2020

У меня есть приложение, похожее на док (несколько изображений в сетке, например виджет), которое должно оставаться поверх рабочего стола, только когда рабочий стол является текущим окном переднего плана.

В настоящее время я использую неуправляемый код, который я собрал здесь и там, чтобы получить имя окна переднего плана при изменении окна переднего плана. Я использую Topmost, чтобы вывести окно моего приложения на передний план, когда ActiveWindowTitle() == null, потому что при переключении на рабочий стол окно переднего плана становится нулевым. Проблема в том, что другие приложения время от времени возвращают также ноль windows.

Как я могу убедиться, что текущее окно переднего плана - это Desktop, а не какая-то другая программа?

    delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
    private static WinEventDelegate stickyDelegate = null;

    [DllImport("user32.dll")]
    static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);

    private const uint WINEVENT_OUTOFCONTEXT = 0;
    private const uint EVENT_SYSTEM_FOREGROUND = 3;

    [DllImport("user32.dll")]
    static extern IntPtr GetForegroundWindow();

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);

    public static void ActivateStickToDesktop()
    {
        stickyDelegate = new WinEventDelegate(WinEventProc);
        IntPtr m_hhook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, stickyDelegate, 0, 0, WINEVENT_OUTOFCONTEXT);
    }

    private static string GetActiveWindowTitle()
    {
        const int nChars = 256;
        IntPtr handle = IntPtr.Zero;
        StringBuilder Buff = new StringBuilder(nChars);
        handle = GetForegroundWindow();

        if (GetWindowText(handle, Buff, nChars) > 0)
        {
            return Buff.ToString();
        }
        return null;
    }

    public static void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
    {
        activeWindowName = GetActiveWindowTitle();
        Console.WriteLine("Current active window name: " + activeWindowName);

        if(string.IsNullOrEmpty(activeWindowName))
        {
            AppWindow.Topmost = true;
        } else
        {
            AppWindow.Topmost = false;
            SendToBottom(AppWindow);
        }

        Console.WriteLine("Is Topmost: " + AppWindow.Topmost);
    }

1 Ответ

0 голосов
/ 18 марта 2020

Чтобы окно всегда оставалось сверху, внесите изменения, которые я предлагаю. добавьте Topmost="True" в Mainwindow.xaml, также добавьте Deactivated="Window_Deactivated" в mainwindow.xaml. внутри Mainwindow.xaml.cs добавить

private void Window_Deactivated(object sender, EventArgs e)
    {
        Window window = (Window)sender;
        window.Topmost = true;
    }

, это будет работать для большинства случаев

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...