Gå til innhold

Anbefalte innlegg

Forsøker å få informasjon om hvor musepekeren er og om noen taster holdes nede. Ikke bare innenfor programmet mitt, men på hele skjermen.

 

Har da kommer borti windows hooks, og det viser seg at globale hooks må over i en .dll så vidt jeg skjønner.

Det er forsåvidt greit nok, men da må jeg lære meg noe nytt. :)

 

Er det ikke mulig å gjøre dette direkte i C#?

Lenke til kommentar
Videoannonse
Annonse

Under Windows Forms har du Cursor.Position (og Controls.MousePosition). For å fortelle hvor musepekeren er uansett kan du bruke GlobalHotKeys som er en del enklere å jobbe med, og sikrere enn window hooks. Du finner masse ferdigskrevne klassee for dette med gewgle.

 

Nydelig. har ikke hørt om dette før. takk.

Lenke til kommentar

Under Windows Forms har du Cursor.Position (og Controls.MousePosition). For å fortelle hvor musepekeren er uansett kan du bruke GlobalHotKeys som er en del enklere å jobbe med, og sikrere enn window hooks. Du finner masse ferdigskrevne klassee for dette med gewgle.

 

Nydelig. har ikke hørt om dette før. takk.

 

Her er en fin løsning på globale hotkeys:

http://www.liensberger.it/web/blog/?p=207

Lenke til kommentar
  • 4 uker senere...

Til info: Globale hooks må IKKE på egen DLL. Du skal kunne skrive alt i .Net.

 

Her er en hook klasse jeg skrev en gang i tiden. Jeg bruker den en gang i blant i spill for å force keybindings jeg ikke ellers får til. Lytter på min Key. Trykker en annen.

 

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApplication1 {
   public class KeyboardHook : IDisposable {
       bool Global = false;

       #region DllImports and func delegate

       public delegate void LocalKeyEventHandler(Keys key);
       public event LocalKeyEventHandler KeyDown;
       public event LocalKeyEventHandler KeyUp;

       public delegate int CallbackDelegate(int Code, int W, int L);

       //Structure returned by a WH_KEYBOARD_LL hook
       [structLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
       public struct KBDLLHookStruct {
           public Int32 vkCode;
           public Int32 scanCode;
           public Int32 flags;
           public Int32 time;
           public Int32 dwExtraInfo;
       }

       [DllImport("user32", CallingConvention = CallingConvention.StdCall)]
       private static extern int SetWindowsHookEx(HookType idHook, CallbackDelegate lpfn, int hInstance, int threadId);

       [DllImport("user32", CallingConvention = CallingConvention.StdCall)]
       private static extern bool UnhookWindowsHookEx(int idHook);

       [DllImport("user32", CallingConvention = CallingConvention.StdCall)]
       private static extern int CallNextHookEx(int idHook, int nCode, int wParam, int lParam);

       [DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall)]
       private static extern int GetCurrentThreadId();

       //Used to find HWND to user32.dll
       [DllImport("kernel32")]
       public extern static int LoadLibrary(string lpLibFileName);

       public enum HookType : int {
           WH_JOURNALRECORD = 0,
           WH_JOURNALPLAYBACK = 1,
           WH_KEYBOARD = 2,
           WH_GETMESSAGE = 3,
           WH_CALLWNDPROC = 4,
           WH_CBT = 5,
           WH_SYSMSGFILTER = 6,
           WH_MOUSE = 7,
           WH_HARDWARE = 8,
           WH_DEBUG = 9,
           WH_SHELL = 10,
           WH_FOREGROUNDIDLE = 11,
           WH_CALLWNDPROCRET = 12,
           WH_KEYBOARD_LL = 13,
           WH_MOUSE_LL = 14
       }

       #endregion

       #region Constructor & Destructor

       private int HookID = 0;
       CallbackDelegate TheHookCB = null;


       //Start hook
       public KeyboardHook(bool Global) {
           this.Global = Global;
           int hInstance = LoadLibrary("User32");
           TheHookCB = new CallbackDelegate(KeybHookProc);
           if (Global) {
               HookID = SetWindowsHookEx(HookType.WH_KEYBOARD_LL, TheHookCB,
                   hInstance, //0 for local hook. eller hwnd til user32 for global
                   //0 istedet for hInstance rett over mener jeg funker fint i Windows 7 i hvertfall, men måtte bruke hInstance når jeg testet på Win XP.
                   0); //0 for global hook. eller thread for hooken
           } else {
               HookID = SetWindowsHookEx(HookType.WH_KEYBOARD, TheHookCB,
                   0, //0 for local hook. eller hwnd til user32 for global
                   GetCurrentThreadId()); //0 for global hook. eller thread for hooken
           }
       }

       bool IsFinalized = false;
       ~KeyboardHook() {
           if (!IsFinalized) {
               UnhookWindowsHookEx(HookID);
               IsFinalized = true;
           }
       }
       public void Dispose() {
           if (!IsFinalized) {
               UnhookWindowsHookEx(HookID);
               IsFinalized = true;
           }
       }


       #endregion

       #region Callback Handler




       //The listener that will trigger events
       private int KeybHookProc(int Code, int W, int L) {
           KBDLLHookStruct LS = new KBDLLHookStruct();
           if (Code < 0) { //Sendes code 3 og code 0 med samme info
               return CallNextHookEx(HookID, Code, W, L);
           }
           try {
               if (!Global) {
                   if (Code == 3) { //Sendes code 3 og code 0 med samme info
                       IntPtr ptr = IntPtr.Zero;

                       int keydownup = L >> 30;
                       if (keydownup == 0) {
                           if (KeyDown != null) KeyDown((Keys)W);
                       }
                       if (keydownup == -1) {
                           if (KeyUp != null) KeyUp((Keys)W);
                       }
                       if (keydownup == 1) {
                           //if (KeyHold != null) KeyHold((Keys)wParam);
                       }

                       System.Diagnostics.Debug.WriteLine("Down: " + (Keys)W);
                   }
               } else {
                   KeyEvents kEvent = (KeyEvents)W;

                   Int32 vkCode = Marshal.ReadInt32((IntPtr)L); //Leser vkCode som er de første 32 bits hvor L peker.

                   if (kEvent != KeyEvents.KeyDown && kEvent != KeyEvents.KeyUp && kEvent != KeyEvents.SKeyDown && kEvent != KeyEvents.SKeyUp) {
                   }
                   if (kEvent == KeyEvents.KeyDown || kEvent == KeyEvents.SKeyDown) {
                       if (KeyDown != null) KeyDown((Keys)vkCode);
                   }
                   if (kEvent == KeyEvents.KeyUp || kEvent == KeyEvents.SKeyUp) {
                       if (KeyUp != null) KeyUp((Keys)vkCode);
                   }
               }
           } catch (Exception) {
               //Ignorer feil. Kan ikke ødelegge løkken
           }

           return CallNextHookEx(HookID, Code, W, L);

       }

       public enum KeyEvents {
           KeyDown = 0x0100,
           KeyUp = 0x0101,
           SKeyDown = 0x0104,
           SKeyUp = 0x0105
       }


       #endregion


   }
}

 

 

 

