Managed Debugging Assistant 'CallbackOnCollectedDelegate' : C# windows form - c#

I m developing a Multi choices Exam System and needed to disable all the keyboard and just use mouse click, but I got this issue
A callback was made on a garbage collected delegate of type
'UI!UI.Forms.frmExamHome+LowLevelKeyboardProcDelegate::Invoke'. This
may cause application crashes, corruption and data loss. When passing
delegates to unmanaged code, they must be kept alive by the managed
application until it is guaranteed that they will never be called.'
My code:
void wniDisable()
{
intLLKey = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]).ToInt32(), 0);
}
[DllImport("user32", EntryPoint = "SetWindowsHookExA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern int SetWindowsHookEx(int idHook, LowLevelKeyboardProcDelegate lpfn, int hMod, int dwThreadId);
[DllImport("user32", EntryPoint = "UnhookWindowsHookEx", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern int UnhookWindowsHookEx(int hHook);
public delegate int LowLevelKeyboardProcDelegate(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);
[DllImport("user32", EntryPoint = "CallNextHookEx", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern int CallNextHookEx(int hHook, int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);
public const int WH_KEYBOARD_LL = 13;
/*code needed to disable start menu*/
[DllImport("user32.dll")]
private static extern int FindWindow(string className, string windowText);
[DllImport("user32.dll")]
private static extern int ShowWindow(int hwnd, int command);
private const int SW_HIDE = 0;
private const int SW_SHOW = 1;
public struct KBDLLHOOKSTRUCT
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}
public static int intLLKey;
public int LowLevelKeyboardProc(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam)
{
bool blnEat = false;
switch (wParam)
{
case 256:
case 257:
case 260:
case 261:
//Alt+Tab, Alt+Esc, Ctrl+Esc, Windows Key,
blnEat = ((lParam.vkCode == 9) && (lParam.flags == 32)) | ((lParam.vkCode == 27) && (lParam.flags == 32)) | ((lParam.vkCode == 27) && (lParam.flags == 0)) | ((lParam.vkCode == 91) && (lParam.flags == 1)) | ((lParam.vkCode == 92) && (lParam.flags == 1)) | ((lParam.vkCode == 73) && (lParam.flags == 0));
break;
}
if (blnEat == true)
{
return 1;
}
else
{
return CallNextHookEx(0, nCode, wParam, ref lParam);
}
}
public void KillStartMenu()
{
int hwnd = FindWindow("Shell_TrayWnd", "");
ShowWindow(hwnd, SW_HIDE);
}

You need to store the hook delegate as class member or the delegate instance will be method local and be garbage collected after you have left the method.
Check out https://github.com/Alois-xx/etwcontroller/blob/master/ETWController/Hooking/Hooker.cs
for a working sample.
class Hooker : IDisposable
{
int MouseHookHandle;
int KeyboardHookHandle;
HookProc MouseHookGCRootedDelegate;
HookProc KeyboardHookGCRootedDelegate;
..
public Hooker()
{
// HookEvents.RegisterItself();
MouseHookGCRootedDelegate = MouseHook;
KeyboardHookGCRootedDelegate = KeyboardHook;
}
void HookKeyboard(bool bHook)
{
if (KeyboardHookHandle == 0 && bHook)
{
using (var mainMod = Process.GetCurrentProcess().MainModule)
KeyboardHookHandle = HookNativeDefinitions.SetWindowsHookEx(HookNativeDefinitions.WH_KEYBOARD_LL, KeyboardHookGCRootedDelegate, HookNativeDefinitions.GetModuleHandle(mainMod.ModuleName), 0);
//If the SetWindowsHookEx function fails.
if (KeyboardHookHandle == 0)
{
System.Windows.MessageBox.Show("SetWindowsHookEx Failed " + new Win32Exception(Marshal.GetLastWin32Error()));
return;
}
}
else if(bHook == false)
{
Debug.Print("Unhook keyboard");
HookNativeDefinitions.UnhookWindowsHookEx(KeyboardHookHandle);
KeyboardHookHandle = 0;
}
}

Related

Every other window freezes after replacing mouse action - c#

I'm writing an application that binds custom actions to my mouse buttons. For example, I connected the volume up to one of the thumb buttons. Everything works fine as long as I stay in one window because every other windows and the taskbar seems to freeze and it will take some time before the windows are activated again or if I kill my application or the window I am working in.
In the code below I capture the mouse events and check with the settings in the application if the button action is still default or if it has changed. If the action has changed, then the application should for example turn the volume up with two.
[DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(string name);
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
public static bool usingKeyboard = false;
public static bool leftButtonDown = false;
static int hMHook;
public const int WH_MOUSE_LL = 14;
//Declare MouseHookProcedure as a HookProc type.
static HookProc MouseHookProcedure;
private enum MouseMessages
{
WM_LBUTTONDOWN = 0x0201,
WM_LBUTTONUP = 0x0202,
WM_MOUSEMOVE = 0x0200,
WM_MOUSEWHEEL = 0x020A,
WM_RBUTTONDOWN = 0x0204,
WM_RBUTTONUP = 0x0205,
WM_XBUTTONDOWN = 0x020B,
WM_XBUTTONUP = 0x020C,
WM_MBUTTONUP = 0x0208,
WM_MBUTTONDOWN = 0x0207
}
[StructLayout(LayoutKind.Sequential)]
public class POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
public class MouseHookStruct
{
public POINT pt;
public int hwnd;
public int wHitTestCode;
public int dwExtraInfo;
}
[DllImport("kernel32.dll")]
static extern uint GetLastError();
[DllImport("user32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn,
IntPtr hInstance, int threadId);
[DllImport("user32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
[DllImport("user32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode,
IntPtr wParam, IntPtr lParam);
private int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));
MouseUsageMessage message = new MouseUsageMessage(1);
MouseUsageManager.mouseUsageMessageQueue.Add(message);
if (nCode >= 0)
{
if (MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam)
{
leftButtonDown = true;
} else if (MouseMessages.WM_LBUTTONUP == (MouseMessages)wParam)
{
leftButtonDown = false;
} else if (MouseMessages.WM_RBUTTONDOWN == (MouseMessages)wParam)
{
} else if (MouseMessages.WM_RBUTTONUP == (MouseMessages) wParam) {
} else if (MouseMessages.WM_XBUTTONUP == (MouseMessages)wParam)
{
switch (MyMouseHookStruct.hwnd)
{
case 65536:
if (Settings.Default.thumbClick1User != Settings.Default.thumbClick1Default)
{
ExecuteAction(Settings.Default.thumbClick1User);
return 1;
}
break;
case 131072:
if (Settings.Default.thumbClick2User != Settings.Default.thumbClick2Default)
{
ExecuteAction(Settings.Default.thumbClick2User);
return 1;
}
break;
}
} else if (MouseMessages.WM_MBUTTONDOWN == (MouseMessages)wParam)
{
}
}
return CallNextHookEx(hMHook, nCode, wParam, lParam);
}
Why are the other windows freezing or why can't I use my mouse on the other windows after I've clicked the thumb buttons?
EDIT: Additional code
private void ExecuteAction(string setting)
{
VolumeControl vc = new VolumeControl();
Keybindings kb = new Keybindings();
switch (setting)
{
case "volUp":
vc.VolUp();
break;
case "volDown":
vc.VolDown();
break;
case "cut":
kb.Cut();
break;
case "selectAll":
kb.SelectAll();
break;
case "copy":
kb.Copy();
break;
default:
break;
}
}
The setting string that is sended to the ExecuteAction function is just a string with the action to be performed, i.e. copy, volume up, volume down etc.
VolumeControl class:
public class VolumeControl
{
private const int APPCOMMAND_VOLUME_MUTE = 0x80000;
private const int APPCOMMAND_VOLUME_UP = 0xA0000;
private const int APPCOMMAND_VOLUME_DOWN = 0x90000;
private const int WM_APPCOMMAND = 0x319;
IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;
[DllImport("user32.dll")]
public static extern IntPtr SendMessageW(IntPtr hWnd, int Msg,
IntPtr wParam, IntPtr lParam);
public void VolDown()
{
SendMessageW(handle, WM_APPCOMMAND, handle,
(IntPtr)APPCOMMAND_VOLUME_DOWN);
}
public void VolUp()
{
SendMessageW(handle, WM_APPCOMMAND, handle,
(IntPtr)APPCOMMAND_VOLUME_UP);
}
}
Create Hook function, the function that is called when the class is initialized:
private void createHook()
{
while (hMHook == 0) //|| hKHook == 0)
{
//if (hMHook == 0)
//{
//hMHook = SetWindowsHookEx(WH_MOUSE_LL,
//MouseHookProcedure,
//GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName),
//(IntPtr)0,
//0);
//}
if (hMHook == 0)
{
hMHook = SetWindowsHookEx(WH_MOUSE_LL,
MouseHookProcedure,
GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName),
0);
}
if (hMHook == 0) //|| hKHook == 0)
{
Console.WriteLine("SetWindowsHookEx Failed");
return;
}
Console.WriteLine("Hooked");
}
}
My solution, i have built a simple console project
when you launch program, the hook is activated, and you can toggle with middle mouse button. the right button up and letf button up play with system volume..
the main program:
using HookInput.API;
using HookInput.Mouse;
using System;
using System.Diagnostics;
using System.Windows.Forms;
namespace ConsoleApp3
{
public class Program
{
private static MouseInput mouseInputHook = null;
static void Main(string[] args)
{
var vc = new VolumeControl();
mouseInputHook = new MouseInput(vc);
mouseInputHook.setHook(true);
Console.WriteLine("hook activated");
Application.Run(new ApplicationContext());
}
}
public class VolumeControl
{
private const int APPCOMMAND_VOLUME_MUTE = 0x80000;
private const int APPCOMMAND_VOLUME_UP = 0xA0000;
private const int APPCOMMAND_VOLUME_DOWN = 0x90000;
private const int WM_APPCOMMAND = 0x319;
public IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;
public void VolDown()
{
WindowsHookAPI.SendMessageW(handle, WM_APPCOMMAND, handle, (IntPtr)APPCOMMAND_VOLUME_DOWN);
}
public void VolUp()
{
WindowsHookAPI.SendMessageW(handle, WM_APPCOMMAND, handle, (IntPtr)APPCOMMAND_VOLUME_UP);
}
}
}
the APIs:
using System;
using System.Runtime.InteropServices;
namespace HookInput.API
{
public class WindowsHookAPI
{
//public delegate IntPtr HookDelegate(
// Int32 Code, IntPtr wParam, IntPtr lParam);
public delegate IntPtr HookDelegate(Int32 Code, IntPtr wParam, IntPtr lParam);
[DllImport("User32.dll")]
public static extern IntPtr CallNextHookEx(IntPtr hHook, Int32 nCode, IntPtr wParam, IntPtr lParam);
[DllImport("User32.dll")]
public static extern IntPtr UnhookWindowsHookEx(IntPtr hHook);
[DllImport("User32.dll")]
public static extern IntPtr SetWindowsHookEx(Int32 idHook, HookDelegate lpfn, IntPtr hmod, Int32 dwThreadId);
[DllImport("user32.dll")]
public static extern IntPtr SendMessageW(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
}
}
the hook and structures:
using HookInput.API;
using System;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;
using ConsoleApp3;
namespace HookInput.Mouse
{
public class MouseInput
{
private const Int32 WM_MOUSEMOVE = 0x0200;
private const Int32 WM_LBUTTONDOWN = 0x0201;
private const Int32 WM_LBUTTONUP = 0x0202;
private const Int32 WM_LBUTTONDBLCLK = 0x0203;
private const Int32 WM_RBUTTONDOWN = 0x0204;
private const Int32 WM_RBUTTONUP = 0x0205;
private const Int32 WM_RBUTTONDBLCLK = 0x0206;
private const Int32 WM_MBUTTONDOWN = 0x0207;
private const Int32 WM_MBUTTONUP = 0x0208;
private const Int32 WM_MBUTTONDBLCLK = 0x0209;
private const Int32 WM_MOUSEWHEEL = 0x020A;
private const Int32 WM_XBUTTONDOWN = 0x020B;
private const Int32 WM_XBUTTONUP = 0x020C;
private const Int32 WM_XBUTTONDBLCLK = 0x020D;
private MemoryMappedViewAccessor accessor;
private bool hooked = false;
private WindowsHookAPI.HookDelegate mouseDelegate;
private IntPtr mouseHandle;
private const Int32 WH_MOUSE_LL = 14;
private readonly VolumeControl vc;
public MouseInput(VolumeControl vc)
{
this.vc = vc;
}
public void setHook(bool on)
{
if (hooked == on) return;
if (on)
{
mouseDelegate = MouseHookDelegate;
mouseHandle = WindowsHookAPI.SetWindowsHookEx(WH_MOUSE_LL, mouseDelegate, IntPtr.Zero, 0);
if (mouseHandle != IntPtr.Zero) hooked = true;
}
else
{
WindowsHookAPI.UnhookWindowsHookEx(mouseHandle);
hooked = false;
}
}
private IntPtr MouseHookDelegate(Int32 Code, IntPtr wParam, IntPtr lParam)
{
//mouseData:
//If the message is WM_MOUSEWHEEL, the high-order word of this member is the wheel delta.The low-order word is reserved.
// A positive value indicates that the wheel was rotated forward, away from the user;
// a negative value indicates that the wheel was rotated backward, toward the user.
// One wheel click is defined as WHEEL_DELTA, which is 120.(0x78 or 0xFF88)
//If the message is WM_XBUTTONDOWN, WM_XBUTTONUP, WM_XBUTTONDBLCLK, WM_NCXBUTTONDOWN, WM_NCXBUTTONUP, or WM_NCXBUTTONDBLCLK,
// the high - order word specifies which X button was pressed or released,
// and the low - order word is reserved.This value can be one or more of the following values.Otherwise, mouseData is not used.
//XBUTTON1 = 0x0001 The first X button was pressed or released.
//XBUTTON2 = 0x0002 The second X button was pressed or released.
MSLLHOOKSTRUCT lparam = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
int command = (int)wParam;
if (Code < 0 || command == WM_LBUTTONDBLCLK || command == WM_RBUTTONDBLCLK)
return WindowsHookAPI.CallNextHookEx(mouseHandle, Code, wParam, lParam);
else if (command == WM_XBUTTONDOWN || command == WM_XBUTTONUP)
{
int numbutton = ((int)lparam.mouseData >> 16) - 1;
//return (IntPtr)1;
}
else if (command == WM_LBUTTONDOWN || command == WM_LBUTTONUP)
{
if (command == WM_LBUTTONUP)
{
vc.VolDown();
Console.WriteLine("L down");
}
}
else if (command == WM_RBUTTONDOWN || command == WM_RBUTTONUP)
{
if (command == WM_RBUTTONUP)
{
vc.VolUp();
Console.WriteLine("L Up");
}
}
else if (command == WM_MBUTTONDOWN || command == WM_MBUTTONUP)
{
if (hooked)
{
setHook(false);
Console.WriteLine("hook deactivated");
}
else
{
setHook(true);
Console.WriteLine("hook activated");
}
}
else if (command == WM_MOUSEWHEEL)
{
}
return WindowsHookAPI.CallNextHookEx(mouseHandle, Code, wParam, lParam);
}
~MouseInput()
{
}
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
private struct MSLLHOOKSTRUCT
{
public POINT pt;
public uint mouseData;
public uint flags;
public uint time;
public IntPtr dwExtraInfo;
}
}
}

How to clear IE cache for specific site using C# not using JS or jQuery

I want to clear IE cache for a site using C# . I am having a Windows application which uses WebBrowser control to login to specific site. But, I am not storing any cache using my program , IE does it by default.
I was trying to understand
https://msdn.microsoft.com/en-us/library/windows/desktop/aa384026(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/aa384049(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/aa383983(v=vs.85).aspx
But I couldn't find a solution out of it.
you can Use my class to Clear IE Cache
public static class WebBrowserHelper
{
#region WINAPI
[DllImport("wininet", EntryPoint = "DeleteUrlCacheEntryA", SetLastError = true)]
public static extern bool DeleteUrlCacheEntry(IntPtr lpszUrlName);
[DllImport("wininet", SetLastError = true)]
public static extern bool DeleteUrlCacheGroup(long GroupId, int dwFlags, IntPtr lpReserved);
[DllImport("wininet", EntryPoint = "FindFirstUrlCacheEntryA", SetLastError = true)]
public static extern IntPtr FindFirstUrlCacheEntry(string lpszUrlSearchPattern, IntPtr lpFirstCacheEntryInfo, ref int lpdwFirstCacheEntryInfoBufferSize);
[DllImport("wininet", SetLastError = true)]
public static extern IntPtr FindFirstUrlCacheGroup(int dwFlags, int dwFilter, IntPtr lpSearchCondition, int dwSearchCondition, ref long lpGroupId, IntPtr lpReserved);
[DllImport("wininet", EntryPoint = "FindNextUrlCacheEntryA", SetLastError = true)]
public static extern bool FindNextUrlCacheEntry(IntPtr hFind, IntPtr lpNextCacheEntryInfo, ref int lpdwNextCacheEntryInfoBufferSize);
[DllImport("wininet", SetLastError = true)]
public static extern bool FindNextUrlCacheGroup(IntPtr hFind, ref long lpGroupId, IntPtr lpReserved);
#endregion
[StructLayout(LayoutKind.Explicit)]
public struct INTERNET_CACHE_ENTRY_INFOA
{
[FieldOffset(0)]
public uint dwStructSize;
[FieldOffset(4)]
public IntPtr lpszSourceUrlName;
[FieldOffset(8)]
public IntPtr lpszLocalFileName;
[FieldOffset(12)]
public uint CacheEntryType;
[FieldOffset(16)]
public uint dwUseCount;
[FieldOffset(20)]
public uint dwHitRate;
[FieldOffset(24)]
public uint dwSizeLow;
[FieldOffset(28)]
public uint dwSizeHigh;
[FieldOffset(32)]
public System.Runtime.InteropServices.ComTypes.FILETIME LastModifiedTime;
[FieldOffset(40)]
public System.Runtime.InteropServices.ComTypes.FILETIME ExpireTime;
[FieldOffset(48)]
public System.Runtime.InteropServices.ComTypes.FILETIME LastAccessTime;
[FieldOffset(56)]
public System.Runtime.InteropServices.ComTypes.FILETIME LastSyncTime;
[FieldOffset(64)]
public IntPtr lpHeaderInfo;
[FieldOffset(68)]
public uint dwHeaderInfoSize;
[FieldOffset(72)]
public IntPtr lpszFileExtension;
[FieldOffset(76)]
public uint dwReserved;
[FieldOffset(76)]
public uint dwExemptDelta;
}
public static void ClearCache()
{
bool flag;
bool flag1;
long num = (long)0;
int num1 = 0;
int num2 = 0;
IntPtr zero = IntPtr.Zero;
IntPtr intPtr = IntPtr.Zero;
bool flag2 = false;
intPtr = FindFirstUrlCacheGroup(0, 0, IntPtr.Zero, 0, ref num, IntPtr.Zero);
if ((intPtr == IntPtr.Zero ? true : 259 != Marshal.GetLastWin32Error()))
{
while (true)
{
flag = true;
if ((259 == Marshal.GetLastWin32Error() ? false : 2 != Marshal.GetLastWin32Error()))
{
flag2 = DeleteUrlCacheGroup(num, 2, IntPtr.Zero);
if ((flag2 ? false : 2 == Marshal.GetLastWin32Error()))
{
flag2 = FindNextUrlCacheGroup(intPtr, ref num, IntPtr.Zero);
}
if (flag2)
{
flag1 = true;
}
else
{
flag1 = (259 == Marshal.GetLastWin32Error() ? false : 2 != Marshal.GetLastWin32Error());
}
if (!flag1)
{
break;
}
}
else
{
break;
}
}
intPtr = FindFirstUrlCacheEntry(null, IntPtr.Zero, ref num1);
if ((intPtr == IntPtr.Zero ? true : 259 != Marshal.GetLastWin32Error()))
{
num2 = num1;
zero = Marshal.AllocHGlobal(num2);
intPtr = FindFirstUrlCacheEntry(null, zero, ref num1);
while (true)
{
flag = true;
INTERNET_CACHE_ENTRY_INFOA structure = (INTERNET_CACHE_ENTRY_INFOA)Marshal.PtrToStructure(zero, typeof(INTERNET_CACHE_ENTRY_INFOA));
if (259 != Marshal.GetLastWin32Error())
{
num1 = num2;
flag2 = DeleteUrlCacheEntry(structure.lpszSourceUrlName);
if (!flag2)
{
flag2 = FindNextUrlCacheEntry(intPtr, zero, ref num1);
}
if (!(flag2 ? true : 259 != Marshal.GetLastWin32Error()))
{
break;
}
else if ((flag2 ? false : num1 > num2))
{
num2 = num1;
zero = Marshal.ReAllocHGlobal(zero, (IntPtr)num2);
flag2 = FindNextUrlCacheEntry(intPtr, zero, ref num1);
}
}
else
{
break;
}
}
Marshal.FreeHGlobal(zero);
}
}
}
}

cant send key stroke only to Word Through my program that use KeyboardHook

i have my program that Captures weighing and send it to a open window.
its work excellent , except with a single software - Microsoft Word
I have tried everything and have no idea why.
my code:
this is the GlobalKeyBoardHook.cs class
public class GlobalKeyboardHook
{
[DllImport("user32.dll")]
static extern int CallNextHookEx(IntPtr hhk, int code, int wParam, ref keyBoardHookStruct lParam);
[DllImport("user32.dll")]
static extern IntPtr SetWindowsHookEx(int idHook, LLKeyboardHook callback, IntPtr hInstance, uint theardID);
[DllImport("user32.dll")]
static extern bool UnhookWindowsHookEx(IntPtr hInstance);
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string lpFileName);
public delegate int LLKeyboardHook(int Code, int wParam, ref keyBoardHookStruct lParam);
public struct keyBoardHookStruct
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}
const int WH_KEYBOARD_LL = 13;
const int WM_KEYDOWN = 0x0100;
const int WM_KEYUP = 0x0101;
const int WM_SYSKEYDOWN = 0x0104;
const int WM_SYSKEYUP = 0x0105;
LLKeyboardHook llkh;
public List<Keys> HookedKeys = new List<Keys>();
IntPtr Hook = IntPtr.Zero;
public event KeyEventHandler KeyDown;
public event KeyEventHandler KeyUp;
// This is the Constructor. This is the code that runs every time you create a new GlobalKeyboardHook object
public GlobalKeyboardHook()
{
llkh = new LLKeyboardHook(HookProc);
// This starts the hook. You can leave this as comment and you have to start it manually (the thing I do in the tutorial, with the button)
// Or delete the comment mark and your hook will start automatically when your program starts (because a new GlobalKeyboardHook object is created)
// That's why there are duplicates, because you start it twice! I'm sorry, I haven't noticed this...
// hook(); <-- Choose!
}
~GlobalKeyboardHook()
{ unhook(); }
public void hook()
{
IntPtr hInstance = LoadLibrary("User32");
Hook = SetWindowsHookEx(WH_KEYBOARD_LL, llkh, hInstance, 0);
}
public void unhook()
{
UnhookWindowsHookEx(Hook);
}
public int HookProc(int Code, int wParam, ref keyBoardHookStruct lParam)
{
if (Code >= 0)
{
Keys key = (Keys)lParam.vkCode;
if (HookedKeys.Contains(key))
{
KeyEventArgs kArg = new KeyEventArgs(key);
if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && (KeyDown != null))
KeyDown(this, kArg);
else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && (KeyUp != null))
KeyUp(this, kArg);
if (kArg.Handled)
return 1;
}
}
return CallNextHookEx(Hook, Code, wParam, ref lParam);
}
// --- from here start the program --
GlobalKeyboardHook gHook;
gHook = new GlobalKeyboardHook(); // Create a new GlobalKeyboardHook
gHook.KeyDown += new KeyEventHandler(gHook_KeyDown);
foreach (Keys key in Enum.GetValues(typeof(Keys)))
{
gHook.HookedKeys.Add(key);
}
gHook.hook();
public void gHook_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyValue == KeyPressg) //Pause-Break //19
{
ProccName = (GetActiveWindowTitle().ToString());
Start(ProccName);
gHook.unhook();
gHook.hook();
}
else
{
}
}
private string GetActiveWindowTitle()
{
const int nChars = 256;
StringBuilder Buff = new StringBuilder(nChars);
IntPtr handle = GetForegroundWindow();
if (GetWindowText(handle, Buff, nChars) > 0)
{
return Buff.ToString();
}
return null;
}
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
public void Start(string NAME)
{
MSG = lblMSG.Text.Trim();
IntPtr zero = IntPtr.Zero;
for (int i = 0; (i < 60) && (zero == IntPtr.Zero); i++)
{
Thread.Sleep(500);
zero = FindWindow(null, NAME);
}
if (zero != IntPtr.Zero)
{
try
{
string text = lblMSG.Text.Trim();
text = text.Replace("gHook", "");
//OLD
//foreach (char c in text)
// SendKeys.SendWait(c.ToString());
//NEW
if (text.Length == 0) return;
SendKeys.SendWait(text);
if (MyParam._KeyAfter == "Enter")
{
MyParam.FromKEY = true;
SendKeys.SendWait("{ENTER}");
}
else if (MyParam._KeyAfter == "TAB")
{
SendKeys.SendWait("{TAB}");
}
else if (MyParam._KeyAfter == "Key Down")
{
SendKeys.SendWait("{DOWN}");
}
SendKeys.Flush();
}
catch { }
}
}
Any ideas why ?
thanks
EDIT
i fount the problem place:
public void Start(string NAME)
{
// --> NAME Contain --> Word‪ - 123.docx for example when Word window open
MSG = lblMSG.Text.Trim();
IntPtr zero = IntPtr.Zero;
for (int i = 0; (i < 60) && (zero == IntPtr.Zero); i++)
{
Thread.Sleep(500);
zero = FindWindow(null, NAME); // <-- in Word zero Always Contain 0 And never goes on in the code so stuck
}
// <--- the program stops here and stuck
if (zero != IntPtr.Zero)
{

Next Song Button For External Media Player?

Feel free to edit title.
Ok so i'm trying to create a short key button that skips to the next song of any media player? like what some keyboards have as in FN + F11 and it goes to next song is there anyway to integrate that into c# for my own keyboard? i have this code so far but all its doing is posting a msg onto the textbox1.
// Structure contain information about low-level keyboard input event
[StructLayout(LayoutKind.Sequential)]
private struct KBDLLHOOKSTRUCT
{
public Keys key;
public int scanCode;
public int flags;
public int time;
public IntPtr extra;
}
//System level functions to be used for hook and unhook keyboard input
private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int id, LowLevelKeyboardProc callback, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool UnhookWindowsHookEx(IntPtr hook);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hook, int nCode, IntPtr wp, IntPtr lp);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string name);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern short GetAsyncKeyState(Keys key);
//Declaring Global objects
private IntPtr ptrHook;
private LowLevelKeyboardProc objKeyboardProcess;
private IntPtr captureKey(int nCode, IntPtr wp, IntPtr lp)
{
if (nCode >= 0)
{
KBDLLHOOKSTRUCT objKeyInfo = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lp, typeof(KBDLLHOOKSTRUCT));
// Keys
if (objKeyInfo.key == Keys.F10 && ModifierKeys == Keys.Alt)
{
textBox1.Focus();
a += 1;
c += 1;
textBox1.Text += Convert.ToString(c) + ". " + "Previous Song" + Environment.NewLine;
PrevSongCount.Text = Convert.ToString(a);
AllUpCount.Text = Convert.ToString(c);
return (IntPtr)1;
}
if (objKeyInfo.key == Keys.F11 && ModifierKeys == Keys.Alt)
{
textBox1.Focus();
b += 1;
c += 1;
textBox1.Text += Convert.ToString(c) + ". " + "Next Song" + Environment.NewLine;
NextSongCount.Text = Convert.ToString(b);
AllUpCount.Text = Convert.ToString(c);
return (IntPtr)1;
}
}
return CallNextHookEx(ptrHook, nCode, wp, lp);
}
bool HasAltModifier(int flags)
{
return (flags & 0x20) == 0x20;
}
This was not as easy as I thought. But finally I managed to do it and the solution was shockingly simple.
After compiling this you are using the venerable virtual media keyboard codes.
http://msdn.microsoft.com/en-us/library/dd375731%28v=VS.85%29.aspx
I used this cmd line prog for my microsoft natural keyboard which does not have media keys but has 5 programmable keys and to get it to work you hack the registry
HKEY_CURRENT_USER\Software\Microsoft\IntelliType Pro\EventMapping\82 or
HKEY_CURRENT_USER\Software\Microsoft\IntelliType Pro\ModelSpecific\1016\EventMapping\82
where the 81 is just one of the dynamic keys (78-82)
and put the value previous or next into the Arguments key.
using System;
using System.Runtime.InteropServices;
namespace NxtTrack
{
class Program
{
[DllImport("user32.dll")]
private static extern bool PostMessage(IntPtr hWnd, uint Msg, UIntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
public static extern void keybd_event(byte vkCode, byte scanCode, int flags, IntPtr extraInfo);
enum TrackMove
{
Previous,Next
}
static void Main(string[] args)
{
TrackMove trackMove;
try
{
if(args[0].ToLower().Contains("previous"))
trackMove = TrackMove.Previous;
else if(args[0].ToLower().Contains("next"))
trackMove = TrackMove.Next;
else
{
throw new Exception("wrong param");
}
}
catch
{
Console.WriteLine("Params needed: Next or Previous");
return;
}
TrackKeys(trackMove);
}
private static void TrackKeys(TrackMove trackMove)
{
//http://msdn.microsoft.com/en-us/library/dd375731%28v=VS.85%29.aspx
byte msg = trackMove == TrackMove.Previous ? (byte)0xB1 : (byte)0xB0;
keybd_event(msg, 0x45, 0, IntPtr.Zero);
}
}
}

where to get the keycode for keyboard hook in c#

I am using the below code to disable the keyboard combination hooks.
I got this code while i surfed the net.
I want to know the list of keycodes for the keyboard keys. [lParam.vkCode == ???]
Please provide me the link for that, Thanks..
namespace BlockShortcuts
{
public class DisableKeys
{
private delegate int LowLevelKeyboardProcDelegate(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);
[DllImport("user32.dll", EntryPoint = "SetWindowsHookExA", CharSet = CharSet.Ansi)]
private static extern int SetWindowsHookEx(int idHook, LowLevelKeyboardProcDelegate lpfn, int hMod, int dwThreadId);
[DllImport("user32.dll")]
private static extern int UnhookWindowsHookEx(int hHook);
[DllImport("user32.dll", EntryPoint = "CallNextHookEx", CharSet = CharSet.Ansi)]
private static extern int CallNextHookEx(int hHook, int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);
const int WH_KEYBOARD_LL = 13;
private int intLLKey;
private struct KBDLLHOOKSTRUCT
{
public int vkCode;
int scanCode;
public int flags;
int time;
int dwExtraInfo;
}
private int LowLevelKeyboardProc(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam)
{
bool blnEat = false; switch (wParam)
{
case 256:
case 257:
case 260:
case 261:
//Alt+Tab, Alt+Esc, Ctrl+Esc, Windows Key
if (((lParam.vkCode == 9) && (lParam.flags == 32)) ||
((lParam.vkCode == 27) && (lParam.flags == 32)) ||
((lParam.vkCode == 27) && (lParam.flags == 0)) ||
((lParam.vkCode == 91) && (lParam.flags == 1)) ||
((lParam.vkCode == 92) && (lParam.flags == 1)) ||
((true) && (lParam.flags == 32)))
{
blnEat = true;
}
break;
} if (blnEat) return 1; else return CallNextHookEx(0, nCode, wParam, ref lParam);
}
public void DisableKeyboardHook()
{
intLLKey = SetWindowsHookEx(WH_KEYBOARD_LL, new LowLevelKeyboardProcDelegate(LowLevelKeyboardProc), System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]).ToInt32(), 0);
}
private void ReleaseKeyboardHook()
{
intLLKey = UnhookWindowsHookEx(intLLKey);
}
#endregion
}
}
Start by looking at the definition of the callback LowLevelKeyboardProc.
Then examine the definition of the struct that is your lparam.
From there you can see that vkcode is a virtual key code. There is a list of those on MSDN as well.
EDIT: As per comment, updated link to point to Windows Keyboard Input section of MSDN rather than the Windows CE Keyboard Input section of MSDN.
Pinvoke.net has them copy-paste ready.

Categories