Home » WPF

Monitor Keys

Hey guys I'm building an application where I need my form to pop up when ctrl+ctrl or some other shortcut is pressed. I need this to happen no matter what window has focus.
Similar to that Google desktop search thing.. which comes preinstalled on Ubuntu.

Soooo do I need to create a service or..?
Could y'all just point me in the right direction? I don't know how to create this type of service.. or any type for that matter.


4 Answers Found


Answer 1

You could google  for keyboard hooks or alternatively try something like this:

Public Class Form1
    Public Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Integer) As Integer
    Dim WithEvents Tmr As New Timer
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Tmr.Interval = 100
    End Sub
    Private Sub Tmr_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Tmr.Tick
        If CBool(GetAsyncKeyState(Keys.ControlKey)) And CBool(GetAsyncKeyState(Keys.E)) Then
            MsgBox("Ctrl - E", MsgBoxStyle.SystemModal)
        End If
    End Sub
End Class

Answer 2

Hi Dylan,

Welcome to VB.NET forums!

You also can have a look at keyboard hook in this scenario.

A hook is a point  in the system message-handling mechanism where an application  can install a subroutine to monitor  the message traffic in the system. This is where certain types of messages will be processed before they reach the target window  procedure.   For a detailed introduction on hooks, please refer to

To set a Windows hook, we call the Windows API SetWindowsHookEx from the user32.dll.   This function installs an application-defined hook procedure in the system hook chain associated with the certain hook type.   We use the Windows API CallNextHookEx from the user32.dll to pass the hook information to the next hook procedure in the current hook chain. The Windows API UnhookWindowsHookEx is used to remove a hook procedure installed in a hook chain by the SetWindowsHookEx function.

In order to set a low level mouse and keyboard hook in VB.NET, we P/Invoke Windows API SetWindowsHookEx, CallNextHookEx, UnhookWindowsHookEx, and GetModuleHandle. 

The first parameter of SetWindowsHookEx specifies the type  of hook procedure to be installed.  Here we use WH_KEYBOARD_LL or WH_MOUSE_LL .  
The second parameter is the pointer to the hook procedure. In C# we pass the delegate of the hook callback function to this parameter.  

The third parameter is the handle of the module containing the hook procedure.  Therefore, we call the GetModuleHandle to retrieve the current module handle of the C# hook application.

The fourth parameter specifies the identifier of the thread with which the hook procedure is to be associated.  If this parameter is zero, the hook procedure is associated with all existing threads running in the same desktop  as the calling thread.

To conclude the hook procedure, we use CallNextHookEx function to pass the hook information to the next hook procedure in the current hook chain.  

When we want to stop the low level mouse or keyboard hook, we can use the UnhookWindowsHookEx function to remove the hook procedure installed. The parameter is the hook ID we get from the SetWindowsHookEx function.

Take a look at following code snippet. I mainly refer to this article . You can also read following articles for your reference.

How to set a Windows hook in Visual C# .NET

Windows Hooks in the .NET Framework

Processing Global Mouse and Keyboard Hooks in C#

Global System Hooks in .NET

