Keyboard Hook - TextBox

Posted on 2009-04-10
Last Modified: 2012-05-06
I have a C# DLL being called from a C++ App. The C++ App is putting in a Keyboard Hook so that when I try to edit something in a TextBox all the keystrokes go to the main app (as accelertors very funny actually)

So to combat this I installed my own Keyboard Hook in my C# DLL and am able to trap the Keystrokes before they get to the main app and choke them off by not calling the the next Keyboard Hook.

Great. So now I have a wParam and an lParam and I need to send them to the TextBox

At first I tired converting the keycode and manipulating the actual TextBox Text but this started turning into writing my own Text Control ...

I then decided to Use p/Invoke PostMessage and TextBox.Handle and posy WM_KEYDOWN to the textbox gotta work right?

Nope the Main app picked up the message and happily started opening dialogs and stuff as I add insult to injury nothing showed up in the TextBox.

Any Ideas how to get the Captured Keystrokes to the TextBox?



Question by:williamcampbell
  • 4
  • 3

Accepted Solution

jonathan_mccoy earned 500 total points
ID: 24120432
you can have a winForm take Key input before it gets to the controls
I would try flipping that and sending the form the key Strokes like a fake keyboard

In programming we end up in such weird places:)
LVL 12

Author Comment

ID: 24120889
Not sure how to do that ...

Once I get the keys how would I send them to the textBox?

Expert Comment

ID: 24127746
I was thinking you use the windows message pump and get the handle to your C# window

so a key input comes in and normally it would go to you c++ app but you cut that and have it inside you c# app
now send it from your c# app to the c# winForm window and it will pass it to the textBox like normal
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

LVL 12

Author Comment

ID: 24130849

 It's a C# Dll Witha WinForm loaded Via COM

 Tried your tip ... the KeyStrokes get caught by the Main App (as accelerators)

 The Senario was:
 My C# Gets KeyStrokes via Hook
 PostMessage to Main C# Window
 C++ App Gets KeyStrokes and Eats them
I will have to see what the C++ app is doing and have it unhook its accelerators while I have focus.

const int WM_KEYDOWN = 0x100;

IntPtr windowHandle = FindWindow(null, "Model Analyzer");

bool result = PostMessage (windowHandle, WM_KEYDOWN, (int)e.wParam, (int)e.lParam);

Open in new window


Expert Comment

ID: 24132208
if you C++ app ignored any stuff going to your C#, so you would let your C++ know what the C# winForm handle was and let that slip and just catch anything else:) a idea

anyway a side note you can use control handles like so
    private const int WM_SETTEXT = 0x0C;
    private void button1_Click(object sender, EventArgs e)
      string txt = "Test01";
      SendMessage(richTextBox1.Handle,  WM_SETTEXT,0, txt);
just thought I would put that into the mix
LVL 12

Author Comment

ID: 24132255
I started down the SetText path and it ended up getting hairy ... I would have to handle all the arrow keys and modifiers and .. oh my I'm re-writing the TextBox

They guy who wrote the C++ side is on Vacation so I was looking for a quick workaround. Modifying the C++ is not a n option at this stage.

Thanks for the ideas

            String current = txtBoxLView.Text;

            String selected = txtBoxLView.SelectedText;

            bool handled = false;

            switch ((Keys)e.wParam)


                case Keys.Back:


                        if (selected != "")


                            current = current.Substring(txtBoxLView.SelectionStart, txtBoxLView.SelectionLength);



                            if (current.Length > 0)


                                current = current.Substring(0, current.Length - 1);


                        handled = true;



                case Keys.NumPad0:

                case Keys.NumPad1:

                case Keys.NumPad2:

                case Keys.NumPad3:

                case Keys.NumPad4:

                case Keys.NumPad5:

                case Keys.NumPad6:

                case Keys.NumPad7:

                case Keys.NumPad8:

                case Keys.NumPad9: current += ((int)e.wParam - 96); handled = true;



            if (handled == false)

                switch ((int)e.wParam)


                    case 13:

                    case 27: // End Editing





                    case 48:

                    case 49:

                    case 50:

                    case 51:

                    case 52:

                    case 53:

                    case 54:

                    case 55:

                    case 56:

                    case 57: current += ((int)e.wParam - 48);


                    case 190: current += ".";


                    case 46:

                        if (selected != "")


                            current = current.Substring(txtBoxLView.SelectionStart, txtBoxLView.SelectionLength);




            txtBoxLView.Text = current;

Open in new window


Expert Comment

ID: 24134599
you could wrap the textBox, if you derived the textBox you could add a emulate function that would fire the KeyPress event, 70% it could be done this way:)    more or less a textBox2 that had a "void FakeKey(char c)" press function
{find event that takes input and fire it by hand with fake input}

cool code, nothing like a hammer to make a square peg fit in a round hole:)

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
network + 7 73
.NET Error 7 42
Convert VB6 MSXML2.ServerXMLHTTP process to C# 2 33
C# Export DataGridView 4 38
In order to hide the "ugly" records selectors (triangles) in the rowheaders, here are some suggestions. Microsoft doesn't have a direct method/property to do it. You can only hide the rowheader column. First solution, the easy way The first sol…
This article describes a simple method to resize a control at runtime.  It includes ready-to-use source code and a complete sample demonstration application.  We'll also talk about C# Extension Methods. Introduction In one of my applications…
Sending a Secure fax is easy with eFax Corporate ( First, Just open a new email message.  In the To field, type your recipient's fax number You can even send a secure international fax — just include t…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now