Announce

PukiWiki contents have been moved into SONOTS Plugin (20070703)

vimouse

vimousをハックしてみた時のメモ

http://sourceforge.net/projects/vimouse/

  • ViMouse.cs (Right Click -> View Code)
  • Build -> Use 'vimouse\bin\Release\vimouse.exe'

Modified functions.

  • Default = keyboard
  • Toggle to mouse mode = Shift+Esc
  • Left click = a, right = s, middle = d, wheel = f
  • Unable additional features at keyboard mode.
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using CodeProject.SystemHotkey;
using CodeProject.Win32;

namespace vimouse
{
    public partial class ViMouse : Form
    {
        [DllImport("User32.dll")]
        private static extern short GetAsyncKeyState(Keys vKey);

        private bool flagDoExit = false;
        private bool flagInstalled = false;
        private static Icon iconViMouse = new Icon("vimouse.ico");
        private static Icon iconViMouseKb = new Icon("vimousekb.ico");
        private System.Collections.Hashtable pressed = new Hashtable();

        private static Keys Keys_Semicolon = (Keys)187;

        private SystemHotkey hotkeyToggle = new SystemHotkey();
        private SystemHotkey hotkeyInput = new SystemHotkey();
        private SystemHotkey hotkeyInputNA = new SystemHotkey();
        private SystemHotkey hotkeyEnter = new SystemHotkey();
        private SystemHotkey hotkeyKbUp = new SystemHotkey();
        private SystemHotkey hotkeyKbDown = new SystemHotkey();
        private SystemHotkey hotkeyKbLeft = new SystemHotkey();
        private SystemHotkey hotkeyKbRight = new SystemHotkey();
        private SystemHotkey hotkeyYank = new SystemHotkey();
        private SystemHotkey hotkeyPaste = new SystemHotkey();

        private SystemHotkey hotkeyUp = new SystemHotkey();
        private SystemHotkey hotkeyDown = new SystemHotkey();
        private SystemHotkey hotkeyLeft = new SystemHotkey();
        private SystemHotkey hotkeyRight = new SystemHotkey();
        private SystemHotkey hotkeyLButton = new SystemHotkey();
        private SystemHotkey hotkeyRButton = new SystemHotkey();
        private SystemHotkey hotkeyMButton = new SystemHotkey();
        private SystemHotkey hotkeyWButton = new SystemHotkey();
        private SystemHotkey hotkeyVerySlow = new SystemHotkey();
        private SystemHotkey hotkeyVeryFast = new SystemHotkey();
        private SystemHotkey hotkeySlow = new SystemHotkey();
        private SystemHotkey hotkeyFast = new SystemHotkey();
        private SystemHotkey hotkeyArrow = new SystemHotkey();

        // position
        private double px = 0;
        private double py = 0;

        // velocity
        private double vx = 0;
        private double vy = 0;

        // accelaration
        private double ax = 5;
        private double ay = 5;

        // velocity modification
        private double vfx = 1;
        private double vfy = 1;
        private double vsx = 1;
        private double vsy = 1;
        private double fx = 1;
        private double fy = 1;
        private double sx = 1;
        private double sy = 1;

        public ViMouse()
        {
            InitializeComponent();
            
            hotkeyToggle.Pressed += new EventHandler(hotkeyToggle_Pressed);
            hotkeyInput.Pressed += new EventHandler(hotkeyInput_Pressed);
            hotkeyInputNA.Pressed += new EventHandler(hotkeyInputNA_Pressed);
            hotkeyEnter.Pressed += new EventHandler(hotkeyEnter_Pressed);
            hotkeyYank.Pressed += new EventHandler(hotkeyYank_Pressed);
            hotkeyPaste.Pressed += new EventHandler(hotkeyPaste_Pressed);
            hotkeyKbDown.Pressed += new EventHandler(hotkeyKbDown_Pressed);
            hotkeyKbUp.Pressed += new EventHandler(hotkeyKbUp_Pressed);
            hotkeyKbLeft.Pressed += new EventHandler(hotkeyKbLeft_Pressed);
            hotkeyKbRight.Pressed += new EventHandler(hotkeyKbRight_Pressed);

            hotkeyDown.Pressed += new EventHandler(hotkey_Pressed);
            hotkeyUp.Pressed += new EventHandler(hotkey_Pressed);
            hotkeyLeft.Pressed += new EventHandler(hotkey_Pressed);
            hotkeyRight.Pressed += new EventHandler(hotkey_Pressed);
            hotkeyLButton.Pressed += new EventHandler(hotkey_Pressed);
            hotkeyRButton.Pressed += new EventHandler(hotkey_Pressed);
            hotkeyMButton.Pressed += new EventHandler(hotkey_Pressed);
            hotkeyWButton.Pressed += new EventHandler(hotkey_Pressed);
            hotkeyArrow.Pressed += new EventHandler(hotkey_Pressed);

            hotkeyFast.Pressed += new EventHandler(hotkey_Pressed);
            hotkeySlow.Pressed += new EventHandler(hotkey_Pressed);
            hotkeyVeryFast.Pressed += new EventHandler(hotkey_Pressed);
            hotkeyVerySlow.Pressed += new EventHandler(hotkey_Pressed);
        }

