2009-07-21 12 views
9

Es. con winamp (almeno su Windows), puoi giocare a schermo intero con Winamp in background e utilizzare i pulsanti multimediali * per controllare il suono. Winamp non ha bisogno di mettere a fuoco, permettendo al gioco di continuare a schermo intero.Cattura di sequenze di tasti senza messa a fuoco

Preferisco scrivere questo in Java ma probabilmente non funzionerà (l'acquisizione di sequenze di tasti senza messa a fuoco è già difficile in Java afaik), quindi anche qualsiasi soluzione C# va bene.

Quindi la domanda di base è: come acquisire sequenze di tasti senza messa a fuoco?

*) Credo che i pulsanti "indietro/avanti/stop/mail/ricerca/preferiti/web/home" siano chiamati pulsanti multimediali, ma un nome migliore sarebbe il benvenuto :).

+0

li pulsanti multimediali o tasti multimediali chiamo troppo, non conosci un nome migliore – Luc

risposta

7

I ganci per finestre di basso livello sono un modo per farlo. Ecco uno article e qui c'è un po 'più di informazioni da MSDN.

Questa è una visione parziale di ciò che il codice può essere simile:

private IntPtr LowLevelKeyboardHook(int nCode, WindowsMessages wParam, [In] KBDLLHOOKSTRUCT lParam) 
    { 
     bool callNext = true; 

     bool isKeyDown = (wParam == WindowsMessages.KEYDOWN || wParam == WindowsMessages.SYSKEYDOWN); 
     bool isKeyUp = (wParam == WindowsMessages.KEYUP || wParam == WindowsMessages.SYSKEYUP); 

     if ((nCode >= 0) && (isKeyDown || isKeyUp)) 
     { 
      // the virtual key codes and the winforms Keys have the same enumeration 
      // so we can freely cast back and forth between them 
      Keys key = (Keys)lParam.vkCode; 

      // Do your other processing here... 
     } 

     // if any handler returned false, trap the message 
     return (callNext) ? User32.CallNextHookEx(_mainHook, nCode, wParam, lParam) : _nullNext; 
    } 


    /// <summary> 
    /// Registers the user's LowLevelKeyboardProc with the system in order to 
    /// intercept any keyboard events before processed in the regular fashion. 
    /// This can be used to log all keyboard events or ignore them. 
    /// </summary> 
    /// <param name="hook">Callback function to call whenever a keyboard event occurs.</param> 
    /// <returns>The IntPtr assigned by the Windows's sytem that defines the callback.</returns> 
    private IntPtr RegisterLowLevelHook(LowLevelKeyboardProc hook) 
    { 
     IntPtr handle = IntPtr.Zero; 

     using (Process currentProcess = Process.GetCurrentProcess()) 
     using (ProcessModule currentModule = currentProcess.MainModule) 
     { 
      IntPtr module = Kernel32.GetModuleHandle(currentModule.ModuleName); 
      handle = User32.SetWindowsHookEx(HookType.KEYBOARD_LL, hook, module, 0); 
     } 

     return handle; 
    } 

    /// <summary> 
    /// Unregisters a previously registered callback from the low-level chain. 
    /// </summary> 
    /// <param name="hook">IntPtr previously assigned to the low-level chain. 
    /// Users should have stored the value given by 
    /// <see cref="Drs.Interop.Win32.LowLevelKeyboard.RegisterLowLevelHook"/>, 
    /// and use that value as the parameter into this function.</param> 
    /// <returns>True if the hook was removed, false otherwise.</returns> 
    private bool UnregisterLowLevelHook(IntPtr hook) 
    { 
     return User32.UnhookWindowsHookEx(hook); 
    } 

Basta attuare tutte le P/Invoke dichiarazioni necessario, e dovrebbe funzionare. Io uso questo approccio nella mia applicazione e funziona perfettamente.

+0

Questi tipi non sono riconosciuti sulla mia applicazione e non compila (WindowsMessages, User32 etc ...) cosa hai fatto per farlo funzionare? hai questo codice online ovunque per caso? –

+1

No, quelle sono le dichiarazioni che dovresti dichiarare. Non ho quel codice online, ma puoi creare semplici stub usando le firme P/Invoke da http://www.pinvoke.net. –

+0

qual è la variabile _nullNext? –

Problemi correlati