コントロールに簡単にマウスジェスチャを実装出来る。WebBrowserコントロールには使えない。
using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; namespace Anis.Controls { ///<summary>コントロールにマウスジェスチャ機能を追加するクラス</summary> public class MouseGestureListener :IDisposable { Control ctrl; ToolStripStatusLabel statusView; int sensitivity; string gestureStatus; Dictionary<string, string> actionList; Point mousePosition; bool contextMenuEnabled; bool isMouseDown = false; ContextMenuEnabledChange contextMenuEnabledChange; /// <param name="ctrl">マウスジェスチャ機能を追加するコントロール</param> /// <param name="sensitivity">マウスジェスチャの感度</param> /// <param name="statusToolStripItem">マウスジェスチャの状態を表示させるToolStripItem</param> /// <param name="actionList">キーに"↑","→","↓","←",を組み合わせたマウスジェスチャを、 /// 値にアクション名を登録したDictionary</param> /// <param name="contextMenuEnabledChange">コンテキストメニューの有効無効を切り替えるためのメソッド</param> /// <param name="contextMenuEnabled">コンテキストメニューの有効、無効</param> ///<remarks>マウスジェスチャが完了するとGestureCompleteイベントが発生するので、 /// e.Actionでアクション名を取得して下さい。</remarks> public MouseGestureListener( Control ctrl, ToolStripStatusLabel statusView, int sensitivity, Dictionary<string, string> actionList, ContextMenuEnabledChange contextMenuEnabledChange, bool contextMenuEnabled) { this.ctrl = ctrl; this.sensitivity = sensitivity; this.statusView = statusView; this.actionList = actionList; this.contextMenuEnabledChange = contextMenuEnabledChange; this.contextMenuEnabled = contextMenuEnabled; statusView.TextChanged += new EventHandler(statusToolStripItem_TextChanged); ctrl.MouseDown += new MouseEventHandler(ctrl_MouseDown); ctrl.MouseMove += new MouseEventHandler(ctrl_MouseMove); ctrl.MouseUp += new MouseEventHandler(ctrl_MouseUp); ctrl.PreviewKeyDown += new PreviewKeyDownEventHandler(ctrl_PreviewKeyDown); } void ctrl_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) { contextMenuEnabledChange(contextMenuEnabled); } void ctrl_MouseUp(object sender, MouseEventArgs e) { if(actionList.ContainsKey(gestureStatus)) { GestureComplete(sender, new GestureCompleteEventArgs(actionList[gestureStatus])); } isMouseDown = false; gestureStatus = ""; statusView.Text = ""; } void ctrl_MouseMove(object sender, MouseEventArgs e) { if(gestureStatus == "") { contextMenuEnabledChange(contextMenuEnabled); } if(Control.MouseButtons != MouseButtons.Right) { isMouseDown = false; statusView.Text = ""; gestureStatus = ""; } if(isMouseDown) { string str = ""; bool flag = false; if(mousePosition.X - e.Location.X >= sensitivity && !gestureStatus.EndsWith("←")) { str = "←"; flag = true; } else if(mousePosition.X - e.Location.X <= -sensitivity && !gestureStatus.EndsWith("→")) { str = "→"; flag = true; } else if(mousePosition.Y - e.Location.Y >= sensitivity && !gestureStatus.EndsWith("↑")) { str = "↑"; flag = true; } else if(mousePosition.Y - e.Location.Y <= -sensitivity && !gestureStatus.EndsWith("↓")) { str = "↓"; flag = true; } if(flag) { mousePosition = e.Location; gestureStatus += str; statusView.Text = gestureStatus; contextMenuEnabledChange(false); } } } void ctrl_MouseDown(object sender, MouseEventArgs e) { if(Control.MouseButtons == MouseButtons.Right) { mousePosition = e.Location; gestureStatus = ""; isMouseDown = true; } } void statusToolStripItem_TextChanged(object sender, EventArgs e) { ToolStripItem ctrl = (ToolStripItem)sender; if(actionList.ContainsKey(ctrl.Text)) { ctrl.Text += "[" + actionList[ctrl.Text] + "]"; } } /// <summary>マウスジェスチャが完了すると発生するイベント</summary> public event GestureCompleteEventHandler GestureComplete; #region IDisposable メンバ public void Dispose() { statusView.TextChanged -= new EventHandler(statusToolStripItem_TextChanged); ctrl.MouseDown -= new MouseEventHandler(ctrl_MouseDown); ctrl.MouseMove -= new MouseEventHandler(ctrl_MouseMove); ctrl.MouseUp -= new MouseEventHandler(ctrl_MouseUp); ctrl.PreviewKeyDown -= new PreviewKeyDownEventHandler(ctrl_PreviewKeyDown); } #endregion } ///<summary>GestureCompleteイベントを処理するメソッドを表します。</summary> public delegate void GestureCompleteEventHandler(object sender, GestureCompleteEventArgs e); /// <summary>コンテキストメニューの有効、無効を切り替えるメソッドを表します。</summary> public delegate void ContextMenuEnabledChange(bool contextMenuEnabled); /// <summary>GestureCompleteイベントのデータ</summary> public class GestureCompleteEventArgs :EventArgs { private string action_ = ""; /// <param name="action">マウスジェスチャのアクション名</param> public GestureCompleteEventArgs(string action) : base() { action_ = action; } /// <summary>マウスジェスチャのアクション名を取得します。</summary> public string Action { get { return action_; } } } }
以下の様に使用する。
using System; using System.Collections.Generic; using System.Windows.Forms; using Anis.Controls; namespace WindowsFormsApplication1 { public partial class Form1 :Form { public Form1() { InitializeComponent(); } MouseGestureListener mgl; private void Form1_Load(object sender, EventArgs e) { Dictionary<string, string> gestureList = new Dictionary<string, string>(); gestureList.Add("↓→↓", "閉じる"); mgl = new MouseGestureListener( this.textBox1, this.toolStripStatusLabel1,15, gestureList, contextEnabledChange, this.textBox1.ShortcutsEnabled); mgl.GestureComplete += new GestureCompleteEventHandler(mgl_GestureComplete); } void mgl_GestureComplete(object sender, GestureCompleteEventArgs e) { if(e.Action == "閉じる") { this.Close(); } } private void contextEnabledChange(bool value) { this.textBox1.ShortcutsEnabled = value; } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { mgl.Dispose(); } } }
This program is wonderful! be moved!
Thanks for the try!