I'm developing a Windows Forms application in C# with an embedded WebBrowser
control to "dummy-proof" (i.e. disable context menus, back button, free navigation, etc.) access to a third-party web application.
Right now I'm trying to add the Zoom feature to my custom browser. I have the keyboard combos working for it (CTRL + and CTRL - make the correct OLE calls to the underlying ActiveX WebBrowser object), but among the other frustrating things about WebBrowser
I've had to deal with, I can't seem to figure out how to capture CTRL-Mouse wheel to simulate the Zoom function like IE does. I've looked everywhere to find a solution to this but to no avail.
To try to figure it out, I created an empty form with just the WebBrowser control in it, and found the following:
MouseWheel
event when the parent form has focus and the mouse cursor is hovering over the top of the window (e.g. over the title of the application), or when the mouse cursor is hovering over the WebBrowser
control when it does not appear to have focus even though the parent form has focus.MouseWheel
event when the mouse cursor is hovering over the WebBrowser
control and WebBrowser
has focus, and there seems to be no effect.WebBrowser
but does not fire the MouseWheel
event until the vertical scroll bar has fully reached either the top or the bottom.
Message
for WM_MOUSEWHEEL
by overriding WndProc
and DefWndProc
both for a sample class inherited from WebBrowser
and for the parent form applies only for the above conditions (with wParam
properly denoting MK_CONTROL
).PreviewKeyDown
event fires when CTRL is pressed, as expected, but still does nothing in unison with the mouse wheel.So I guess the Message
is being processed below the parent form and the managed control level and does not bubble up to where I can intercept or even handle it. Is there a way to do this, or some other way to simulate zooming in and out using CTRL-MouseWheel?
Thanks for reading!
First cast the WebBrowser.Document.DomDocument
to the right interface in the mshtml namespace, like mshtml.HTMLDocumentEvents2_Event
, then you can handle (and cancel) mousewheel events. I'm not sure, but I think you need to wire up the event handler anytime the document is changed, so I do it on the WebBrowser.DocumentCompleted
event. I'm also not sure if you need to release any COM objects.
This was frustrating enough that I got it to work and stopped caring...
Here is at least one document explaining the basics: How to handle document events in a Visual C# .NET application
For your specific case, just conditionally squash the onmousewheel
event, based on whether or not the CTRL
key is pressed.
private void webBrowser_DocumentCompleted(object sender,
WebBrowserDocumentCompletedEventArgs e)
{
if (webBrowser.Url.ToString() == "about:blank")
return;
var docEvents = (mshtml.HTMLDocumentEvents2_Event)webBrowser.Document.DomDocument;
docEvents.onmousewheel -= docEvents_onmousewheel; //may not be necessary?
docEvents.onmousewheel += docEvents_onmousewheel;
}
bool docEvents_onmousewheel(mshtml.IHTMLEventObj pEvtObj)
{
if (pEvtObj.ctrlKey)
{
pEvtObj.cancelBubble = true; //not sure what this does really
pEvtObj.returnValue = false; //this cancels the event
return false; //not sure what this does really
}
else
return true; //again not sure what this does
}
Now if you need to know the Wheel Delta (scroll amount), you'll want to cast the events object to yet another interface.
bool docEvents_onmousewheel(mshtml.IHTMLEventObj pEvtObj)
{
var wheelEventObj = (mshtml.IHTMLEventObj4)pEvtObj;
var delta = wheelEventObj.wheelDelta;
[...]
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With