Imports System.Runtime.InteropServices
Imports System.Reflection
Imports System.Drawing
Imports System.Threading
Public Class Form1
    'Dim mc As MyHook = New MyHook
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    End Sub
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    End Sub
End Class
Module Keyboard
    <DllImport("kernel32.dll", CharSet:=CharSet.Auto)> _
    Public Function GetModuleHandle(ByVal lpModuleName As String) As IntPtr
    End Function
    Public Declare Function UnhookWindowsHookEx Lib "user32" _
      (ByVal hHook As Integer) As Integer
    Public Declare Function SetWindowsHookEx Lib "user32" _
      Alias "SetWindowsHookExA" (ByVal idHook As Integer, _
      ByVal lpfn As KeyboardHookDelegate, ByVal hmod As IntPtr, _
      ByVal dwThreadId As Integer) As Integer
    Private Declare Function GetAsyncKeyState Lib "user32" _
      (ByVal vKey As Integer) As Integer
    Private Declare Function CallNextHookEx Lib "user32" _
      (ByVal hHook As Integer, _
      ByVal nCode As Integer, _
      ByVal wParam As Integer, _
      ByVal lParam As KBDLLHOOKSTRUCT) As Integer
    Public Structure KBDLLHOOKSTRUCT
        Public vkCode As Integer
        Public scanCode As Integer
        Public flags As Integer
        Public time As Integer
        Public dwExtraInfo As Integer
    End Structure
    ' Low-Level Keyboard Constants
    Private Const HC_ACTION As Integer = 0
    Private Const LLKHF_EXTENDED As Integer = &H1
    Private Const LLKHF_INJECTED As Integer = &H10
    Private Const LLKHF_ALTDOWN As Integer = &H20
    Private Const LLKHF_UP As Integer = &H80
    ' Virtual Keys
    Public Const VK_TAB As Integer = &H9
    Public Const VK_CONTROL As Integer = &H11
    Public Const VK_ESCAPE As Integer = &H1B
    Public Const VK_DELETE As Integer = &H2E
    Private Const WH_KEYBOARD_LL As Integer = 13
    Public KeyboardHandle As Integer
    ' Implement this function to block as many
    ' key combinations as you'd like
    Public Function IsHooked( _
      ByRef Hookstruct As KBDLLHOOKSTRUCT) As Boolean
        Debug.WriteLine("Hookstruct.vkCode: " & Hookstruct.vkCode)
        Debug.WriteLine(Hookstruct.vkCode = VK_ESCAPE)
        Debug.WriteLine(Hookstruct.vkCode = VK_TAB)
        If (Hookstruct.vkCode = VK_ESCAPE) And _
          CBool(GetAsyncKeyState(VK_CONTROL) _
          And &H8000) Then
            Call HookedState("Ctrl + Esc blocked")
            Return True
        End If
        If (Hookstruct.vkCode = VK_TAB) And _
          CBool(Hookstruct.flags And _
          LLKHF_ALTDOWN) Then
            Call HookedState("Alt + Tab blockd")
            Return True
        End If
        If (Hookstruct.vkCode = VK_ESCAPE) And _
          CBool(Hookstruct.flags And _
            LLKHF_ALTDOWN) Then
            Call HookedState("Alt + Escape blocked")
            Return True
        End If
        '' disable PrintScreen here
        If (Hookstruct.vkCode = 44) Then
            Call HookedState("Print blocked")
            Return True
        End If
        Return False
    End Function
    Private Sub HookedState(ByVal Text As String)
    End Sub
    Public Function KeyboardCallback(ByVal Code As Integer, _
      ByVal wParam As Integer, _
      ByRef lParam As KBDLLHOOKSTRUCT) As Integer
        If (Code = HC_ACTION) Then
            Debug.WriteLine("Calling IsHooked")
            If (IsHooked(lParam)) Then
                Return 1
            End If
        End If
        Return CallNextHookEx(KeyboardHandle, _
          Code, wParam, lParam)
    End Function
    Public Delegate Function KeyboardHookDelegate( _
      ByVal Code As Integer, _
      ByVal wParam As Integer, ByRef lParam As KBDLLHOOKSTRUCT) _
                   As Integer
    <MarshalAs(UnmanagedType.FunctionPtr)> _
    Private callback As KeyboardHookDelegate
    Public Sub HookKeyboard(ByRef f As Form)
        callback = New KeyboardHookDelegate(AddressOf KeyboardCallback)
        KeyboardHandle = SetWindowsHookEx(WH_KEYBOARD_LL, callback, GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0)
        Call CheckHooked()
    End Sub
    Public Sub CheckHooked()
        If (Hooked()) Then
            Debug.WriteLine("Keyboard hooked")
            Debug.WriteLine("Keyboard hook failed: " & Err.LastDllError)
        End If
    End Sub
    Private Function Hooked() As Boolean
        Hooked = KeyboardHandle <> 0
    End Function
    Public Sub UnhookKeyboard()
        If (Hooked()) Then
            Call UnhookWindowsHookEx(KeyboardHandle)
        End If
    End Sub
