マウスジェスチャ対応ブラウザコンポーネント 暫定版

とりあえず載せてみます。突っ込み大歓迎!

#region マウスジェスチャ対応ブラウザクラス
/// <summary>
/// マウスジェスチャ対応ブラウザクラス
/// </summary>
public class MGWebBrowser : WebBrowser
{
    // マウスジェスチャ 方向
    private enum GestureDirection
    {
        Up,
        Down,
        Left,
        Right,
        None,
    }

    // マウスジェスチャ 状態
    private enum GestureStatus
    {
        Gesturing,
        Gestured,
        GestureStop,
        None,
    }

    private bool mouseGestureLeftDown = false;
    private bool mouseGestureRightDown = false;

    private Point mouseStartPos;
    private Point mousePreStartPos;

    private GestureStatus mouseGestureStatus = GestureStatus.None;

    private int mouseGestureAccuracy = 10; // マウス移動量感度
    //private int mouseGectureClearance = 7; // マウス移動間隔 未使用
    private List<GestureDirection> gestureList;

    public MGWebBrowser()
    {
        gestureList = new List<GestureDirection>();
        this.Navigated += new WebBrowserNavigatedEventHandler(MGWebBrowser_Navigated);
    }

    void MGWebBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
    {
        this.Document.MouseDown += new HtmlElementEventHandler(Document_MouseDown);
        this.Document.MouseUp += new HtmlElementEventHandler(Document_MouseUp);
        this.Document.MouseMove += new HtmlElementEventHandler(Document_MouseMove);
    }

    void Document_MouseMove(object sender, HtmlElementEventArgs e)
    {
        if (mouseGestureStatus != GestureStatus.None)
        {
            int X = e.MousePosition.X - mouseStartPos.X;
            int Y = e.MousePosition.Y - mouseStartPos.Y;
            int pX = e.MousePosition.X - mousePreStartPos.X;
            int pY = e.MousePosition.Y - mousePreStartPos.Y;

            // 移動量が mouseGestureAccuracy 以上であれば方向データを記録
            if (Math.Abs(X) >= mouseGestureAccuracy || Math.Abs(Y) >= mouseGestureAccuracy)
            {
                if (gestureList.Count == 0 || getDirection(pX, pY) != gestureList[gestureList.Count - 1])
                {
                    gestureList.Add(getDirection(X, Y));
                    mouseStartPos.X = e.MousePosition.X;
                    mouseStartPos.Y = e.MousePosition.Y;
                    mousePreStartPos.X = e.MousePosition.X;
                    mousePreStartPos.Y = e.MousePosition.Y;
                }
            }
        }
    }

    void Document_MouseUp(object sender, HtmlElementEventArgs e)
    {
        Debug.WriteLine("Mouse UP");
        Debug.WriteLine(e.MouseButtonsPressed);
        if (e.MouseButtonsPressed == (MouseButtons.Left | MouseButtons.Right))
        {
            Debug.WriteLine("Gesturing Off");
        }
        else
        {
            if (e.MouseButtonsPressed == MouseButtons.Right)
            {
                mouseGestureRightDown = false;
            }
            else if (e.MouseButtonsPressed == MouseButtons.Left)
            {
                mouseGestureLeftDown = false;
            }
        }

        if (mouseGestureStatus == GestureStatus.Gesturing)
        {
            if (gestureList[0] == GestureDirection.Left)
            {
                GoBack();
            }
            else if (gestureList[0] == GestureDirection.Right)
            {
                GoForward();
            }
            mouseGestureStatus = GestureStatus.None;
            gestureList.Clear();
        }
    }

    void Document_MouseDown(object sender, HtmlElementEventArgs e)
    {
        if (e.MouseButtonsPressed == MouseButtons.Left)
        {
            mouseGestureLeftDown = true;
        }
        else if (e.MouseButtonsPressed == MouseButtons.Right)
        {
            mouseGestureStatus = GestureStatus.Gesturing;

            mouseStartPos.X = e.MousePosition.X;
            mouseStartPos.Y = e.MousePosition.Y;
            mousePreStartPos.X = e.MousePosition.X;
            mousePreStartPos.Y = e.MousePosition.Y;

            mouseGestureRightDown = true;
        }
        else if (e.MouseButtonsPressed == (MouseButtons.Left | MouseButtons.Right))
        {
            Debug.WriteLine("Gesturing On");
            mouseGestureStatus = GestureStatus.Gesturing;
            e.ReturnValue = true;
            if (mouseGestureRightDown)
            {
                this.GoBack();
            }
            else if (mouseGestureLeftDown)
            {
                this.GoForward();
            }
        }
    }

    private GestureDirection getDirection (int X, int Y)
    {
        if (Math.Abs(X) >= Math.Abs(Y))
        {
            if (X > 0)
            {
                return GestureDirection.Right;
            }
            else
            {
                return GestureDirection.Left;
            }
        }
        else
        {
            if (Y > 0)
            {
                return GestureDirection.Down;
            }
            else
            {
                return GestureDirection.Up;
            }
        }
    }
}
#endregion

ジェスチャする度に gestureList に方向データを溜めていきます。んで右ボタンから指を離す時に gestureList の内容を判断して、対応する動作を行います。今は戻ると進むしか実装していませんが、追加するのは簡単です。まぁ最近の流れからいえば、カスタマイズが可能なように作るべきでしょうから、デリゲート使いまくりで作っていくことになると思いますが。

ポップアップが出る問題は解決していません。あと Generics を使ってる List 型を使っているので C#2.0 専用です。