locked
Перехват аппаратной кнопки (Windows CE 5.0) RRS feed

  • Вопрос

  • Есть навигатор на базе WinCE 5.0, на нем есть аппаратная кнопка ON|OFF.

    В сети Интеренет нашел пример кода - установка ловушки на нажатие кнопки. Адаптировал чтобы видеть действие при нажатии этой аппататной кнопки.

    Вот исходный код:

    using System;
    
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    
    namespace keyhooks
    {
      public partial class Form1 : Form
      {
        UserActivityHook hook = new UserActivityHook();
    
        public Form1()
        {
          InitializeComponent();
        }
    
        private void Form1_Load(object sender, EventArgs e)
        {
          
          hook.HookEvent += new UserActivityHook.HookEventHandler(MyHook);
          hook.Start();
        }
    
        public void MyHook(HookEventArgs e, KeyBoardInfo keyBoardInfo)
        {
          li.Items.Add("Кнопка " + e.Code.ToString() + " /scCODE: " + keyBoardInfo.scanCode.ToString() + " /vkCODE: " + keyBoardInfo.vkCode.ToString() + " /time: " + keyBoardInfo.time.ToString() + " /flag: " + keyBoardInfo.flags.ToString());
          li.Items.Add("   Code: " + e.Code.ToString() +"/Lparam: "+ e.lParam.ToString() + "/Wparam: "+e.wParam.ToString());          
        }
    
        private void Form1_Closing(object sender, CancelEventArgs e)
        {
          hook.Stop();
        }
      }
    
      public class UserActivityHook
      {
        public delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
        public delegate void HookEventHandler(HookEventArgs e, KeyBoardInfo keyBoardInfo);
    
        public event HookEventHandler HookEvent;
    
        private HookProc hookDeleg;
    
        private static int hHook = 0;
    
        public UserActivityHook()
        {
        }
    
        public void Start()
        {
    
          if (hHook != 0)
          {
            //Unhook the previouse one
            this.Stop();
          }
          hookDeleg = new HookProc(HookProcedure);
          hHook = SetWindowsHookEx(WH_KEYBOARD_LL, hookDeleg, GetModuleHandle(null), 0);
    
          if (hHook == 0)
          {
            throw new SystemException("Failed acquiring of the hook.");
          }
        }
    
        /// <summary>
        /// Stop the hook
        /// </summary>
        public void Stop()
        {
          UnhookWindowsHookEx(hHook);
          hHook = 0;
        }
    
        #region protected and private methods
        
        public virtual void OnHookEvent(HookEventArgs hookArgs, KeyBoardInfo keyBoardInfo)
        {
          if (HookEvent != null)
          {
            HookEvent(hookArgs, keyBoardInfo);
          }
        }
    
        private int HookProcedure(int code, IntPtr wParam, IntPtr lParam)
        {
          KBDLLHOOKSTRUCT hookStruct = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT));
          if (code < 0)
            return CallNextHookEx(hookDeleg, code, wParam, lParam);
    
          // Let clients determine what to do
          HookEventArgs e = new HookEventArgs();
          e.Code = code;
          e.wParam = wParam;
          e.lParam = lParam;
    
          KeyBoardInfo keyInfo = new KeyBoardInfo();
          keyInfo.vkCode = hookStruct.vkCode;
          keyInfo.scanCode = hookStruct.scanCode;
    
          OnHookEvent(e, keyInfo);
          hHook = 0;
    
          return CallNextHookEx(hookDeleg, code, wParam, lParam);
        }
    
        #endregion
    
    
    
        #region P/Invoke declarations
    
    
        [DllImport("coredll.dll")]
        private static extern int SetWindowsHookEx(int type, HookProc hookProc, IntPtr hInstance, int m);
    
        [DllImport("coredll.dll")]
        private static extern IntPtr GetModuleHandle(string mod);
    
        [DllImport("coredll.dll")]
        private static extern int CallNextHookEx(HookProc hhk, int nCode, IntPtr wParam, IntPtr lParam);
    
        [DllImport("coredll.dll")]
        private static extern int GetCurrentThreadId();
    
        [DllImport("coredll.dll", SetLastError = true)]
        private static extern int UnhookWindowsHookEx(int idHook);
    
    
    
        private struct KBDLLHOOKSTRUCT
        {
          public int vkCode;
          public int scanCode;
          public int flags;
          public int time;
          public IntPtr dwExtraInfo;
        }
    
        const int WH_KEYBOARD_LL = 20;
        #endregion
    
      }
    
      public class HookEventArgs : EventArgs
      {
        public int Code;  // Hook code
        public IntPtr wParam;  // WPARAM argument
        public IntPtr lParam;  // LPARAM argument
      }
    
      public struct KeyBoardInfo
      {
        public int vkCode;
        public int scanCode;
        public int flags;
        public int time;
    
      }
    }
    
    
    

    Но это программа с формой и ловит она только при активном своем состоянии.

    Подскажите как сделать ловушку вообще в системе, чтобы поместив это в консольное приложение и запустив в фоне она ловила нажатие этой аппаратной кнопки (даже во всех других запущенных программах).

    15 мая 2011 г. 4:52

