tags:

views:

244

answers:

1

I asked a question earlier about keyhooks in vb.net.

My current issue is such:

I have created a program which should perform a certain action whenever a certain group of keys is pressed at the same time. The program must be able to run in the background, or in the system tray or something. Essentially, this should work like the KeyDown event on a form, except the form in this case is everything.

I'm not certain if there is a way to do this directly from within the .net API, but if there is I certainly have not found it.

+1  A: 

That doesn't require a keyboard hook, you'll want to register a hot key. Much easier to implement and much less demanding of system resources. Here's an example, it restores the form to the foreground if it was minimized. Note that you can register more than one key:

Imports System.Runtime.InteropServices
Imports System.ComponentModel

Public Class Form1
  Private Const cHotKeyId As Integer = 0

  Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
    '--- Register Ctrl + Shift + U as a hot key
    If Not RegisterHotKey(Me.Handle, cHotKeyId, MOD_CONTROL + MOD_SHIFT, Keys.U) Then
      Throw New Win32Exception()
    End If
    MyBase.OnLoad(e)
  End Sub

  Protected Overrides Sub OnFormClosing(ByVal e As System.Windows.Forms.FormClosingEventArgs)
    UnregisterHotKey(Me.Handle, cHotKeyId)
    MyBase.OnFormClosing(e)
  End Sub

  Protected Overrides Sub WndProc(ByRef m As Message)
    Console.WriteLine(m.ToString())
    If (m.Msg = WM_HOTKEY AndAlso m.WParam = CType(cHotKeyId, IntPtr)) Then
      Me.Visible = True
      If Me.WindowState = FormWindowState.Minimized Then Me.WindowState = FormWindowState.Normal
      SetForegroundWindow(Me.Handle)
    End If
    MyBase.WndProc(m)
  End Sub

  '--- P/Invoke declarations
  Private Const WM_HOTKEY As Integer = &H312
  Private Const MOD_ALT As Integer = &H1
  Private Const MOD_CONTROL As Integer = &H2
  Private Const MOD_SHIFT As Integer = &H4
  Private Declare Function RegisterHotKey Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal id As Integer, ByVal fsModifier As Integer, ByVal vk As Integer) As Boolean
  Private Declare Function UnregisterHotKey Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal id As Integer) As Boolean
  Private Declare Function SetForegroundWindow Lib "user32.dll" (ByVal hWnd As IntPtr) As Boolean

End Class
Hans Passant
I only want it to activate if the application is running, not if the app is NOT running. (is there some way to do that with your code?) And no, I don't want a keyboard hook, I'd prefer the actual KeyDown events.
Cyclone
Still, either way it does essentially what I want, +1. I'll leave the question open still in case you or someone else can give something that fits what I want exactly.
Cyclone
Erm, this will only work if the app is running. If you want something else then you'll have to explain your requirements better.
Hans Passant
I'm sorry, I misunderstood your code. I thought it actually RAN the app if it was not running. What you suggest here looks good, I'll give it a shot.
Cyclone
Works great, that code is simple and easy to use.
Cyclone