简体   繁体   English

将WPF窗口与桌面混合

[英]Blending a WPF Window with the desktop

Is it possible (and how) to adjust the blending mode used to display a WPF form on the desktop? 是否可以(以及如何)调整用于在桌面上显示WPF表单的混合模式?

I have a window that serves as an overlay for the entire screen. 我有一个窗口,可以覆盖整个屏幕。 Here's the XAML: 这是XAML:

<Window x:Class="RedGreenBarsWPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Red/Green Overlay" Topmost="True" Height="300" Width="525" AllowsTransparency="True" WindowStyle="None" Background="Transparent" WindowStartupLocation="Manual" IsHitTestVisible="False">
    <Canvas Name="canvas" />
</Window>

It can't be clicked, and it gets resized and moved to cover the entire screen when the Window loads. 不能单击它,并且在加载窗口时会对其进行调整大小并移动以覆盖整个屏幕。 I then draw some shapes on the canvas like this: 然后,我在画布上绘制一些形状,如下所示:

System.Windows.Media.Brush red = new SolidColorBrush(System.Windows.Media.Color.FromArgb(200, 255, 0, 0));

System.Windows.Size s = new System.Windows.Size(System.Windows.SystemParameters.PrimaryScreenWidth, System.Windows.SystemParameters.PrimaryScreenHeight);

int lines = 20;
for (double i = 0; i < s.Width; i += s.Width / lines)
{
    System.Windows.Shapes.Rectangle rect = new System.Windows.Shapes.Rectangle
    {
        Width = s.Width / lines,
        Height = s.Height
    };

    rect.Fill = red;

    Canvas.SetTop(rect, 0);
    Canvas.SetLeft(rect, i * 2);
    canvas.Children.Add(rect);
}

This does exactly what it should, but not what I want. 这确实是应该做的,但不是我想要的。 Here's a visualization done in Photoshop (mine looks like "Normal"): 这是在Photoshop中完成的可视化效果(我的图像看起来像“正常”):

在此处输入图片说明

I need to figure out a way to make it look like the red box on the right, where the text isn't lightened by the overlaying colour. 我需要找出一种使它看起来像右边的红色框的方法,其中文本不会被覆盖的颜色淡化。 I've searched high and low, and although there are libraries out there that can accomplish this with elements within the Window, I need the blend mode to extend over the entire desktop. 我已经搜索了很多东西,尽管那里有一些库可以用Window中的元素来完成此任务,但我需要混合模式才能扩展到整个桌面。 How can this be done? 如何才能做到这一点?

You need to use a different blending function. 您需要使用其他混合功能。 So far I believe you have no easy solution ; 到目前为止,我相信您没有简单的解决方案; this has already been requested but is not yet supported by WPF. WPF已请求此功能,但尚不支持。

This other question was also about using different blending functions for WPF brushes. 这个另一个问题也是关于为WPF笔刷使用不同的混合功能。 It also contains links to a pretty nice (but long) tutorial about how implementing custom blending (it's a whole blending library actually). 它还包含指向一个不错的(但很长)教程的链接,该教程关于如何实现自定义混合(实际上是一个完整的混合库)。

These pages contain zips with the source code on almost each page. 这些页面包含zip,几乎每个页面上都有源代码。 You need the following to build them: (quoting) .NET 3.5 SP1, DirectX SDK, and the Shader Effects BuildTask and Templates from the WPF Futures stuff on CodePlex. 您需要以下内容来构建它们:(引用).NET 3.5 SP1,DirectX SDK,以及CodePlex上WPF Futures中的Shader Effects BuildTask和模板。

I'm copying the links here: 我在这里复制链接:

EDIT: To capture the desktop image, you can try to use a simple FrameworkElement , such as a Rectangle , with a transparent background ( Transparent is a brush). 编辑:要捕获桌面图像,您可以尝试使用具有透明背景的简单FrameworkElement (例如Rectangle (“ Transparent是画笔)。 Then you can use the RenderTargetBitmap class to convert it to an ImageBrush. 然后,您可以使用RenderTargetBitmap类将其转换为ImageBrush。 Here is a code snippet that should help you to get started: 这是一个代码片段,可以帮助您入门:

public Brush RectangleToBrush(Rectangle rect)
{
    int w = (int)rect.ActualWidth;
    int h = (int)rect.ActualHeight;
    var rtb = new RenderTargetBitmap(w, h, 96d, 96d, PixelFormats.Default);
    rtb.Render(rect);

    ImageBrush brush = new ImageBrush(BitmapFrame.Create(rtb));

    return brush;
}

You can probably put this rectangle in your .xaml file, using a Grid, to make it cover the whole window: 您可以使用Grid将此矩形放在.xaml文件中,以使其覆盖整个窗口:

<Window ...>
    <Grid>
        <Rectangle x:Name="DesktopCaptureRectangle"/>
        <Grid>
            <!-- Your controls here -->
        </Grid>
    </Grid>
</Window>

Note: I'm not sure this solution will be good performance-wise... 注意:我不确定此解决方案在性能方面是否会很好...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM