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

top