lolp1 / Overlay.NET

An easy-to-use overlay library written in C# by Jacob Kemple.
732 stars 87 forks source link

WPF Overlay not able to receive events? #4

Closed Trxplz0 closed 5 years ago

Trxplz0 commented 7 years ago

Hi,

I was trying to render a WPF user control in WPF overlay, it's rendering all controls but they won't be able to accept events like "CLICK" even with TopMost enabled.

This is how I'm setting the content:

wpfOverlay.OverlayWindow.Content = new MyUserControl();

image

lolp1 commented 7 years ago

Have you tried adding the controls directly to the WPF overlay? As in wpfOverlay.Children.Add ...?

Trxplz0 commented 7 years ago

Yes, it didn't work either.

lolp1 commented 7 years ago

My guess is because this is used on the wpf window https://github.com/lolp1/Overlay.NET/blob/master/src/Overlay.NET/Common/WindowExtensions.cs#L13 to allow graphics drawn on the canvas to be click-through. Reason described here https://github.com/lolp1/Overlay.NET/blob/master/src/Overlay.NET/Wpf/OverlayWindow.xaml.cs#L46

You can try a couple things.

  1. Track the mouse click events how ever way you like, if the event is raised with the coordinates being within your button controls bounds for example, then you know it was clicked and you can handle as normal.

  2. Mess with not using the MakeTransparent thing, but I've had little to no luck with that. I do it the first way myself.

Trxplz0 commented 7 years ago

I was looking at the code and already tried a lot of ways, I didn't figure it out yet, but disabling the MakeTransparent makes the overlay to flickering until I close the Overlay.NET. I notice during the flickering it focus the hooked application and then switches the focus to Overlay.NET console window in a loop and still until I close.

Maybe, in the end, i will have to choose option 1.

It changes something if there's no need to draw shapes? Just draw a WPF user control able to receive events?

Thanks for help.

lolp1 commented 7 years ago

@Trxplz0

The issue appears to be something like this (though I am currently trying to figure out what to do about it): If the overlay wants to render graphics, in order to prevent disruption of the window it is linked to, all things will should, imo, be click through.

Otherwise, you end up with some one drawing graphics, for example, drawing some text to the screen of the last 3 messages from an irc feed. If the transparent thing is disabled, suddenly this click-through text is competing with clicking with the overlay and the actual window it is attached to.

I think the best option for me here is to write a basic menu abstraction that tracks mouse position on click events and checks if they are within the bounds of the menu item. Then it can follow up with the specified handler.

You can of course do that your self for now if you like. One option to do that I have not tried, is to use the default mouse events in the WPF window to do this.

The second, the way I am doing it currently, is to use the mouse hook in my Process.NET lib (it is on Nuget as well - search for Process.NET) found here:

https://github.com/lolp1/Process.NET/blob/master/src/Process.NET/Windows/Mouse/MouseHook.cs

If you choose to use my mouse hook, make sure you check out msdns page on SetWindowHookEx for possible issues.

lolp1 commented 7 years ago

Small update, my free time is back again for at least a few weeks or a lot longer possibly (done helping my GF with her business website/app now) also family from Christmas/new years is back home. Will look in go this issue further today and let you know what I find.

Trxplz0 commented 7 years ago

I'm looking into either and let you know what I find.

Thanks for helping me!

lolp1 commented 7 years ago

I have found a way to sort of work around this. What you do is remove this line: https://github.com/lolp1/Overlay.NET/blob/master/src/Overlay.NET/Wpf/OverlayWindow.xaml.cs#L50

Then here is where the work around comes in. The issue is once you remove the transparent flag, when you click the shape, it will gain focus no matter what you do. The way to work around this is to set the window it is overlaying to the active window in the event handler. Here is an example.

                var rectangle = new Rectangle {
                    RadiusX = 2,
                    RadiusY = 2,
                    Width = 50,
                    Height = 100,
                    Margin = new Thickness(400, 400, 0, 0),
                    Stroke = new SolidColorBrush(Color.FromRgb(255, 0, 0)),
                    Fill = new SolidColorBrush(Color.FromArgb(100, 255, 255, 255)),
                };

                rectangle.MouseLeftButtonDown += Drawable_MouseLeftButtonDown;
                Overlay.Add(rectangle);

        // this is the 'Target window' called in the init mehtod from WPF here:
        // var wpfOverlay = (WpfOverlayDemoExample) _overlay;
        // wpfOverlay.Initialize(_processSharp.WindowFactory.MainWindow);
        // just save a reference to the instance.
        private IWindow _window; 
        private void Drawable_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {   
            _window.Activate();
            Log.WriteLine($"Left buttton was clicked? {e.LeftButton == MouseButtonState.Pressed}");
        }

Now for the most part it works fine, the only annoyance left is the cursor will change while the mouse is over the element. This looks unnatural. The way to deal with it is to manually set the controls cursor to the same cursor the window the overlay is targeting uses. For example you could set the rectangles cursor property:

rectangle.Cursor = new Cursor(@"C:\..\cursor.ani (or .cur)") ; 
lolp1 commented 7 years ago

I re-opened this because I think there is another way a friend told me about. I am going to try hooking WndProc and ignoring WM_FOCUS messages from the window. This way we can enable events with out having to re-focus the window.

lolp1 commented 5 years ago

Fixing this soon.

Trxplz0 commented 5 years ago

Nice to hear, thank you!

lolp1 commented 5 years ago

@Trxplz0 Still intend to fix.. sorry for delay.

xcxooxl commented 5 years ago

@lolp1 Waiting for this too.. This library is awesome !