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;
}
No comments:
Post a Comment