Deepankshee Jain
Deepankshee Jain

Reputation: 131

Disable capturing screen in WPF c# for child windows

I am trying to disable capturing screen and It is working with my main window -

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

But it is not working when I open a popup/child window. Is there any way it could work with child windows as well? Any help would be appreciated Thanks in advance.

Upvotes: 2

Views: 1325

Answers (3)

Deepankshee Jain
Deepankshee Jain

Reputation: 131

After a lot of analysis, found the solution in my child window in xaml file -

<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" this property was set to true. Because of this property this function (SetWindowDisplayAffinity(mainWindowHandle, WDA_MONITOR);) was always returning false. Removed this property and it started working. Hope this helps

Upvotes: 1

DRapp
DRapp

Reputation: 48139

If you want this to happen globally on all windows in your application, you would be best to pre-define your own custom window class and put it in there. Then derive all your windows from YOUR class vs the default window... Something like

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

Then, in all your windows, since the "local" references your CaptureScreenTest namespace, just change all your window definitions from ex:

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

to

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

Then you don't have to mess around with doing this on every window. You could even parameterize your window to identify if you want it enabled or not. I have done similar baseline window declaration for my WPF app and all forms derive from it. I have other captured / constant functionality in my core window class and it all comes along for the ride and I never have to forget to implement on other windows.

Now, since your future window declaration inherit from this, if they too have a "Loaded" event call, the parent class will STILL do it's own and the derived will continue to do what they need too.

Upvotes: 0

Tam Bui
Tam Bui

Reputation: 3048

Deepankshee, I'm not sure what your issue is. It worked for me, and I followed your instructions exactly.

Before (WITHOUT OnLoaded event in both windows): enter image description here

After (WITH OnLoaded event in both windows): enter image description here

Here's my code...

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

Upvotes: 1

Related Questions