Text isn't showing up in Windows Forms Textbox - c#

I am developing a tiny keylogger (for non-malicious purposes) and I want to write all logged keypresses to a text box. Currently, all calls to WriteOutput don't write anything to the box except for the start and stop methods. What am I doing wrong?
Here is my code:
Program.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Drawing;
namespace Logger
{
/// <summary>
/// Class with program entry point.
/// </summary>
internal sealed class Program
{
public static bool log = false;
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private static LowLevelKeyboardProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
/// <summary>
/// Program entry point.
/// </summary>
[STAThread]
private static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
_hookID = SetHook(_proc);
Application.Run(new MainForm());
UnhookWindowsHookEx(_hookID);
}
private static IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
}
}
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN && log == true)
{
int vkCode = Marshal.ReadInt32(lParam);
MainForm MF = new MainForm();
//THIS IS THE CALL THAT DOESN'T OUTPUT ANYTHING!
MF.WriteOutput(vkCode.ToString());
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
}
}
Mainform.cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
namespace Logger
{
/// <summary>
/// Description of MainForm.
/// </summary>
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
public void WriteOutput(string input)
{
output.AppendText(string.Format(input));
using (StreamWriter sr = new StreamWriter("log.log", true))
{
sr.Write(input.ToString());
}
}
private void StartClick(object sender, System.EventArgs e)
{
Program.log = true;
output.AppendText(string.Format("Logging started\n"));
}
private void StopClick(object sender, EventArgs e)
{
Program.log = false;
output.AppendText(string.Format("Logging stopped\n"));
}
}
}

You are instantiating a new form each time:
MainForm MF = new MainForm();
MF.WriteOutput(vkCode.ToString());
Instead, re-use the same MainForm instance. In Program.cs:
private static MainForm mainForm;
....
[STAThread]
private static void Main(string[] args)
{
...
mainForm = new MainForm();
Application.Run(mainForm);
...
}
....
mainForm.WriteOutput(vkCode.ToString());

Try casting vkCode to Keys and then write it to the textbox.
Like this:
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN && log == true)
{
int vkCode = Marshal.ReadInt32(lParam);
MainForm MF = new MainForm();
MF.WriteOutput((Keys)vkCode);
}
I have used this same code before in a switch statement to capture specific letters and it has worked well using the cast.
Hope this helps!

Related

Transparent form inexplicably passes only some touch inputs

I have problems while I'm working where I'll pick up my laptop and since the screen is nearly the entire area of the laptops top portion, my hand ends up touching the screen and often minimizing or closing the program I'm working with. To remedy this, I made a small program I'm using to "disable" the touchscreen on my laptop, brought on by windows 10's lack of a disable option outside of device manager (on windows 7, you could just use the mouse settings - on win10 this option is gone).
The program works well by essentially identifying and dropping mouse inputs identified as touches, but has a weird quirk in that a few windows still receive touch inputs, such as Edge and Chrome. Most programs don't have this problem and the program usually correctly drops the touch inputs. It's not a huge deal, but I'm wondering why those windows still receive inputs when others do not.
I have attached the code (it's small), does anyone know why some programs still receive these inputs?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Windows.Input;
namespace TouchDisable
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Width = Screen.PrimaryScreen.Bounds.Width;
Height = Screen.PrimaryScreen.Bounds.Height;
_hookID = SetHook(_proc);
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
UnhookWindowsHookEx(_hookID);
}
//------------------------------------------------------------------------------------------
private static LowLevelMouseProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
private static IntPtr SetHook(LowLevelMouseProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_MOUSE_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (IsTouch(lParam))
return new IntPtr(1);
else
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
private const int WH_MOUSE_LL = 14;
private enum MouseMessages
{
WM_LBUTTONDOWN = 0x0201,
WM_LBUTTONUP = 0x0202,
WM_MOUSEMOVE = 0x0200,
WM_MOUSEWHEEL = 0x020A,
WM_RBUTTONDOWN = 0x0204,
WM_RBUTTONUP = 0x0205
}
[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;
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
//------------------------------------------------------------------------------------------
const uint TOUCH_FLAG = 0xFF515700;
static bool IsTouch(IntPtr lParam)
{
MSLLHOOKSTRUCT hookData = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam,
typeof(MSLLHOOKSTRUCT));
uint extraInfo = (uint)hookData.dwExtraInfo.ToInt32();
if ((extraInfo & TOUCH_FLAG) == TOUCH_FLAG)
return true;
return false;
}
}
}

MouseHook causes juddering mouse movement when processing

