( ・ω・)且~~

ネトゲとか雑記

自分用キーコンあぷり

2011年06月25日 | ソフトとか

・・・自分用のwikiなり作っておくべきだったなぁ~(´-`)且~~

自分の家だとソフトで無変換キーをマウスの左クリックに割り当ててるんだけど、今のお仕事先で勝手にネットからソフトを落としてくる事が出来ないので自作。

ソースコードを出先でコンパイルする分には何も言われまい(たぶん)。
低レベルグローバルフック使ってるからセキュリティソフトによっては文句言われるかな~?

作って気づいたけど、.net framework 3 ぐらいで作っておけばVistaなら標準で入ってるしデフォで使えるじゃん・・・
4で作って失敗したかもとか思ったけどメンドイしイイヤ。
3で作ってもVisualStudio2008以上が入ってないとコンパイルデキナイし。

Hookのときにウィンドウメッセージを使ってるからなのかコンソールアプリで作ると動かない。
Threadとは違うと思うしウィンドウズフォームアプリだと動くからWndProc絡みなのかなー

-----------------------------------------------------------

 public partial class Form1 : Form

    {
        public Form1()
        {
            InitializeComponent();

            Action<ushort,ushort,Action> addActionsInHook = (UpOrDown, KeyCode, MouseAct) =>
            {
                Func<bool> keyAction = () => { MouseAct(); return false; };
                Hook._ActionsInHook.Add(new Tuple<IntPtr,ushort>((IntPtr)UpOrDown, KeyCode), keyAction);
            };
            addActionsInHook(0x0100, 29, EventSender.LBtnDown ); //無変換キーDOWNでマウス左ボタンDOWN
            addActionsInHook(0x0101, 29, EventSender.LBtnUp);   //無変換キーUPでマウス左ボタンUP
            Hook.Start();
            this.Load += new System.EventHandler(Form1_Load);

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Location = new Point(Screen.PrimaryScreen.WorkingArea.Width - 100, Screen.PrimaryScreen.WorkingArea.Height - 50);
            this.ShowInTaskbar = false;
            this.FormBorderStyle = FormBorderStyle.None;
            this.TransparencyKey = this.BackColor;
            var btn = new Button();
            btn.BackColor = Color.BurlyWood;
            btn.Click += new System.EventHandler(new EventHandler((object sen, EventArgs evn) => { this.Close(); }));
            this.Controls.Add(btn);
        }

        public static class Hook
        {
            private delegate IntPtr HookProcDelegate_KB(int nCode, IntPtr wParam, ref KeybordInput lParam);

            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
            private static extern IntPtr SetWindowsHookEx(int hooktype, HookProcDelegate_KB lpfn, IntPtr hMod, int threadId);

            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            private static extern bool UnhookWindowsHookEx(IntPtr idHook);

            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            private static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, ref  KeybordInput lParam);

            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern IntPtr GetModuleHandle(String lpModuleName);

            [StructLayout(LayoutKind.Sequential)]
            private struct KeybordInput
            {
                public ushort wVk, wScan;
                public uint dwFlag, time;
                public IntPtr dwExtraInfo;
            }

            private static IntPtr _SHook = IntPtr.Zero;             //プロシージャハンドル保存用
            private static HookProcDelegate_KB _HProc;              //フック用デリゲート

            public static Dictionary<Tuple<IntPtr,ushort>, Func<bool>> _ActionsInHook = new Dictionary<Tuple<IntPtr,ushort>, Func<bool>>();

            public static void Start()
            {
                using (ProcessModule module = Process.GetCurrentProcess().MainModule)
                {
                    _HProc = new HookProcDelegate_KB(Hook_Proc);
                    var hMod = GetModuleHandle(module.ModuleName);
                    _SHook = SetWindowsHookEx(13, _HProc, hMod, 0);
                }
            }

            public static void End() { UnhookWindowsHookEx(_SHook); }

            private static IntPtr Hook_Proc(int nCode, IntPtr wParam, ref KeybordInput lParam)
            {
                bool flgChain = true;
                try { if (nCode == 0x0000) flgChain = _ActionsInHook[new Tuple<IntPtr,ushort>(wParam, lParam.wVk)](); }
                catch (Exception e) { flgChain = true; }
                return flgChain ?  CallNextHookEx(_SHook, nCode, wParam, ref lParam)  : (IntPtr)0x0001;
            }
        }

        public static class EventSender
        {
            private static bool _FlgLBtnDown = false;

            [DllImport("user32.dll")]
            private static extern uint SendInput(uint eventNum, ref  Device inputStrct, int cbSize);

            [StructLayout(LayoutKind.Explicit)]
            private struct Device
            {
                [FieldOffset(0)]
                public int type;
                [FieldOffset(4)]
                public MouseInput mi;
            }

            [StructLayout(LayoutKind.Sequential)]
            private struct MouseInput
            {
                public int x, y;
                public uint mData;      //Wheele or X1 or X2
                public uint dwFlag;         //btn code
                public uint time;           //Event time stamp
                public IntPtr dwExtraInfo;
            }

            public static void LBtnDown()
            {
                if (!_FlgLBtnDown)
                {
                    SendEvent(0x0002);
                    _FlgLBtnDown = true;
                }
            }

            public static void LBtnUp() {
                SendEvent(0x0004);
                _FlgLBtnDown = false;
            }
           
            private static void SendEvent(uint dwFlag)
            {
                var input = new Device();
                input.mi.dwFlag = dwFlag;
                SendInput(1, ref input, Marshal.SizeOf(input));
            }
        }
    }

 


最新の画像もっと見る

2 コメント

コメント日が  古い順  |   新しい順
Unknown (通りすがりバンジョー)
2011-06-25 19:52:34
こんばんわ~
とあるPCゲームで
オンラインしようとしてたら
サービス終了してましたw

そのゲームが新しく出るのか出ないのか
海外メーカーだからさっぱりです
  _、_
( ,_ノ` )y━・~~~
返信する
Unknown (詩鳥)
2011-06-26 23:50:31
自分もそのパターンになって海外の方ではまだサービスが続いてたので、一時期そっちで遊んでマスタ|ω・)且~~
アジア産なら再度出るかもしれませんが、洋ゲーだと絶望的な気ががが。
返信する

コメントを投稿