        void hotkeyInputNA_Pressed(object sender, EventArgs e)
        {
            Uninstall();
        }

        void hotkeyKbRight_Pressed(object sender, EventArgs e)
        {
            Input.Arrow(1, 0);
        }

        void hotkeyKbLeft_Pressed(object sender, EventArgs e)
        {
            Input.Arrow(-1, 0);
        }

        void hotkeyKbUp_Pressed(object sender, EventArgs e)
        {
            Input.Arrow(0, -1);
        }

        void hotkeyKbDown_Pressed(object sender, EventArgs e)
        {
            Input.Arrow(0, 1);
        }

        void hotkeyPaste_Pressed(object sender, EventArgs e)
        {
            notifyIcon.ShowBalloonTip(10000, "操作", "貼り付けました", ToolTipIcon.Info);
            Input.KeyDown(Keys.LControlKey);
            Input.KeyClick(Keys.V);
            Input.KeyUp(Keys.LControlKey);
        }

        void hotkeyYank_Pressed(object sender, EventArgs e)
        {
            notifyIcon.ShowBalloonTip(10000, "操作", "コピーしました", ToolTipIcon.Info);
            Keys old = hotkeyToggle.HotKey;
            Input.KeyDown(Keys.LControlKey);
            Input.KeyClick(Keys.C);
            Input.KeyUp(Keys.LControlKey);
            hotkeyToggle.HotKey = old;
        }

        void hotkeyEnter_Pressed(object sender, EventArgs e)
        {
            Input.KeyClick(Keys.Enter);
        }

        void hotkeyInput_Pressed(object sender, EventArgs e)
        {
            Input.LClick();
            Uninstall();
        }

        void hotkey_Pressed(object sender, EventArgs e)
        {
            if (pressed[sender] == null)
            {
                if (sender == hotkeyLButton) Input.LDown();
                else if (sender == hotkeyRButton) Input.RDown();
                else if (sender == hotkeyMButton) Input.MDown();
                else if (sender == hotkeyFast) fx = fy = 2;
                else if (sender == hotkeySlow) sx = sy = 0.7;
                else if (sender == hotkeyVeryFast) vfx = vfy = 3;
                else if (sender == hotkeyVerySlow) vsx = vsy = 0.3;
                else if (sender == hotkeyArrow) Input.Focus();
            }

            pressed[sender] = true;
        }

        void hotkeyToggle_Pressed(object sender, EventArgs e)
        {
            Install();
        }

        private void Install()
        {
            if (flagInstalled) return;

            // ホットキーの登録解除
            hotkeyToggle.HotKey = Keys.None;
            hotkeyEnter.HotKey = Keys.None;
            hotkeyKbRight.HotKey = Keys.None;
            hotkeyKbLeft.HotKey = Keys.None;
            hotkeyKbUp.HotKey = Keys.None;
            hotkeyKbDown.HotKey = Keys.None;

            // ホットキーの登録
            hotkeyDown.HotKey = Keys.J;
            hotkeyUp.HotKey = Keys.K;
            hotkeyLeft.HotKey = Keys.H;
            hotkeyRight.HotKey = Keys.L;
            hotkeyLButton.HotKey = Keys.A;
            hotkeyMButton.HotKey = Keys.S;
            hotkeyRButton.HotKey = Keys.D;
            hotkeyWButton.HotKey = Keys.F;
            hotkeyInput.HotKey = Keys.I;
            hotkeyInputNA.HotKey = Keys.O;
            hotkeyVeryFast.HotKey = Keys.V;
            hotkeyFast.HotKey = Keys.C;
            hotkeySlow.HotKey = Keys.X;
            hotkeyVerySlow.HotKey = Keys.Z;
            hotkeyYank.HotKey = Keys.Y;
            hotkeyPaste.HotKey = Keys.P;
            hotkeyArrow.HotKey = Keys.R;

            // カーソル座標を取得
            px = Cursor.Position.X + 0.5;
            py = Cursor.Position.Y + 0.5;

            notifyIcon.Icon = iconViMouse;
            timer.Start();
            flagInstalled = true;
        }

