简体   繁体   中英

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?

I have a window that serves as an overlay for the entire screen. Here's the 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"):

在此处输入图片说明

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. 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.

This other question was also about using different blending functions for WPF brushes. 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. 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.

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). Then you can use the RenderTargetBitmap class to convert it to an 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:

<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...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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