MicrosoftEdge / WebView2Feedback

Feedback and discussions about Microsoft Edge WebView2
https://aka.ms/webview2
454 stars 55 forks source link

MouseHover and MouseMove events do not work with WebView2 #425

Open carlossanlop opened 4 years ago

carlossanlop commented 4 years ago

Description

The MouseHover and MouseMove events do not work with WebView2 in WinForms.

Version SDK: 0.9.579-prerelease Runtime: Canary 87.0.635.0 64-bits Framework: WinForms with dotnet 5.0.100-rc.1.20452.10 OS: Win10 Version 2004 Build 19041.450 64-bits

Repro Steps

Add a MouseHover OR MouseMove event handler (not together) to the WebView2 instance in the *Form.Designer.cs file:

private void InitializeComponent()
{
    this._webBrowser = new Microsoft.Web.WebView2.WinForms.WebView2();
    this.SuspendLayout();
    // 
    // _webBrowser
    // 
    this._webBrowser.Name = "_webBrowser";
    ... // Bunch of other properties set
    this._webBrowser.MouseHover += new System.EventHandler(this.WebBrowser_MouseHover);
    // OR
    this._webBrowser.MouseMove += new System.Windows.Forms.MouseEventHandler(this.WebBrowser_MouseMove);
    // But do not test them together
    ...

The event methods are defined like this in the *Form.cs file:

private void WebBrowser_MouseHover(object sender, EventArgs e)
{
    Close();
}
private void WebBrowser_MouseMove(object sender, MouseEventArgs e)
{
    Close();
}

It seems the WebView2 instance is able to detect mouse hover, but only on the first miliseconds while the window is loading. After that, once the webpage starts loading, there is no way to exit the app except if I kill it (or manually add a handler to detect the Esc key and exit the app).

Additional context

I tried adding the event handlers directly in my Form instance, but it seems Edge eats the mouse events and prevents my app from reading them.

AB#29285088

ukandrewc commented 4 years ago

These events are part of the control that WebView2 inherits from. They don't work in WebView2. You either need to handle them from JS or this control raises mouse events: https://github.com/ukandrewc/Webview2.Winforms.DOM

carlossanlop commented 4 years ago

If you need a repro, feel free to clone this small project I have, and test the above code yourself: https://github.com/carlossanlop/web-page-screensaver The first code snippet goes in PreferencesForm.Designer.cs, and the second code snippet (the two methods) go in PreferencesForm.cs.

jellyedwards commented 3 years ago

Hey @carlossanlop - I'm actually forking the same repo you are (https://github.com/jellyedwards/web-page-screensaver) & I ended up using a transparent panel (https://stackoverflow.com/questions/4463363/how-can-i-set-the-opacity-or-transparency-of-a-panel-in-winforms) & it's mouse move event to hide the screensaver

clshan-13 commented 3 years ago

Hey, @champnic @carlossanlop @jellyedwards @ukandrewc I want to know whether the MouseMove/MouseHover/MouseLeave events are supported in WebView2 Win32. If so, please give some suggestions about how to implement it in C++?

champnic commented 3 years ago

@clshan-13 Those mouse events are WPF, so aren't available in Win32. For mouse events in Win32 you need to handle messages sent to your HWND. For an example of this, please see the OnMouseMessage() function in our sample app: https://github.com/MicrosoftEdge/WebView2Samples/blob/c9eb0c88b61a562c3981098a8651d82ba806f7ce/SampleApps/WebView2APISample/ViewComponent.cpp#L620

darkguy2008 commented 3 years ago

Hi! Chiming in here to say that I've also encountered this problem. Basically I'm trying to implement mouse dragging in a borderless window and while I have it kinda working with postMessage, it isn't ideal because mousemove sends a lot of events. My idea is to actually have a flag to do the dragging, so if the flag is true or false (in mousedown or mouseup) then proceed to drag:

ReleaseCapture();
SendMessage(_hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);

This is working in a sense, I'm able to start dragging, but I'm unable to stop dragging because neither WebView2, or the form, or anything else catches the MouseUp event to set my flag to false. Of course, it may be my fault, but this could be easily solved if WebView2 allowed us to implement the mouse events instead.

Any ideas or workarounds known as to date? Will the MS team implement this feature? Thanks!

obartelt commented 3 years ago

Any news on this? Seems lazy and pathetic to make a WinForms/WPF wrapper control, inherit from the appropriate base control classes but not abstract away the stupid JavaScript workarounds needed to get the desired functionality, which additionally is suggested by inheriting from Control. Needless to say that the JavaScript workarounds do NOT work when injected into loaded documents if you disable scripting alltogether, as I need to do because I'm displaying HTML e-mails which potentially can include malicious scripts :-(

Joren-Thijs commented 3 years ago

Same issue here i am trying to capture the mousemove event for an automatic logout service in WPF. Right now if the user moves inside the webview long enough he is logged out.

I am very dissapointed in the .NET Team something as basic as this is not supported.

I think i wil have to go with messaging from the webview as explained in https://stackoverflow.com/a/65398068/13562840

Kokujou commented 1 year ago

quite old but i do second this request. it's quite frustrating. i'm using blazor which apprently inherits from WebView2. so not only does blazor not handle mouse events itself - you need to use a JS interop, which i hate but now it even PREVENTS the handling of events that would otherwise be there natively... that's frustrating as hell...

i also tried putting a transpaent panel on top BTW but i don't know, maybe i'm not that skilled in WPF but whatever i did whether i changed the Z-Index or whatever, the blazor view was always on top, and I couldn't change it.

so yeah... currently i went to a quite dirty solution which is using a user32 DLL to get the state of the current mouse button, + using the Windows.Forms.Cursor to get the position of the mause for mouse move i'm essentially having a periodic timer that gets started when the user clicks on the UI element (the click event can luckily be handled by blazor because it's element-scope)

but the amount of effort that was involved was crazy and the conversions were also quite strange... because apparently Window.Left doesn't refer to the pixel coordinates so you need to transform stuff to screen coordinates first and all i wanted was a slider 😆

fis-cz commented 1 year ago

Just to add, if somebody needs it. It is possible to capture WM_PARENTNOTIFY event on the form (or the parent control of the WebView) such as (WinForms):

            if (m.Msg == 0x210 /* WM_PARENTNOTIFY */ && m.WParam == 0x201 /* WM_LBUTTONDOWN  */)
            {
                int x = ((int)(m.LParam & 0x0000FFFF)) - webView21.Left;
                int y = ((int)((m.LParam & 0xFFFF0000) >> 16)) - webView21.Top;

                System.Diagnostics.Debug.WriteLine("{0}, {1}", x, y);
            }

            base.WndProc(ref m);
Mrgaton commented 2 months ago

It would be great to add customs events for this