Scott Hood
Scott Hood

Reputation: 21

Allow user to zoom with mousewheel using the cefsharp browser

I am running cefsharp/75. I want to turn on zooming with the ctrl key and the mousewheel. My event handler is never triggered. And if you hold ctrl and use the mouse will the screen doesn't move. So something inside the control and handling the event. Is there just a setting I am missing?

Upvotes: 2

Views: 2131

Answers (3)

alexb
alexb

Reputation: 33

Here is a WinForms solution:
Register a MouseEventHandler for the form:

this.MouseWheel += new MouseEventHandler(this.OnMouseWheel);

private void OnMouseWheel(object sender, System.Windows.Forms.MouseEventArgs e)
{
  Control ctrl = FindControlAtCursor(this);
  if (ctrl == null) return; 
if(control is CEFBrowser)
{
  var zoomLevel = CefSharp.WebBrowserExtensions.GetZoomLevelAsync((ChromiumWebBrowser)ctrl).Result;
  zoomLevel += e.Delta > 0 ? 0.1 : -0.1;
  (ctrl as CefSharp.IWebBrowser).GetBrowser().GetHost().SetZoomLevel(zoomLevel);
}
}

It works OK except for one thing: after performing Zoom then scrolling the page, you must click anywhere outside the CEF control before zooming again.

Upvotes: -1

TheBoxyBear
TheBoxyBear

Reputation: 391

Using CefSharp.WinForms.NETCore v114.2.120 for my project, I was able to get it to work using ChromiumWidgetNativeWindow to handle the WM_MOUSEWHEEL and WM_MOUSEHWHEEL WndProc messages.

ChromiumRenderWidgetHandleFinder.TryFindHandle(browser, out var chromeWidgetHostHandle);
NativeWindow = new ChromiumWidgetNativeWindow(browser, chromeWidgetHostHandle);
NativeWindow.OnWndProc(Browser_WndProc);

Here is where I handle the scrolling, where delta is the number of ticks of the scroll wheel, negative when scrolling down.

private bool Browser_WndProc(Message m)
{
    if (m.Msg is not 0x020A or 0x020E) // Mouse wheel
        return false;

    if ((m.WParam & 0x0008) == 0) // Ctrl pressed
        return false;

    short delta = (short)((short)(m.WParam >> 16 & 0xFFFF) / 120);
    ZoomLevel += zoomRate * delta;

    return true;
}

ZoomLevel is a property I defined to control the zoom of the browser

public double ZoomLevel
{
    get => _zoomLevel;
    set => browser.SetZoomLevel(_zoomLevel = value);
}
private double _zoomLevel = 1d;

It's important to note that fetching the handle will often fail if done right after creating the ChromiumWebBrowser instance. I got good results by waiting until after the first page navigation.

browser.LoadUrl(url);
await browser.WaitForNavigationAsync();

if (NativeWindow is null)
{
    ChromiumRenderWidgetHandleFinder.TryFindHandle(browser, out var chromeWidgetHostHandle);
    NativeWindow = new ChromiumWidgetNativeWindow(browser, chromeWidgetHostHandle);
    NativeWindow.OnWndProc(Browser_WndProc);
}

Upvotes: 0

vik_78
vik_78

Reputation: 1157

I added mouse and keyboard zoom. In init section subscribe for events

cefBrowser.PreviewMouseWheel += CefBrowser_PreviewMouseWheel;
cefBrowser.KeyUp += CefBrowser_KeyUp;

I used PreviewMouseWheel to avoid scrolling during zoom (e.Handled = true).

private void CefBrowser_PreviewMouseWheel(object sender, MouseWheelEventArgs e) {

  if (Keyboard.Modifiers != ModifierKeys.Control)
    return;

  if (e.Delta > 0)
    cefBrowser.ZoomInCommand.Execute(null);
  else
    cefBrowser.ZoomOutCommand.Execute(null);
  e.Handled = true;
}

private void CefBrowser_KeyUp(object sender, KeyEventArgs e) {

  if (Keyboard.Modifiers != ModifierKeys.Control)
    return;

  if (e.Key == Key.Add)
    cefBrowser.ZoomInCommand.Execute(null);
  if (e.Key == Key.Subtract)
    cefBrowser.ZoomOutCommand.Execute(null);
  if (e.Key == Key.NumPad0)
    cefBrowser.ZoomLevel = 0;
}

So now cef zooming almost like chrome

Upvotes: 4

Related Questions