        private void Uninstall()
        {
            if (!flagInstalled) return;

            // ホットキーの登録解除
            hotkeyDown.HotKey = Keys.None;
            hotkeyUp.HotKey = Keys.None;
            hotkeyLeft.HotKey = Keys.None;
            hotkeyRight.HotKey = Keys.None;
            hotkeyLButton.HotKey = Keys.None;
            hotkeyRButton.HotKey = Keys.None;
            hotkeyMButton.HotKey = Keys.None;
            hotkeyWButton.HotKey = Keys.None;
            hotkeyInput.HotKey = Keys.None;
            hotkeyInputNA.HotKey = Keys.None;
            hotkeyFast.HotKey = Keys.None;
            hotkeySlow.HotKey = Keys.None;
            hotkeyVeryFast.HotKey = Keys.None;
            hotkeyVerySlow.HotKey = Keys.None;
            hotkeyYank.HotKey = Keys.None;
            hotkeyPaste.HotKey = Keys.None;
            hotkeyArrow.HotKey = Keys.None;

            // ホットキーの登録
            hotkeyToggle.HotKey = Keys.Shift | Keys.Escape;
            //hotkeyEnter.HotKey = Keys.Control | Keys.M;
            //hotkeyKbDown.HotKey = Keys.Control | Keys.J;
            //hotkeyKbUp.HotKey = Keys.Control | Keys.K;
            //hotkeyKbLeft.HotKey = Keys.Control | Keys.H;
            //hotkeyKbRight.HotKey = Keys.Control | Keys.L;

            notifyIcon.Icon = iconViMouseKb;
            timer.Stop();
            flagInstalled = false;
        }

        private void ViMouse_Load(object sender, EventArgs e)
        {
            Install();
            Uninstall();
        }

        private void ViMouse_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!flagDoExit)
            {
                WindowState = FormWindowState.Minimized;
                Hide();
                e.Cancel = true;
            }
        }

        private void notifyIcon_MouseClick(object sender, MouseEventArgs e)
        {
            switch (e.Button)
            {
            case MouseButtons.Left:
                Show();
                WindowState = FormWindowState.Normal;
                Activate();
                break;
            case MouseButtons.Right:
                break;
            }
        }

        private void menuitemExit_Click(object sender, EventArgs e)
        {
            flagDoExit = true;
            Close();
        }

        private void ViMouse_FormClosed(object sender, FormClosedEventArgs e)
        {
            Uninstall();
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            // 押上チェック
            ArrayList removed = new ArrayList();
            foreach (DictionaryEntry d in pressed)
            {
                SystemHotkey hotkey = (SystemHotkey)d.Key;
                if (GetAsyncKeyState(hotkey.HotKey) >= 0)
                {
                    removed.Add(hotkey);
                }
            }
            foreach (SystemHotkey hotkey in removed)
            {
                if (hotkey == hotkeyLButton) Input.LUp();
                else if (hotkey == hotkeyRButton) Input.RUp();
                else if (hotkey == hotkeyMButton) Input.MUp();
                else if (hotkey == hotkeyFast) fx = fy = 1;
                else if (hotkey == hotkeySlow) sx = sy = 1;
                else if (hotkey == hotkeyVeryFast) vfx = vfy = 1;
                else if (hotkey == hotkeyVerySlow) vsx = vsy = 1;
                pressed.Remove(hotkey);
            }

            // マウス移動チェックと同期
            if ((int)px != Cursor.Position.X || (int)py != Cursor.Position.Y)
            {
                px = Cursor.Position.X + 0.5;
                py = Cursor.Position.Y + 0.5;
            }
            
            // ベクトルチェック
            double dx = 0, dy = 0;
            if (pressed[hotkeyDown] != null) dy += 1;
            if (pressed[hotkeyUp] != null) dy -= 1;
            if (pressed[hotkeyLeft] != null) dx -= 1;
            if (pressed[hotkeyRight] != null) dx += 1;
            double scale = Math.Sqrt(dx * dx + dy * dy);

            // 加速
            vx += ax * dx / scale;
            vy += ay * dy / scale;

            // 減速
            vx *= 0.8;
            vy *= 0.8;

            // 無入力チェック
            if (scale < 0.5)
            {
                vx = 0;
                vy = 0;
                return;
            }

            double VX = vfx * vsx * fx * sx * vx;
            double VY = vfy * vsy * fy * sy * vy;

            // ホイールモードのチェック
            if (pressed[hotkeyWButton] != null)
            {
                Input.Wheel((int)(VX * 1), (int)(VY * 0.15));
                return;
            }

            // 矢印キーモードのチェック
            if (pressed[hotkeyArrow] != null)
            {
                Input.Arrow((int)(VX * 0.15), (int)(VY * 0.15));
                return;
            }

            // 移動
            px += VX;
            py += VY;

            // マウス移動
            Cursor.Position = new Point((int)px, (int)py);
        }

        private void ViMouse_Shown(object sender, EventArgs e)
        {
            Hide();
        }

        private void tableLayoutPanel_Paint(object sender, PaintEventArgs e)
        {

        }
    }
}