4

I want to send a mouse click to the application behind a control. I have a Topmost transparent window and some controls in it. I would like to be able to send click through some of that controls.

I have already tried setting the property IsHitTestVisible="False" to the control, but it doesn´t work. It doesn´t send click through the control to desktop for example.

I´ve also tried the solution proposed in this question: How to create a semi transparent window in WPF that allows mouse events to pass through

And it works, but I would like to make transparent some controls, not the window.

How could I apply the solution to that question to a single control, for example an ellipse?

The solution:

public static class WindowsServices
{
  const int WS_EX_TRANSPARENT = 0x00000020;
  const int GWL_EXSTYLE = (-20);

  [DllImport("user32.dll")]
  static extern int GetWindowLong(IntPtr hwnd, int index);

  [DllImport("user32.dll")]
  static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle);

  public static void SetWindowExTransparent(IntPtr hwnd)
  {
    var extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
    SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_TRANSPARENT);
  }
}

protected override void OnSourceInitialized(EventArgs e)
{
  base.OnSourceInitialized(e);
  var hwnd = new WindowInteropHelper(this).Handle;
  WindowsServices.SetWindowExTransparent(hwnd);
}
Community
  • 1
  • 1
kevin
  • 988
  • 12
  • 23
  • What you should do is capture all mouse events as normal on the window. Get your window position on the screen and add the mouse click position to that. After you have an absolute position on the screen where the mouse was clicked you need to send a global mouse down event via P/Invoke. – Edza Jun 13 '15 at 19:43
  • I have an ellipse that behaves as a cursor controlled by the Leap Motion controller. Actually I can send clicks to the left corner of the ellipse (near the border, but outside the ellipse), but what I want is to send click to the center of the ellipse. When I do this, the ellipse recibes the click and not whatever is behind the ellipse. For example I can´t use the ellipse to click on a folder unless I put the ellipse click point near the border of the ellipse, but outside. To send click I´m actually using mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo). – kevin Jun 13 '15 at 20:41
  • I´ve also tried with sendInput and with postmessage, but it didn´t work, because the ellipse is Topmost and it was allways receiving the mouse event. – kevin Jun 13 '15 at 20:45

1 Answers1

0

Use the routed event un this way . In control A write the click event:

 #region - Routed events -
    /// <summary>
    /// Bubble event
    /// </summary>
    public static readonly RoutedEvent ClickEvent =
        EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof([Class name]));
    public event RoutedEventHandler Click
    {
        add { AddHandler(ClickEvent, value); }
        remove { RemoveHandler(ClickEvent, value); }
    }

    /// <summary>
    /// Fired the click event
    /// </summary>
    /// <param name="sender">this control</param>
    /// <param name="e">routed args</param>
    private void usercontrol_Clicked(object sender, RoutedEventArgs e)
    {
        RoutedEventArgs args = new RoutedEventArgs(LastUnitCycleTime.ClickEvent);
        RaiseEvent(args);
    }
    #endregion - Routed events -

then you can use it in all other control just to use the following way:

in each other control constructor insert this line: in this case usercontrol2

usercontrol_Clicked += usercontrol2Name_Clicked;

then this is the method in control2 was fired when you click on control1

  private void usercontrol2Name_Clicked(object sender, RoutedEventArgs e)
    {          
        //effort here what you want....
    }
luka
  • 605
  • 8
  • 15