除了 c# 中选定的控件之外,使桌面屏幕变灰

发布于 2024-11-03 19:39:32 字数 122 浏览 7 评论 0原文

我想选择一个要单击的 UI 控件,并将桌面屏幕的其余部分半透明地变灰。我正在考虑用位图绘制整个屏幕,但这是一个非常缓慢的过程。我想有人知道 WPF 中如何做到这一点。我没有 WPF 经验。我想在 Windows 7 上执行此操作。

I want to select a UI control to be clicked and gray out the rest of the desktop screen semi-transparently. I was thinking bitmap painting the whole screen but it is very slow process. I guess someone out there know in WPF how to do that. I don't have experiance in WPF. I wanted to do this on Windows 7.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

心不设防 2024-11-10 19:39:32

基本上,您想要显示一个顶级全屏透明窗口,该窗口不可聚焦且不响应输入。然后,您可以使用此窗口手动绘制叠加层。我认为最简单的方法是覆盖窗口上的 OnRender 并绘制一个填充整个窗口的矩形,但使用剪贴蒙版(通过 DrawingContext.PushClip)来排除您想要不覆盖的区域。

编辑:

这是一个示例:

窗口可能应该这样设置:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        AllowsTransparency="True"
        WindowStyle="None"
        WindowState="Maximized"
        Topmost="False"
        Background="{x:Null}"
        IsHitTestVisible="False">
</Window>

WindowStyleWindowState 设置将导致窗口最大化并与任务栏重叠。
Topmost 设置为 true 将导致窗口位于所有其他窗口之上,而 IsHitTestVisible 将导致鼠标单击“落入”。

警告:如果您设置此选项,您将被困在最顶层的窗口中,您无法关闭该窗口,因为它不侦听键盘命令。 您需要在代码中的某个位置手动关闭窗口。您可能想创建一个全局鼠标钩子来监听鼠标松开,并创建一个键盘钩子来监听 ESC 或其他内容。

为了避免人们受到伤害,我在上面的示例中将 TopMost 设置为 False。仅当您已经弄清楚如何/何时在代码中关闭窗口时,才将其更改为 true。

Background 设置为 null,以便您可以在后面的代码中使用自定义绘图。

后面的代码与此类似:

public MainWindow()
{
    InitializeComponent();
}

protected override void OnRender(DrawingContext drawingContext)
{
    base.OnRender(drawingContext);
    var screenGeometry = new RectangleGeometry(new Rect(0, 0, ActualWidth, ActualHeight));
    var excludeRectangle = new RectangleGeometry(new Rect(200, 200, 150, 150));
    drawingContext.PushClip(CombinedGeometry.Combine(screenGeometry,excludeRectangle, GeometryCombineMode.Exclude,null));
    drawingContext.PushOpacity(.8);
    drawingContext.DrawRectangle(Brushes.Black, null, new Rect(0, 0, ActualWidth, ActualHeight));
    drawingContext.Pop();
    drawingContext.Pop();
}

您可以在其中为排除矩形使用正确的位置和大小。

如果运行此代码,您将看到屏幕变灰,除了左上角有一个小矩形。

Basically you want to show a top-level full screen transparent window which is not focusable and doesn't respond to input. You can then use this window to draw the overlay manually. I think the easiest way would be to override OnRender on the Window and to draw a rectangle that fills the whole window but uses a clipping mask (via drawingContext.PushClip) to exclude the area you want to leave uncovered.

EDIT:

Here is an example:

The Window should probably be set up like this:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        AllowsTransparency="True"
        WindowStyle="None"
        WindowState="Maximized"
        Topmost="False"
        Background="{x:Null}"
        IsHitTestVisible="False">
</Window>

The WindowStyle and WindowStatesettings will cause the window to be maximized and overlapping the task bar.
Topmost set to true will cause the window to be on top of all other windows and IsHitTestVisible will cause the mouse clicks to 'fall through'.

Warning: If you set this you will be stuck with a topmost window that you can't close since it doesn't listen to keyboard commands. You will need to manually close the window somewhere in your code. Likely you want to create a global mouse hook to listen to mouse up and a keyboard hook to listen to ESC or something.

To save people from themselves I have set TopMost to False in the above example. Only change it to true if you have figured out how/when to close the window in code somewhere.

The Background is set to null so that you can use your custom drawing in code behind.

the code behind similar to this:

public MainWindow()
{
    InitializeComponent();
}

protected override void OnRender(DrawingContext drawingContext)
{
    base.OnRender(drawingContext);
    var screenGeometry = new RectangleGeometry(new Rect(0, 0, ActualWidth, ActualHeight));
    var excludeRectangle = new RectangleGeometry(new Rect(200, 200, 150, 150));
    drawingContext.PushClip(CombinedGeometry.Combine(screenGeometry,excludeRectangle, GeometryCombineMode.Exclude,null));
    drawingContext.PushOpacity(.8);
    drawingContext.DrawRectangle(Brushes.Black, null, new Rect(0, 0, ActualWidth, ActualHeight));
    drawingContext.Pop();
    drawingContext.Pop();
}

where you would use the proper location and size for the excludeRectangle.

If you run this code you will see the screen grayed out except for a little rectangle in the top left.

漫雪独思 2024-11-10 19:39:32

如果你想模糊MainWindow并专注于新的Popup窗口,你可以检查这个:

System.Windows.Media.Effects.BlurEffect objBlur = new System.Windows.Media.Effects.BlurEffect();
((MainWindow)App.Current.MainWindow).Effect = objBlur;

mainFrame.Navigate(new PopUp_page1());

你也可以使用Window而不是Popup窗口。

要消除该效果:

((MainWindow)App.Current.MainWindow).Effect = null;

If you want to blur the MainWindow and focus on new Popup window, you can check this:

System.Windows.Media.Effects.BlurEffect objBlur = new System.Windows.Media.Effects.BlurEffect();
((MainWindow)App.Current.MainWindow).Effect = objBlur;

mainFrame.Navigate(new PopUp_page1());

You can also use Window instead of Popup window.

To remove the effect:

((MainWindow)App.Current.MainWindow).Effect = null;
·深蓝 2024-11-10 19:39:32

我用了这段代码。但看起来它没有使用OnRender。它只显示白色窗口。

namespace GrayOutTEST
{
   class MainWindow1 : Window
   {
       private Window window;
       public MainWindow1() { }
       public void CreateWindow()
    {
        window = new Window();
        window.Title = "WIndow Title";
        window.Height = Screen.PrimaryScreen.Bounds.Height;
        window.Width = Screen.PrimaryScreen.Bounds.Width;
        window.Topmost = false;
        window.IsHitTestVisible = false;
        window.AllowsTransparency = true;
        window.WindowStyle = WindowStyle.None;
        window.WindowState = WindowState.Maximized;
      //  window.Background = null;
        window.Show();
    }
    public void CloseWindow()
    {
        window.Close();
    }
    protected override void OnRender(DrawingContext drawingContext)
    {
        base.OnRender(drawingContext);
        var screenGeometry = new RectangleGeometry(new Rect(0, 0, ActualWidth, ActualHeight));
        var excludeRectangle = new RectangleGeometry(new Rect(200, 200, 150, 150));
        drawingContext.PushClip(CombinedGeometry.Combine(screenGeometry, excludeRectangle, GeometryCombineMode.Exclude, null));
        drawingContext.PushOpacity(.8);
        drawingContext.DrawRectangle(System.Windows.Media.Brushes.Black, null, new Rect(0, 0, ActualWidth, ActualHeight));
        drawingContext.Pop(); drawingContext.Pop();
    } 
    [STAThread]
    static void Main(string[] args)
    {
        MainWindow1 w = new MainWindow1();
        w.CreateWindow();
        Console.Read();
    }

}
}

I used this code. But it looks like it is not using the OnRender. It just shows White Window.

namespace GrayOutTEST
{
   class MainWindow1 : Window
   {
       private Window window;
       public MainWindow1() { }
       public void CreateWindow()
    {
        window = new Window();
        window.Title = "WIndow Title";
        window.Height = Screen.PrimaryScreen.Bounds.Height;
        window.Width = Screen.PrimaryScreen.Bounds.Width;
        window.Topmost = false;
        window.IsHitTestVisible = false;
        window.AllowsTransparency = true;
        window.WindowStyle = WindowStyle.None;
        window.WindowState = WindowState.Maximized;
      //  window.Background = null;
        window.Show();
    }
    public void CloseWindow()
    {
        window.Close();
    }
    protected override void OnRender(DrawingContext drawingContext)
    {
        base.OnRender(drawingContext);
        var screenGeometry = new RectangleGeometry(new Rect(0, 0, ActualWidth, ActualHeight));
        var excludeRectangle = new RectangleGeometry(new Rect(200, 200, 150, 150));
        drawingContext.PushClip(CombinedGeometry.Combine(screenGeometry, excludeRectangle, GeometryCombineMode.Exclude, null));
        drawingContext.PushOpacity(.8);
        drawingContext.DrawRectangle(System.Windows.Media.Brushes.Black, null, new Rect(0, 0, ActualWidth, ActualHeight));
        drawingContext.Pop(); drawingContext.Pop();
    } 
    [STAThread]
    static void Main(string[] args)
    {
        MainWindow1 w = new MainWindow1();
        w.CreateWindow();
        Console.Read();
    }

}
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文