End Module

If you have any further issues, feel free to tell us.

Best regards,

Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.

Answer 3


I was looking to this code that you post to create  a hook.

I have 2 comments:

1) In your function 'IsHooked', What you are saying that you are desabling, is in fact what you are enabling to be processed by the application  that has the hook.

2) in your function KeyboardCallback, you are returning the CallNextHookEx only if the application does not process the hooked key ( this may be what is expected in this case ) but for the futur reader of this thread, if you want the key to be forwarded to the application that has the focus, or to any other application that may have a hook on this key, you need to CallNextHookEx for this.


Answer 4


 Return CallNextHookEx(KeyboardHandle, Code, wParam, lParam)
>> PInvokeStackImbalance was detected
>> Message: A call to PInvoke function
>> 'Utility!Utility.LowLevelKBHook::CallNextHookEx' has unbalanced the
>> stack. This is likely because the managed PInvoke signature does not
>> match the unmanaged target signature. Check that the calling
>> convention and parameters of the PInvoke signature match the target
>> unmanaged signature.


Change ByVal to ByRef => 'ByRef lParam As KBDLLHOOKSTRUCT'.

Search for  Monitor Keys


For any custom dialog (form) in a WinForm application one can set its size and position before displaying it with code such as this:


form.StartPosition = FormStartPosition.Manual;
form.DesktopBounds = MyWindowPosition;

This is particularly important when dealing with multiple monitors. Without such code, when you open a dialog from an application that you have opened on a second monitor, the dialog appears on the primary monitor. This presents a poor user experience.

I would like to know how to do this for standard .NET dialogs, particularly OpenFileDialog and SaveFileDialog (which do not provide a StartPosition property).

I have been looking for a good solution to this for awhile, even posting on other forums some time ago, but have had no success resolving this question.