Ответы

  • ВОПРОС СНИМАЕТСЯ. РЕШЕНИЕ НАЙДЕНО. Для глобального перехвата нажатия аппаратной кнопки нужно ловушку загружать в приложение из DLL-файла.

    Вот текст самой DLL:

    using System;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;
    using System.Text;
    
    namespace hooks
    {
      public class HookEventArgs : EventArgs
      {
        public int Code;  // Hook code
        public IntPtr wParam;  // WPARAM argument
        public IntPtr lParam;  // LPARAM argument
      }
    
      public struct KeyBoardInfo
      {
        public int vkCode;
        public int scanCode;
        public int flags;
        public int time;
      }
    
      public class UserActivityHook
      {
        const int WH_KEYBOARD_LL = 20;
        const int WH_KEYBOARD=2;
    
        private const int WM_KEYDOWN = 0x100;
        private const int WM_KEYUP = 0x101;
        private const int WM_SYSKEYDOWN = 0x104;
        private const int WM_SYSKEYUP = 0x105;
    
        [DllImport("coredll.dll")]
        private static extern int SetWindowsHookEx(int type, HookProc hookProc, IntPtr hInstance, int m);
    
        [DllImport("coredll.dll")]
        private static extern IntPtr GetModuleHandle(string mod);
    
        [DllImport("coredll.dll")]
        private static extern int CallNextHookEx(HookProc hhk, int nCode, IntPtr wParam, IntPtr lParam);
    
        [DllImport("coredll.dll")]
        private static extern int GetCurrentThreadId();
    
        [DllImport("coredll.dll", SetLastError = true)]
        private static extern int UnhookWindowsHookEx(int idHook);
    
        [DllImport("coredll.dll", SetLastError = true)]
        private static extern int GetKeyboardState();
    
    
        private struct KBDLLHOOKSTRUCT
        {
          public int vkCode;
          public int scanCode;
          public int flags;
          public int time;
          public IntPtr dwExtraInfo;
        }
        
        public delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
        public delegate void HookEventHandler(HookEventArgs e, KeyBoardInfo keyBoardInfo);
    
        public event HookEventHandler HookEvent;
        public event HookEventHandler KeyDown;
        public event HookEventHandler KeyUp;
    
        private HookProc hookDeleg;
    
        private static int hHook = 0;
    
        public UserActivityHook() { }
    
        public void Start()
        {
    
          if (hHook != 0)
          {
            this.Stop();
          }
          hookDeleg = new HookProc(HookProcedure);
          hHook = SetWindowsHookEx(WH_KEYBOARD_LL, hookDeleg, GetModuleHandle(null), 0);
    
          if (hHook == 0)
          {
            throw new SystemException("Failed acquiring of the hook.");
          }
        }
    
        public void Stop()
        {
          UnhookWindowsHookEx(hHook);
          hHook = 0;
        }
      
        private int HookProcedure(int code, IntPtr wParam, IntPtr lParam)
        {
          KBDLLHOOKSTRUCT hookStruct = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT));
          if ((code >= 0) && (KeyDown != null || KeyUp != null))
          {
            // Let clients determine what to do
            HookEventArgs e = new HookEventArgs();
            e.Code = code;
            e.wParam = wParam;
            e.lParam = lParam;
    
            KeyBoardInfo keyInfo = new KeyBoardInfo();
            keyInfo.vkCode = hookStruct.vkCode;
            keyInfo.scanCode = hookStruct.scanCode;
    
            if (KeyUp != null && (wParam == (IntPtr)WM_KEYUP || wParam == (IntPtr)WM_SYSKEYUP))
            {
              KeyUp(e, keyInfo);
            }
    
            if (KeyDown != null && (wParam == (IntPtr)WM_KEYDOWN || wParam == (IntPtr)WM_SYSKEYDOWN))
            {
              KeyDown(e, keyInfo);          
            }
    
            //OnHookEvent(e, keyInfo);
            hHook = 0;
          }
          return CallNextHookEx(hookDeleg, code, wParam, lParam);
        }
      }
    
    
    }
    
    

    А вот текст самой программы которая вызывает функцию-обработку ловушки из DLL-файла:

     

    using System;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    using hooks;
    using System.Diagnostics;
    
    namespace keyhooks
    {
      public partial class Form1 : Form
      {
        UserActivityHook hook = new UserActivityHook();
        int a = 0;
        IntPtr hWnd = IntPtr.Zero;
    
        private const int HWND_TOP = 0;
        private const int HWND_BOTTOM = 1;
        private const int HWND_TOPMOST = -1;
        private const int HWND_NOTOPMOST = -2;
        public const int SWP_HIDEWINDOW = 0x0080;
        public const int SWP_SHOWWINDOW = 0x0040;
    
        [DllImport("coredll.dll", SetLastError = true)]
        private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
    
        [DllImport("coredll.dll", EntryPoint = "FindWindowW", SetLastError = true)]
        private static extern IntPtr FindWindowCE(string lpClassName, string lpWindowName);
    
        [DllImport("coredll.dll", SetLastError = true)]
        private static extern int SetWindowLong(IntPtr hWnd, int nIndex);
    
        [DllImport("coredll.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
    
        public Form1()
        {
          InitializeComponent();
        }
    
        private void Form1_Load(object sender, EventArgs e)
        {
          try
          {
            hook.KeyDown += new UserActivityHook.HookEventHandler(MyHookDown);
            hook.KeyUp += new UserActivityHook.HookEventHandler(MyHookUp);
            hook.Start();
          }
          catch
          {
    
          }      
        }
    
        public void MyHookUp(HookEventArgs e, KeyBoardInfo keyBoardInfo)
        {
          timer1.Enabled = false;
          li.Items.Add("UP Button [ vkCODE: " + keyBoardInfo.vkCode.ToString()+" WParam: " + e.wParam.ToString() + " flag: " + keyBoardInfo.flags + " ]");
          a++;
          timer1.Enabled = true;
        }
    
        public void MyHookDown(HookEventArgs e, KeyBoardInfo keyBoardInfo)
        {
          timer1.Enabled = false;
          li.Items.Add("DOWN Button [ vkCODE: " + keyBoardInfo.vkCode.ToString() + " WParam: " + e.wParam.ToString() + " flag: " + keyBoardInfo.flags + " ]");
          a++;
          timer1.Enabled = true;
        }
    
        private void Form1_Closing(object sender, CancelEventArgs e)
        {
          hook.Stop();
        }
    
        private void timer1_Tick(object sender, EventArgs e)
        {
         try
         {  li.Items.Clear();
    
          Process my = new Process();
    
          timer1.Enabled = false;
          if (a > 6)
          {
            // EXIT
            //MessageBox.Show("Кнопка удерживалась более 3 секунд.");
            my.StartInfo.FileName = "\\ResidentFlash2\\MENU\\SOFT\\Power\\Menue.exe";
            my.Start();
            my.WaitForExit();
          }
          
          if (a == 2)
          {
            //HIDE active
            // MessageBox.Show("Кнопка нажата ВСЕГО 1 раз.");
            my.StartInfo.FileName="\\ResidentFlash2\\MENU\\SOFT\\HideAA.exe";
            my.Start();
          }
    
          if (a == 4)
          {
            //Close active
            //MessageBox.Show("Кнопка нажата ВСЕГО 2 раза.");
            my.StartInfo.FileName="\\ResidentFlash2\\MENU\\SOFT\\CloseAA.exe";
            my.Start();
          }
    
          if (a == 6)
          {
            //TC
            //MessageBox.Show("Кнопка нажата ВСЕГО 3 раза.");
            my.StartInfo.FileName="\\ResidentFlash2\\MENU\\SOFT\\task.exe";
            my.Start();
          }
        }
          catch
          {
          
          }
    
          a = 0;
        }
    
        private void button1_Click_1(object sender, EventArgs e)
        {
          Application.Exit();
        }
    
        private void timer2_Tick(object sender, EventArgs e)
        {
          timer2.Enabled = false;
          
          IntPtr handle;
          try
          {
            handle = FindWindowCE(null, "keyhooks");
            if (handle != IntPtr.Zero)
            {
              SetWindowPos(handle, IntPtr.Zero, 0, 0, 5, 5, SWP_HIDEWINDOW);
            }
          }
          catch { }
        }
      }  
    }
    
    
    

    После запуска вызываюшей программы ее форма прячется с панели задач. И программа висит в фоне и глобально отлавливает нажатия аппаратной кнопки:

    1 раз - запускает приложение 1

    2 раза - запускает приложение 2

    3 раза - запускает приложение 3

    Длительное нажатие (свыше 3 секунд) .

    • Помечено в качестве ответа PNA_nsk 16 мая 2011 г. 16:44
    16 мая 2011 г. 16:43