Отключить захват экрана в WPF c# для ребенка windows - PullRequest
1 голос
/ 27 мая 2020

Я пытаюсь отключить захват экрана, и он работает с моим главным окном -

[DllImport("user32.dll")]
        public static extern uint SetWindowDisplayAffinity(IntPtr hwnd, uint dwAffinity);

var mainWindowHandle = new WindowInteropHelper(this).Handle;
                const uint WDA_NONE = 0;
                const uint WDA_MONITOR = 1;
                SetWindowDisplayAffinity(mainWindowHandle, WDA_MONITOR);

Но он не работает, когда я открываю всплывающее / дочернее окно. Есть ли способ, которым это могло бы работать и с дочерним windows? Любая помощь будет принята с благодарностью. Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 28 мая 2020

Deepankshee, я не уверен, в чем ваша проблема. У меня это сработало, и я точно выполнил ваши инструкции.

До (БЕЗ события OnLoaded в обоих windows): enter image description here

После (С событием OnLoaded в обоих windows): enter image description here

Вот мой код ...

MainWindow.xaml:

<Window x:Class="CaptureScreenTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:CaptureScreenTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel>
            <TextBlock FontSize="64" Text="What up? I'm a Main Window." HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap" Margin="5"/>
            <Button Content="Open Child" Click="Button_Click" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="15,5" Margin="15"/>
        </StackPanel>
    </Grid>
</Window>

MainWindow.xaml .cs: ​​

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;

namespace CaptureScreenTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        [DllImport("user32.dll")]
        public static extern uint SetWindowDisplayAffinity(IntPtr hwnd, uint dwAffinity);

        public MainWindow()
        {
            InitializeComponent();
            //this.Loaded += MainWindow_Loaded;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            var mainWindowHandle = new WindowInteropHelper(this).Handle;
            const uint WDA_NONE = 0;
            const uint WDA_MONITOR = 1;
            SetWindowDisplayAffinity(mainWindowHandle, WDA_MONITOR);
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var child = new ChildWindow();
            child.Show();
        }
    }
}

ChildWindow.xaml:

<Window x:Class="CaptureScreenTest.ChildWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:CaptureScreenTest"
        mc:Ignorable="d"
        Title="ChildWindow" Height="450" Width="800">
    <Grid>
        <TextBlock FontSize="64" Text="I'm a Child Window." HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap"/>
    </Grid>
</Window>

ChildWindow.xaml.cs:

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;

namespace CaptureScreenTest
{
    /// <summary>
    /// Interaction logic for ChildWindow.xaml
    /// </summary>
    public partial class ChildWindow : Window
    {
        [DllImport("user32.dll")]
        public static extern uint SetWindowDisplayAffinity(IntPtr hwnd, uint dwAffinity);
        public ChildWindow()
        {
            InitializeComponent();
            //this.Loaded += ChildWindow_Loaded;
        }

        private void ChildWindow_Loaded(object sender, RoutedEventArgs e)
        {
            var mainWindowHandle = new WindowInteropHelper(this).Handle;
            const uint WDA_NONE = 0;
            const uint WDA_MONITOR = 1;
            SetWindowDisplayAffinity(mainWindowHandle, WDA_MONITOR);
        }
    }
}
0 голосов
/ 28 мая 2020

После большого анализа нашел решение в моем дочернем окне в файле xaml -

<Window x:Class="Test.Popup"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:AllenClassRoom"
        xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
        mc:Ignorable="d"
        Title="Popup" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" AllowsTransparency="True" WindowStyle="None" Loaded="Window_Loaded">
    <Grid>

AllowsTransparency = "True" это свойство было установлено в значение true. Из-за этого свойства эта функция (SetWindowDisplayAffinity (mainWindowHandle, WDA_MONITOR);) всегда возвращала false. Убрал это свойство, и оно заработало. Надеюсь, это поможет

0 голосов
/ 28 мая 2020

Если вы хотите, чтобы это происходило глобально на всех windows в вашем приложении, лучше заранее определить свой собственный класс окна и поместить его туда. Затем извлеките весь свой windows из ВАШЕГО класса по сравнению с окном по умолчанию ... Что-то вроде

using System;
using System.Windows;
using System.Runtime.InteropServices;
using System.Windows.Interop;


namespace CaptureScreenTest
{
   public class YourBaseWindow : Window
   {
      public YourBaseWindow()
      {  
         Loaded += MyWindowLoaded;
      }

      [DllImport("user32.dll")]
      public static extern uint SetWindowDisplayAffinity(IntPtr hwnd, uint dwAffinity);

      private void MyWindowLoaded(object sender, RoutedEventArgs e)
      {
         var _curWindHandle = new WindowInteropHelper(this).Handle;
         // const uint WDA_NONE = 0;
         const uint WDA_MONITOR = 1;
         SetWindowDisplayAffinity(_curWindHandle, WDA_MONITOR);
      }
   }
}

Затем во всем вашем windows, поскольку "local" ссылается на ваше пространство имен CaptureScreenTest, просто измените все ваши определения окон от ex:

<Window x:Class="CaptureScreenTest.MainWindow"
   … etc...
   xmlns:local="clr-namespace:CaptureScreenTest"

до

<local:YourBaseWindow x:Class="CaptureScreenTest.MainWindow"
   … etc...
   xmlns:local="clr-namespace:CaptureScreenTest"

Тогда вам не нужно возиться, делая это в каждом окне. Вы даже можете параметризовать свое окно, чтобы определить, хотите ли вы его включить или нет. Я сделал аналогичное объявление базового окна для своего приложения WPF, и все формы являются производными от него. У меня есть другие захваченные / постоянные функции в моем основном классе окна, и все это приходит на ходу, и мне никогда не нужно забывать реализовать на другом windows.

Теперь, поскольку ваше будущее объявление окна наследуется от этого , если у них тоже есть вызов события «Loaded», родительский класс ВСЕГДА будет делать это самостоятельно, а производный класс тоже продолжит делать то, что им нужно.

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