Denne koden er enkel for å bare sjekke om en tast er trykket (ikke hendelses-drevet):

 

       [DllImport("user32.dll")]
       static public extern short GetKeyState(System.Windows.Forms.Keys nVirtKey);

       public static bool GetCapslock() {	
           return Convert.ToBoolean(GetKeyState(System.Windows.Forms.Keys.CapsLock)) & true;
       }
       public static bool GetNumlock() { 
           return Convert.ToBoolean(GetKeyState(System.Windows.Forms.Keys.NumLock)) & true;
       }
       public static bool GetScrollLock() { 
           return Convert.ToBoolean(GetKeyState(System.Windows.Forms.Keys.Scroll)) & true;
       }
       public static bool GetShiftPressed() {
           int state = GetKeyState(System.Windows.Forms.Keys.ShiftKey);
           if (state > 1 || state < -1) return true;
           return false;
       }
       public static bool GetCtrlPressed() { 
           int state = GetKeyState(System.Windows.Forms.Keys.ControlKey);
           if (state > 1 || state < -1) return true;
           return false;
       }
       public static bool GetAltPressed() { 
           int state = GetKeyState(System.Windows.Forms.Keys.Menu);
           if (state > 1 || state < -1) return true;
           return false;
       }

 

 

Eksempel bruk på keyboardhooken:

 

       [sTAThread]
       static void Main() {
           var hk = new KeyboardHook(true);
           hk.KeyDown+=(k)=>{
               MessageBox.Show("Du klikket: " + k.ToString());
           };
           Application.Run();
       }

Endret av wolf5
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...