Временное визуальное приложение wpf - для Visual Studio Ctrl для всплывающих подсказок

Контекст: я работаю над приложением WPF, где пользователю часто приходится записывать биты данных вручную из других программ. Не имея двух мониторов, это связано с большим количеством Alt-tabbing.

Я понял, что было бы неплохо иметь те же функциональные возможности, что и в Visual Studio для всплывающих подсказок, - где вы можете нажать Ctrl, чтобы сделать их слегка прозрачными.

"Проблема" у меня в том, что вы можете (полезно) играть с прозрачностью, если ваше окно разрешает транспарант, что, в свою очередь, возможно только в том случае, если WindowStyle = None. Я действительно не хочу успеть во все сложности, связанные с необходимостью воссоздать заголовок и т.д. В моем приложении.

Есть ли достойная альтернатива?

Ответ 1

С небольшим количеством Win32 Interop вы можете получить HWND своего окна и использовать CreateRgn и определить область отсечения для вашего окна, это сделает любую часть окна "прозрачной" по мере необходимости. Он также изменит тестирование на удар, таким образом, окно будет не только "видеть", но также "щелкнуть".

Вот несколько бит из одного из моих проектов для домашних животных, это устраняет клиентскую область окна. Некоторые из кода здесь могут быть специфическими для WPF, но, в конечном счете, API-интерфейсы Win32, представленные здесь, присутствуют с начала 90-х годов.

    [DllImport("gdi32.dll")]
    internal static extern IntPtr CreateRectRgnIndirect([In] ref Mubox.Win32.Windows.RECT lprc);

    [DllImport("gdi32.dll")]
    internal static extern IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);

    [DllImport("user32.dll")]
    internal static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw);

    [DllImport("gdi32.dll")]
    internal static extern int CombineRgn(IntPtr hrgnDest, IntPtr hrgnSrc1, IntPtr hrgnSrc2, CombineRgnStyles fnCombineMode);

    public enum CombineRgnStyles : int
    {
        RGN_AND = 1,
        RGN_OR = 2,
        RGN_XOR = 3,
        RGN_DIFF = 4,
        RGN_COPY = 5,
        RGN_MIN = RGN_AND,
        RGN_MAX = RGN_COPY
    }

    #endregion

                    IntPtr windowRegion = Control.Windows.CreateRectRgn(0, 0, parkingWindowRect.Width, parkingWindowRect.Height);
                    Mubox.Win32.Windows.RECT clipRect = new Mubox.Win32.Windows.RECT();

                        Mubox.Win32.Windows.GetClientRect(this.Handle, out clipRect);
                        clipRect.Left = (parkingWindowRect.Width - clipRect.Width) / 2;
                        clipRect.Right += clipRect.Left;
                        clipRect.Top = (parkingWindowRect.Height - clipRect.Height) - clipRect.Left;
                        clipRect.Bottom = parkingWindowRect.Height - clipRect.Left;


                    IntPtr clipRegion = Control.Windows.CreateRectRgnIndirect(ref clipRect);
                    Control.Windows.CombineRgn(windowRegion, windowRegion, clipRegion, Windows.CombineRgnStyles.RGN_XOR);
                    Control.Windows.DeleteObject(clipRegion);
                    Control.Windows.SetWindowRgn(this.Handle, windowRegion, true);