Xbutton navigation, in integrated browser with c#

I have been trying for a while to find a way with the application I am developing to navigate Forward or Back using only the xbuttons (4th and 5th button of a 5 button mouse) with the integrated browser. After spending some time trying various things I found a solution posted in one of the msdn sites… unfortunately I don’t remember the URL to link to the site. The original code was in Visual Basic.

Here is the MessageFilter class responsible for the MessageFilter instance that handles the WM_XBUTTONDOWN message.

using System;
using System.Windows.Forms;

public class MessageFilter : IMessageFilter
{
 const int WM_XBUTTONDOWN = 0x020B;
 const int MK_XBUTTON1 = 65568;
 const int MK_XBUTTON2 = 131136;

 private Form _form;
 private EventHandler _backevent;
 private EventHandler _forwardevent;

 /// <summary>
 /// Initializes a new instance of the <see cref="MessageFilter"/> class.
 /// </summary>
 /// <param name="f">The form.</param>
 /// <param name="backevent">The backevent.</param>
 /// <param name="forwardevent">The forwardevent.</param>
 public MessageFilter(WebForm f, ref EventHandler backevent, ref EventHandler forwardevent)
 {
  _form = f;
  _backevent = backevent;
  _forwardevent = forwardevent;
 }

 /// <summary>
 /// Filters out a message before it is dispatched.
 /// </summary>
 /// <param name="m">The message to be dispatched. You cannot modify this message.</param>
 /// <returns>
 /// true to filter the message and stop it from being dispatched; false to allow the message to continue to the next filter or control.
 /// </returns>
 public bool PreFilterMessage(ref Message m)
 {
  bool bHandled = false;

  if (m.Msg == WM_XBUTTONDOWN)
  {
   int w = m.WParam.ToInt32();
   if (w == MK_XBUTTON1)
   {
    _backevent.Invoke(_form, EventArgs.Empty);
    bHandled = true;
   }
   else if (w == MK_XBUTTON2)
   {
    _forwardevent.Invoke(_form, EventArgs.Empty);
    bHandled = true;
   }
  }
 return bHandled;
 }
}

Furthermore you also have to add the following to the code of the form of the browser element:

In the constructor of the form after the call of the InitializeComponent(); method you have to create some Event Handlers for the following events:

this.HandleCreated += new EventHandler(webForm_HandleCreated);
this.HandleDestroyed += new EventHandler(webForm_HandleDestroyed);
this.Activated += new EventHandler(webForm_Activated);
this.Deactivate += new EventHandler(webForm_Deactivate);

And here are the Event Handle methods:

private void webForm_HandleCreated(object sender, EventArgs e)
 {
  EventHandler backevent = new EventHandler(backToolStripButton_Click);
  EventHandler forwardevent = new EventHandler(forwardToolStripButton_Click);
  _mbfilter = new MessageFilter(this, ref backevent, ref forwardevent);
 }
 private void webForm_HandleDestroyed(object sender, EventArgs e)
 {
  _mbfilter = null;
 }
 private void webForm_Activated(object sender, EventArgs e)
 {
  Application.AddMessageFilter(_mbfilter);
 }

 private void webForm_Deactivate(object sender, EventArgs e)
 {
  Application.RemoveMessageFilter(_mbfilter);
 }

For the backward and forward EventHandlers, the EventHandlers of the forward and backward buttons are used.

private void backToolStripButton_Click(object sender, EventArgs e)
 {
  if (geckoReader.CanGoBack)
   geckoReader.GoBack();
 }

private void forwardToolStripButton_Click(object sender, EventArgs e)
{
 if (geckoReader.CanGoForward)
  geckoReader.GoForward();
}

geckoReader is an instance of the GeckoFX gecko c# wrapper.

2 thoughts on “Xbutton navigation, in integrated browser with c#

  1. With many respect i think this is a better solution:

    private const int WM_APPCOMMAND = 0x0319;
    private const long XBUTTON1 = 0x80010000;
    private const long XBUTTON2 = 0x80020000;

    protected override void WndProc(ref Message m)
    {
    switch (m.Msg)
    {
    case WM_APPCOMMAND:
    var lparam = m.LParam.ToInt64();
    if (lparam == XBUTTON1)
    {
    // your code hare
    }
    else if (lparam == XBUTTON2)
    {
    // your code hare
    }
    base.WndProc(ref m);
    break;
    default:
    base.WndProc(ref m);
    break;
    }
    }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s