Results 1 to 2 of 2

Thread: [WPF] Draw a hole in a semi-transparant canvas

  1. #1
    PowerPoster
    Join Date
    Apr 07
    Location
    The Netherlands
    Posts
    5,070

    [WPF] Draw a hole in a semi-transparant canvas

    Hi,

    I am creating a small application for my own use which overlays a semi-transparant black window on top of my whole screen. I can then draw a 'selection rectangle' on top of that window, and when I release the mouse, a screenshot is made from the region underneath the rectangle and immediately uploaded to my webserver and the link is copied to my clipboard.

    Now instead of just having a white line that defines the selection I'd like to actually 'cut a hole' through the canvas, so that the screen is (semi-transparent) black except for my selection, which should be completely transparant and show the desktop underneath.

    How can I achieve this?


    At the moment I merely have a Canvas that handles some mouse properties:
    csharp Code:
    1. public partial class MainWindow : Window
    2.     {
    3.         private Rectangle rectangle;
    4.         private Point clickLocation;
    5.  
    6.         public MainWindow()
    7.         {
    8.             InitializeComponent();
    9.         }
    10.  
    11.         private void Window_KeyUp(object sender, KeyEventArgs e)
    12.         {
    13.             if (e.Key == Key.Escape)
    14.             {
    15.                 this.Close();
    16.             }
    17.         }
    18.  
    19.         private Rectangle CreateRectangle()
    20.         {
    21.             var rect = new Rectangle();
    22.             rect.Stroke = Brushes.White;
    23.             rect.StrokeThickness = 2;
    24.             return rect;
    25.         }
    26.  
    27.         private void canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    28.         {
    29.             rectangle = this.CreateRectangle();
    30.  
    31.             clickLocation = e.GetPosition(canvas);
    32.             Canvas.SetLeft(rectangle, clickLocation.X);
    33.             Canvas.SetTop(rectangle, clickLocation.Y);
    34.             rectangle.Width = 0;
    35.             rectangle.Height = 0;
    36.  
    37.             canvas.Children.Add(rectangle);
    38.         }
    39.  
    40.         private void canvas_MouseMove(object sender, MouseEventArgs e)
    41.         {
    42.             if (rectangle == null) return;
    43.  
    44.             var location = e.GetPosition(canvas);
    45.             var width = location.X - clickLocation.X;
    46.             var height = location.Y - clickLocation.Y;
    47.  
    48.             if (width < 0)
    49.             {
    50.                 Canvas.SetLeft(rectangle, location.X);
    51.                 width = -width;
    52.             }
    53.             if (height < 0)
    54.             {
    55.                 Canvas.SetTop(rectangle, location.Y);
    56.                 height = -height;
    57.             }
    58.  
    59.             rectangle.Width = width;
    60.             rectangle.Height = height;
    61.         }
    62.  
    63.         private void canvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    64.         {
    65.             var rect = new Rect();
    66.             rect.X = Canvas.GetLeft(rectangle);
    67.             rect.Y = Canvas.GetTop(rectangle);
    68.             rect.Width = rectangle.Width;
    69.             rect.Height = rectangle.Height;
    70.  
    71.             this.HandleScreenGrab(rect);
    72.  
    73.             canvas.Children.Clear();
    74.             rectangle = null;
    75.         }
    76.  
    77.         private void HandleScreenGrab(Rect region)
    78.         {
    79.             //...
    80.         }
    81.     }
    I have read in the past about being able to 'cut' geometries by combining them in an exclude combination, or something, but I cannot figure it out... This seems to be close:
    http://stackoverflow.com/questions/7...background-wpf
    But I cannot figure out how to apply it in my case. I've tried creating a RectangleGeometry from the canvas, as well as from the 'rectangle' (which is the selection) and combining them, but the results varied from nothing at all (no change) to a completely transparant window everywhere. Basically everthing except what I want: a rectangular 'hole' (completely transparent) through an otherwise semi-transparent canvas.


    Thanks!

  2. #2
    Frenzied Member boops boops's Avatar
    Join Date
    Nov 08
    Location
    Holland/France
    Posts
    1,980

    Re: [WPF] Draw a hole in a semi-transparant canvas

    Hi Nick,

    I'm a real beginner in WPF but I thought it would be a good exercise to try solving this. I managed to punch a transparent rectangular hole in an inherited canvas like this (please excuse the vb.net):

    Code:
    	Protected Overrides Sub OnRender(dc As System.Windows.Media.DrawingContext)
    		Dim bounds As New RectangleGeometry(New Rect(0, 0, Me.Width, Me.Height))
    		Dim hole As New RectangleGeometry(New Rect(30, 30, Me.Width - 60, Me.Height - 60))
    		Dim combined As Geometry = Geometry.Combine(bounds, hole, GeometryCombineMode.Exclude, Nothing)
    		Me.Clip = combined
    		MyBase.OnRender(dc)
    	End Sub
    I hope it helps.

    BB

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •