Showing posts with label Keyboard Listener. Show all posts
Showing posts with label Keyboard Listener. Show all posts

Tuesday, January 12, 2010

Keyboard Listener in WPF

Key board message Hooking in WPF, using C++/CLI

KeyboardListener.h
==================
#pragma once

using namespace System;
using namespace System::Diagnostics;
using namespace System::Runtime::InteropServices;
using namespace System::Runtime::CompilerServices;
using namespace System::Windows::Input;
using namespace System::Windows::Interop;

public ref class CKeyboardListener : System::IDisposable
{

public:
CKeyboardListener(void);
~CKeyboardListener(void);

public:
delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
static LowLevelKeyboardProc^ m_pLowLevelKeyboardProc;

public:
void DisposeHook(void);
static IntPtr SetHook( LowLevelKeyboardProc^ pLowLevelKeyboardProc );
static IntPtr GetWindowHandle(System::Windows::Window^ window );
static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam);

private:
static const int WH_KEYBOARD_LL = 13;
static const int WM_KEYDOWN = 0x0100;
static System::IntPtr m_hookID = IntPtr::Zero;

public :
[DllImport("user32.dll", CharSet = CharSet::Auto, SetLastError = true)]
static IntPtr SetWindowsHookEx(int idHook,LowLevelKeyboardProc^ lpfn, System::IntPtr hMod, unsigned int dwThreadId);

[DllImport("user32.dll", CharSet = CharSet::Auto, SetLastError = true)]
//[return: MarshalAs(UnmanagedType::Bool)]
static bool UnhookWindowsHookEx(System::IntPtr hhk);

[DllImport("user32.dll", CharSet = CharSet::Auto, SetLastError = true)]
static System::IntPtr CallNextHookEx(System::IntPtr hhk, int nCode,
System::IntPtr wParam, System::IntPtr lParam);

[DllImport("kernel32.dll", CharSet = CharSet::Auto, SetLastError = true)]
static IntPtr GetModuleHandle(System::String^ lpModuleName);

[ DllImport("user32.dll") ]
static IntPtr GetForegroundWindow();
};

KeyboardListener.cpp
================
#include "KeyboardListener.h"
#include "MainApp.h"

CKeyboardListener::CKeyboardListener(void)
{
m_pLowLevelKeyboardProc = gcnew LowLevelKeyboardProc( &CKeyboardListener::HookCallback);
m_hookID = SetHook( m_pLowLevelKeyboardProc );
}

CKeyboardListener::~CKeyboardListener(void)
{

}

void CKeyboardListener::DisposeHook(void)
{
UnhookWindowsHookEx( m_hookID );
}

IntPtr CKeyboardListener::SetHook(LowLevelKeyboardProc^ pLowLevelKeyboardProc)
{
Process^ curProcess = nullptr;
ProcessModule^ curModule = nullptr;

while( curProcess = Process::GetCurrentProcess() )
{
while( curModule = curProcess->MainModule )
{
return SetWindowsHookEx(WH_KEYBOARD_LL, pLowLevelKeyboardProc,
GetModuleHandle(curModule->ModuleName), 0);
}
}

return System::IntPtr::Zero;
}

IntPtr CKeyboardListener::GetWindowHandle(System::Windows::Window^ window )
{
System::Windows::Interop::WindowInteropHelper^ pWindow;
pWindow = gcnew System::Windows::Interop::WindowInteropHelper(window);
return pWindow->Handle;
}

IntPtr CKeyboardListener::HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
int l_nWindowCnt = 0;
System::IntPtr l_hForeGndWnd = GetForegroundWindow();
MainApp^ l_pCurApp = (MainApp^) Application::Current;
int l_nVirtualKeyCode = 0;

l_nVirtualKeyCode = Marshal::ReadInt32(lParam);

if ( l_nVirtualKeyCode == 112 ) //If F1 key
{
for each (Window^ hWindow in l_pCurApp->Windows)
{
++l_nWindowCnt;

System::IntPtr l_hWindow = GetWindowHandle(hWindow);

if ( l_hForeGndWnd == l_hWindow )
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
((MainScreen^)l_pCurApp->mainwnd)->LoadHelp(); //Call the LoadHelp function from MainScreen class
return CallNextHookEx( m_hookID, nCode, wParam, lParam);
}
}
}
}

return System::IntPtr::Zero;
}


And in MainApp.cpp we create an instance of the class "CKeyboardListener"

void MainApp::OnStartup( System::Windows::StartupEventArgs^ e )
{
Application::OnStartup(e);
mainwnd = gcnew MainScreen(ResourceAssembly->Location);
m_pKeyboardListener = gcnew CKeyboardListener(); //Start the key board hooking

mainwnd->Show();
}

void MainApp::OnExit( System::Windows::ExitEventArgs^ e )
{
m_pKeyboardListener->DisposeHook();
m_pKeyboardListener = nullptr;
}