I am building an application using UIAutomation which labels certain widgets on a typical Microsoft Windows user interface, e.g. Windows Explorer, control panel. I am using appropriate threading with UIA based on a Microsoft blog example and everything is working well. The labelling of the widgets is triggered by certain events and one of these events is a mouse click using a low level mousehook code shown below. The problem I have is that when the UI is updated on a mouseclick the mouse movement becomes juddery (as in not smooth) while the UI is updating. So what springs to mind is that the mouse action event needs to run in a different thread. Although I have been programming for quite a few years it has been off and on so I am far from confident when it comes to such threading issues. I have tried the code below in the mouse auction event but it makes no difference. Any help greatly appreciated. I would particularly appreciate example code with an explanation in particular.
// Setup global mouse hook to react to mouse clicks under certain conditions, see event handler
MouseHook.Start();
MouseHook.MouseAction += new EventHandler(MouseHook_MouseAction);
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;
namespace myapplication
{
public static class MouseHook
{
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
public static event EventHandler MouseAction = delegate { };
private const int WH_MOUSE_LL = 14;
private enum MouseMessages
{
WM_LBUTTONDOWN = 0x0201,
// WM_LBUTTONUP = 0x0202,
// WM_MOUSEMOVE = 0x0200,
WM_MOUSEWHEEL = 0x020A,
WM_RBUTTONDOWN = 0x0204,
//WM_RBUTTONUP = 0x0205
}
[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;
}
public static void Start()
{
_hookID = SetHook(_proc);
}
public static void stop()
{
UnhookWindowsHookEx(_hookID);
}
private static LowLevelMouseProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
private static IntPtr SetHook(LowLevelMouseProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
IntPtr hook = SetWindowsHookEx(WH_MOUSE_LL, proc, GetModuleHandle("user32"), 0);
if (hook == IntPtr.Zero) throw new System.ComponentModel.Win32Exception();
return hook;
}
}
private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr HookCallback(
int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && (MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam || MouseMessages.WM_RBUTTONDOWN == (MouseMessages)wParam ||
MouseMessages.WM_MOUSEWHEEL == (MouseMessages)wParam))
{
MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
MouseAction(null, new EventArgs());
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
}
}
private void MouseHook_MouseAction(object sender, EventArgs e)
{
//my attempt at threading solution
Thread th = new Thread(() =>
{
UpdateUI();
Application.Run();
});
th.SetApartmentState(ApartmentState.STA);
th.Start();
}

C#, Need help to seperate one beginner program

As beginner lesson I want to port this tutorial http://null-byte.wonderhowto.com/how-to/create-simple-hidden-console-keylogger-c-sharp-0132757/ to a Windows Form Application.
This should show a user what keys are pressed inside a label called 'lblMessage'.
I have separeted the code now into two pieces.
Form1.cs
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
public GlobalKeyHook hook = new GlobalKeyHook();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// Origin
// _hookID = SetHook(_proc);
hook._hookID = hook.SetHook(_proc);
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
// Origin
// UnhookWindowsHookEx(_hookID);
hook.UnhookWindowsEx(_hookID);
}
}
}
GlobalKeyHook.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
namespace WindowsFormsApplication3
{
class GlobalKeyHook : Form
{
#region DLLs
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
LowLevelKeyboardProc 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)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
#endregion
#region Fields and delegation
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private static LowLevelKeyboardProc _proc = HookCallback;
public static IntPtr _hookID = IntPtr.Zero;
public delegate IntPtr LowLevelKeyboardProc(
int nCode, IntPtr wParam, IntPtr lParam);
#endregion
public GlobalKeyHook()
{
IntPtr hookID = _hookID;
LowLevelKeyboardProc proc = _proc;
}
static Form form = new Form();
#region Methods
private static IntPtr HookCallback(
int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
Console.WriteLine((Keys)vkCode);
form.Text = vkCode.ToString();
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
public static IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
#endregion
}
}
But I am not able to use the public static IntPtr _hookID, the method SetHook() or the DLL UnhookWindowsHookEx in the Form1 class. Is it not possible to use this "types" from another class?
Not sure this will solve all your problems but may help you avoid a few of them down the line.
If this is .net 4.0 or higher your SetWindowsHookEX() call will likely return 0 (it failed) because .net no longer emulates a native module for managed dlls. To fix this you can add a DllImport for LoadLibrary() like this:
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Ansi)]
public static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string lpFileName);
Then somewhere before you call SetWindowsHookEX() do this:
IntPtr hinstDLL = UnsafeMethods.LoadLibrary("user32.dll");
and call SetWindowsHookEX() like this:
SetWindowsHookEx(WH_KEYBOARD_LL, proc,
hinstDLL, 0);
Basically SetWindowsHookEX() needs a valid module handle which it verifies but never actually uses it. the reason to load user32 is that since you are p/invoking functions from it you def have it.
Also, in your constructor just set it to IntPtr.Zero. No need make _hookID if you always are setting it to IntPtr.Zero. It is also worth noting that if the computer you are running this on has less than win7sp1 using IntPtr.Zero won't work (99% sure at least.)
I would strongly suggest you check out This set of hooks They have a decent implementation of a hook library that you can easily extend however you want.
You need to set your GlobalKeyHook class to public class GlobalKeyHook.

MS Word's Add-in TextChange Event in C#

