Keyboard Hook - TextBox

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?



LVL 12
Who is Participating?
jonathan_mccoyConnect With a Mentor Commented:
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:)
williamcampbellAuthor Commented:
Not sure how to do that ...

Once I get the keys how would I send them to the textBox?
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
Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

williamcampbellAuthor Commented:

 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

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
williamcampbellAuthor Commented:
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

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:)
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.