Már megint egy bejegyzés, ami .NET-es és nem Java-s. Az alábbi kód a "Word" title-lel rendelkező alkalmazáson figyeli az Enter gomb lenyomását.
public class FilterLogic{
public delegate void filteredEvent();
private filteredEvent currentFilteredEvent;
private InfoDelegate infoDelegate;
private Logger logger;
public FilterLogic(InfoDelegate infoDelegate)
{
this.infoDelegate = infoDelegate;
this.logger = new Logger(infoDelegate, "FilterLogic");
}
public void setFilteredEvent(filteredEvent currentFilteredEvent){
this.currentFilteredEvent = currentFilteredEvent;
}
public void filterEnterAndApp(IntPtr a, ref Hook.KBDLLHOOKSTRUCT lParam)
{
//ENTER KEY
if (0X0D == lParam.vkCode)
{
try
{
IntPtr hwnd = APIFuncs.getforegroundWindow();
Int32 pid = APIFuncs.GetWindowProcessID(hwnd);
Process p = Process.GetProcessById(pid);
String appName = p.ProcessName;
String appltitle = APIFuncs.ActiveApplTitle().Trim().Replace("\0", "");
Console.WriteLine(appltitle);
if (appltitle != null && appltitle.Contains("Word"))
{
if (currentFilteredEvent != null)
{
currentFilteredEvent();
}
else
{
logger.logMsg(Logger.WARNINGTYPE, "there is no filteredEvent is set, so no function will be called.");
}
}
}
catch (Exception ex)
{
logger.logException(ex);
}
}
}
}
public static class Hook
{
//Similar class is on this site:
//http://blogs.msdn.com/toub/archive/2006/05/03/589423.aspx
private static class API
{
//dll imports for hooking and unhooking and sending events trough hook hierarchy
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr SetWindowsHookEx(
int idHook,
HookDel lpfn,
IntPtr hMod,
uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UnhookWindowsHookEx(
IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CallNextHookEx(
IntPtr hhk,
int nCode,
IntPtr
wParam,
//IntPtr lParam);
ref KBDLLHOOKSTRUCT lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetModuleHandle(
string lpModuleName);
}
public struct KBDLLHOOKSTRUCT
{
public int vkCode;
int scanCode;
public int flags;
int time;
int dwExtraInfo;
}
public delegate IntPtr HookDel(
int nCode,
IntPtr wParam,
ref KBDLLHOOKSTRUCT lParam);
public delegate void KeyHandler(
IntPtr wParam,
ref KBDLLHOOKSTRUCT lParam);
private static IntPtr hhk = IntPtr.Zero;
private static HookDel hd;
private static KeyHandler kh;
//Creation of the hook
public static void CreateHook(KeyHandler _kh)
{
Console.WriteLine("CreateHook _kh: " + _kh);
Process _this = Process.GetCurrentProcess();
ProcessModule mod = _this.MainModule;
hd = HookFunc;
kh = _kh;
hhk = API.SetWindowsHookEx(13, hd, API.GetModuleHandle(mod.ModuleName), 0);
//13 is the parameter specifying that we're gonna do a low-level keyboard hook
//Console.WriteLine(Marshal.GetLastWin32Error().ToString());
//MessageBox.Show(Marshal.GetLastWin32Error().ToString()); //for debugging
//Note that this could be a Console.WriteLine(), as well. I just happened
//to be debugging this in a Windows Application
}
public static bool DestroyHook()
{
//to be called when we're done with the hook
return API.UnhookWindowsHookEx(hhk);
}
//called when key is active
private static IntPtr HookFunc(
int nCode,
IntPtr wParam,
ref KBDLLHOOKSTRUCT lParam)
{
//Console.WriteLine("nCode=" + nCode);
//Console.WriteLine("wParam=" + wParam);
int iwParam = wParam.ToInt32();
//depending on what you want to detect you can either detect keypressed or keyrealased also with a bit tweaking keyclicked.
if (nCode >= 0 && (iwParam == 0x100 ||
iwParam == 0x104)) //0x100 = WM_KEYDOWN, 0x104 = WM_SYSKEYDOWN
kh(wParam, ref lParam);
return API.CallNextHookEx(hhk, nCode, wParam, ref lParam);
}
}
class APIFuncs
{
#region Windows API Functions Declarations
//This Function is used to get Active Window Title...
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
public static extern int GetWindowText(IntPtr hwnd, string lpString, int cch);
//This Function is used to get Handle for Active Window...
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern IntPtr GetForegroundWindow();
//This Function is used to get Active process ID...
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern Int32 GetWindowThreadProcessId(IntPtr hWnd, out Int32 lpdwProcessId);
#endregion
#region User-defined Functions
public static Int32 GetWindowProcessID(IntPtr hwnd)
{
//This Function is used to get Active process ID...
Int32 pid;
GetWindowThreadProcessId(hwnd, out pid);
return pid;
}
public static IntPtr getforegroundWindow()
{
//This method is used to get Handle for Active Window using GetForegroundWindow() method present in user32.dll
return GetForegroundWindow();
}
public static string ActiveApplTitle()
{
//This method is used to get active application's title using GetWindowText() method present in user32.dll
IntPtr hwnd = getforegroundWindow();
if (hwnd.Equals(IntPtr.Zero)) return "";
string lpText = new string((char)0, 100);
int intLength = GetWindowText(hwnd, lpText, lpText.Length);
if ((intLength <= 0) || (intLength > lpText.Length)) return "unknown";
return lpText.Trim();
}
#endregion
}
A loggertől és az infoDelegate-től tekintsünk el, mindkettő csak a logolást segítette. Beregisztrálni és leregisztrálni a keylistenert a kódban, ahol ezt meg akarjuk tenni, a következőképp lehet:
Hook.CreateHook(new Hook.KeyHandler(filterLogic.filterEnterAndApp));
Hook.DestroyHook();
0 megjegyzés:
Megjegyzés küldése