We developing a netcf 3.5 application  on Windows Mobile 5. We encountered  an Out of Memory Problem during our fieldtests. To identify the critical modules i would like to use the RPM (Version So far the tool works fine until i try to view a GC Heap dump. This causes an exception saying that the problem occurred in mscoree3_5.dll. The monitoring itself works.

Does anyone has an idea what to do or how to get the heap dump working?

Thank you a lot.



The computer has 2 monitors. One is connected to video card by VGA adaptor, the other is connected to video car by DVI adaptor.

Using EnumDisplayDevices(), both the two monitors can be found. But the order is arbitary. By pluging and unpluging the two monitor,

sometimes the VGA monitor is "\\.\DISPLAY1", sometimes it is "\\.\DISPLAY2".

How can I find the VGA monitor with which API?


Thank you very much!








I get the following error when running SQL Server SSMS 2008 (32-bit) on my (Windows 7 64-bit) workstation against our SQL Server 2005 (32-bit) development server running Windows Server 2003 (32-bit):

TITLE: Microsoft SQL Server Management Studio


The Activity Monitor is unable to execute queries against server <my server\instance name>.
Activity Monitor for this instance will be placed into a paused state.
Use the context menu in the overview pane to resume the Activity Monitor.


Unable to find SQL Server process ID 2256 on server VTX-DEV-01 (Microsoft.SqlServer.Management.ResourceMonitoring)


I can expand the panes and all display data except Overview and Data File I/O. This is true for all instances on that server. The SSMS 2005 Activity Monitor (also on my workstation) works fine when connected to that server.

I checked for the registry setting to disable the performance counters on both my machine and the server, and it was not there. I started the Performance Counter DLL Host on my machine, but that made no difference. I can see all Processor counters on the server from my local Performance Monitor. I ran "lodctr /R" on both systems, but that didn't help. The only SQL counters I see on the server (from my workstation) are SQLServer:SSIS Pipeline and SQLServer:SSIS Service.

When I run Perfmon directly on the server, I see dozens number of Performance objects that have 5 digit numbers for names. That may be a part of the problem, but I don't know how to correct that.

I want to detect all the output devices connected to computer and see if the device is monitor or projector. Using EnumDisplayDevices I can get a list of all the display devices but there isn't any way to differentiate between a projector and a monitor.

Hi guys,

I need to write an application that logs the packets sent and received using the sockets created by herself. Is there a simpler way than create a logfile with all the network traffic and then parsing it? I've seen it done by http://www.nirsoft.net/utils/socket_sniffer.html , and I was wondering if it is possible to do it in C# and with Network Monitor API


I have a custom message interceptor  where I'm setting CorrelationManager.ActivityId  which I get from the client everyting works fine for successful method call,but when exception happen new activityid is created and ignored the ActivityId   which I set in the interceptor  and new event is recorded in the DB.All this work if I set the Monitoring to "HealtyMonitoring".

Any help is greatly appreciated.





My recommendation is to follow AdventureWorksxxxx sample databases which use identity surrogates for PRIMARY KEY  and place Unique Index or Unique Key constraint on Natural Key(s).  Example follows from AdventureWorks2008.

CREATETABLE Production.Product(
	Name dbo.Name NOTNULL,		-- UNIQUE INDEX
	ProductNumber nvarchar(25) NOTNULL,	-- UNIQUE INDEX
	MakeFlag dbo.Flag NOTNULL,
	FinishedGoodsFlag dbo.Flag NOTNULL,
	Color nvarchar(15) NULL,
	SafetyStockLevel smallintNOTNULL,
	ReorderPoint smallintNOTNULL,
	StandardCost moneyNOTNULL,
	ListPrice moneyNOTNULL,
	Sizenvarchar(5) NULL,
	SizeUnitMeasureCode nchar(3) NULL,
	WeightUnitMeasureCode nchar(3) NULL,
	Weight decimal(8, 2) NULL,
	DaysToManufacture intNOTNULL,
	ProductLine nchar(2) NULL,
	Class nchar(2) NULL,
	Style nchar(2) NULL,
	ProductSubcategoryID intNULL,
	ProductModelID intNULL,
	SellStartDate datetimeNOTNULL,
	SellEndDate datetimeNULL,
	DiscontinuedDate datetimeNULL,
	rowguid uniqueidentifierROWGUIDCOLNOTNULL, -- UNIQUE INDEX
	ModifiedDate datetimeNOTNULL);

I have a rather frustrating problem in SQL Server Management Studio.  I open Object Explorer and expand the tree down to a table.  I expand the table down to the "Keys" folder.  I right-click on the foreign key and select "Script Key as ... CREATE To" and the key is not scripted.  If I script to "New Query Editor Window", a Query Window opens, but all I see is line numbers 1 and 2.  If I script to "Clipboard", nothing is saved in the Clipboard.  This behavior only happens with "CREATE To".  If I script "DROP To", the DROP statement is scripted.  If I script "DROP And CREATE To", only the DROP statement is scripted.  This is really frustrating.  Has anyone else experienced this behavior?

Following this post, and after finishing development of a healthvaultphp-based sync application, I am failing to create an appropriate certificate to work with my LAMP server.

Creation of the public certificate using makecert on my Windows machine works fine, and I use the "-sv" to get the private certificate. Unfortunately, it is being saved as a binary file and not in the PEM format needed for my PHP application.

I was trying to follow several posts regarding to converting to PEM using openssl, but I always get the following error message:
"31305:error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long:asn1_lib.c:150:"

I can't find any useful information regarding to this error online, and this means I cannot proceed with making my application ready to work.

Please provide me some guidelines regarding on how to get the needed private certificate in the right format.




The infrastructure:
The Service Broker initiator is a SQL Server 2005 Enterprise Mirrored pair (production)
The Service Broker target is a solo SQL Server 2005 Enterprise server (reporting)

The background:
This Service Broker deployment has been successfully running for almost a year.
The mirror principle has switched sides several times over the last year without any problem for Service Broker.

The problem:
Yesterday the principle switched between the servers automatically (overload caused by a backup process), and then back to where it started manually when it was noticed.

The error message:
From that point the messages have been stuck at the Service Broker initiator in the sys.transmission_queue with the error message "The database master key or conversation session keys are unavailable".

The script that starts the dialog does use "WITH ENCRYPTION = OFF"

Sadly, this error message appears to be un-google-able.

What to do?:

The sysadmin says he hasn't made any changes to the master or conversation session keys - and I certainly haven't.

Is this just some sort of corruption of the keys?

Am I safe to just recreate the source and target certificates? I don't want to recreate the Master key as it seems like I've read somewhere that if you do that the in-flight (currently sitting in the transmission queue) conversations are toast.

Should I recreate the certificates on both the initiator and the target? If it is corruption, it should just have effected the initiator (during the mirror switch) - right?

Thanks for any advice!
Jim - of the growing transmission_queue


Hi all,

I am newbie to SQL. I would like to create a table asset table which its would have asset Id as primary key and it will be the Identity (bigint) which cannot be altered by the user but also on the same table another field, asset number, which also a unique key but can be modified by the user. User needs that scenerio to number his assets in a particular order.

Please assist. I am using SQL Express 2005


I have polulated by datagridveiw using dataset. Now I want to generate the primary key colum value (col0) value from the value selected in combo box in col1, col2. Because this use diferent combination I could not assign the autonumber this will create the duplicate value.

Something like this

col0.row1.value = col1.row1.value + col2.row2.value

how could i do this ?





I'm creating an addin for Visual Studio, and I'd like to know whether it's possible to map the Visual Studio key bindings directly to System.Windows.Forms.Keys.

Here are few examples.

Keys.Back to "Bkspce".
Keys.Delete to "Del".
Keys.Insert to "Ins".
Keys.PageDown to "PgDn".
... and so on.

Currently I'm maintaining a fairly complex class that does the transformation, and I wish to get rid of it, any suggestions ? :)


Hi all,

I have know to override the OnBackKeyPress function to handle the back key.

Dose anyone know how to handle the  home key and search key handle problem in WP7?




[MS-NLMP] section 4.2.3 uses NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY, and lists session base key in as

0000000: d8 72 62 b0 cd e4 b1 cb 74 99 be cc cd f1 07 84   .rb.&#x2550;...t.......

and lists the key exchange key in section as

0000000: eb 93 42 9a 8b d9 52 f8 b8 9c 55 b8 7f 47 5e dc   ..B...R...U..G..

Section says that “If NTLM v2 session security is negotiated, the key exchange key MUST be the 128-bit session base key.”

If is correct, should the key exchange key and session base key above be the same?




When I run my old application (written with SQL-DMO) I check if a foreignkey is checked with key.Checked.

In my new application (written with SMO) I check the same thing with key.IsChecked, but in this case it always return false, even in those case where my old application returns true.

Isn't key.Checked and key.IsChecked the same thing? Why do they return diffrent values?

Is there anyway to have an AutoNumber(Primary Key) field ie. list of Employe IDs populate  another List Say Employee Activities, where all entries entered by those Employees would be recorded by use of the Employee ID (as a foreign keys with Duplicates Allowed) using Access 2007  

Hi ,

 I would like to know all the foriegn key references in the db for a table's primary key..How can i get that?


sunil m datla


I am just evaluating Cryptography Application blocks suites our requirement.


We want to use TripleDESCryptoServiceProvider.


We have different Keys/IV in the database. Based about the data which I want to encrypt/decrypt the key/IV is going to change . but as far I know the Cryptography Application block by default can create only one Symmetric key for provider using configuration editor.


Now the question is  there a way we can have multiple Keys/IV in database based upon the data I would like set the key/IV to decrypt/encrypt data.


Please let me know am I clear or not.




<< Previous      Next >>

Microsoft   |   Windows   |   Visual Studio   |   Sharepoint   |   Azure