I have a Microsoft Word Add-in that find the similar words in a text (But When I click a button !)
My question is : how to call a function when user typed words ?
In other word , i want an event like "TextChange" or "Keypress" when user typing to get the current word and process it and get it's similar words.
Somethings Like this :
private void TextChangeEventOfCurrentActiveDocument(object sender, System.EventArgs e)
{
...
}
Any Other idea that i can get new words that user typed ?
Thanks.
Finally after a long time, i create this add-in by using Windows hooks.
(Special thanks to #Reg Edit)
Here the entire code that i wrote and this work nice for me. (some optional section of code was removed.)
ThisAddIn.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Word = Microsoft.Office.Interop.Word;
using Office = Microsoft.Office.Core;
using Microsoft.Office.Tools.Word;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
namespace PersianWords
{
public partial class ThisAddIn
{
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private static IntPtr hookId = IntPtr.Zero;
private delegate IntPtr HookProcedure(int nCode, IntPtr wParam, IntPtr lParam);
private static HookProcedure procedure = HookCallback;
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, HookProcedure lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr SetHook(HookProcedure procedure)
{
using (Process process = Process.GetCurrentProcess())
using (ProcessModule module = process.MainModule)
return SetWindowsHookEx(WH_KEYBOARD_LL, procedure, GetModuleHandle(module.ModuleName), 0);
}
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int pointerCode = Marshal.ReadInt32(lParam);
if (pointerCode == 162 || pointerCode == 160)
{
return CallNextHookEx(hookId, nCode, wParam, lParam);
}
string pressedKey = ((Keys)pointerCode).ToString();
//Do some sort of processing on key press
var thread = new Thread(() =>
{
MyClass.WrdApp.CustomizationContext = MyClass.WrdApp.ActiveDocument;
//do something with current document
});
thread.Start();
}
return CallNextHookEx(hookId, nCode, wParam, lParam);
}
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
hookId = SetHook(procedure);
MyClass.WrdApp = Application;
MyClass.WrdApp.CustomizationContext = MyClass.WrdApp.ActiveDocument;
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
UnhookWindowsHookEx(hookId);
}
#region VSTO generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InternalStartup()
{
this.Startup += new System.EventHandler(ThisAddIn_Startup);
this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
}
#endregion
}
}
Sorry to say, but there is no such event. Nothing is getting close to it either.
So you are stuck with a button, or check the contents every once in a while using some sort of timer (the Timer class might be an option).
You could use Windows hooks to intercept keystrokes from another window (Word in this case).
Alternatively, the Word Application has a WindowSelectionChange event, which won't fire on typing, but will fire if the user moves the cursor with an arrow key or clicks a word. This would allow you to react to a word being clicked, rather than the user having to move somewhere else on the screen to click a button.

How to get the "KeyPress" event from a Word 2010 Addin (developed in C#)?

How can I "catch" the KeyPress event from a Word 2010 Addin developed in C#?
Note: I'm not looking for "complex" solutions like hooking stuff, but for the nice and tidy
.NET even from the object model.
The application object I have "in my hands" is:
Microsoft.Office.Interop.Word.Application
Best Regards
Unfortunately there is nothing built-in in the Word API or VSTO which can pick up key strokes, more info on this can be found here
I've been searching for a feasible solution for some time but the best I could come up with was handling it through Windows API using hooks, it's likely you will reach the same conclusion so here's an example:
You'll need to add a using directive to the following assemblies:
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
And here's the hook:
public partial class ThisAddIn
{
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private static IntPtr hookId = IntPtr.Zero;
private delegate IntPtr HookProcedure(int nCode, IntPtr wParam, IntPtr lParam);
private static HookProcedure procedure = HookCallback;
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, HookProcedure lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
hookId = SetHook(procedure);
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
UnhookWindowsHookEx(hookId);
}
private static IntPtr SetHook(HookProcedure procedure)
{
using (Process process = Process.GetCurrentProcess())
using (ProcessModule module = process.MainModule)
return SetWindowsHookEx(WH_KEYBOARD_LL, procedure, GetModuleHandle(module.ModuleName), 0);
}
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int pointerCode = Marshal.ReadInt32(lParam);
string pressedKey = ((Keys)pointerCode).ToString();
//Do some sort of processing on key press
var thread = new Thread(() => { MessageBox.Show(pressedKey); });
thread.Start();
}
return CallNextHookEx(hookId, nCode, wParam, lParam);
}
private void InternalStartup()
{
this.Startup += new System.EventHandler(ThisAddIn_Startup);
this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
}
}
You might try to use the Excel WebBrowser Control instead of the System.Windows.Forms WebBrowser; it handles special key forwarding as TAB, DEL, CTRL+V, etc.
For that change the WebBrowser contructor from
new System.Windows.Forms.WebBrowser();
to
new Microsoft.Office.Tools.Excel.Controls.WebBrowser();
You would need to add references to your project: Project/Add Reference/Extensions select Microsoft.Tools.Outlook & Microsoft.Tools.Outlook.v4.0.Utilities

Categories