Solved

Keyboard Hook - TextBox

Posted on 2009-04-10
7
1,510 Views
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 typed..to add insult to injury nothing showed up in the TextBox.

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

Thx

wc





0
Comment
Question by:williamcampbell
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
7 Comments
 
LVL 2

Accepted Solution

by:
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:)
0
 
LVL 12

Author Comment

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

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

Expert Comment

by:jonathan_mccoy
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
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 12

Author Comment

by:williamcampbell
ID: 24130849
jon,

 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

0
 
LVL 2

Expert Comment

by:jonathan_mccoy
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
0
 
LVL 12

Author Comment

by:williamcampbell
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);
                        }
                        else
                            if (current.Length > 0)
                            {
                                current = current.Substring(0, current.Length - 1);
                            }
                        handled = true;
                    }
                    break;
                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;
 
                    break;
            }
 
            if (handled == false)
                switch ((int)e.wParam)
                {
                    case 13:
                    case 27: // End Editing
                        chklistDefects.EndEditing(true);
                        listAnalysis.EndEditing(true);
                        //cbt.SetChain(true);
                        break;
                    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);
                        break;
                    case 190: current += ".";
                        break;
                    case 46:
                        if (selected != "")
                        {
                            current = current.Substring(txtBoxLView.SelectionStart, txtBoxLView.SelectionLength);
                        }
                        break;
                }
 
            txtBoxLView.Text = current;

Open in new window

0
 
LVL 2

Expert Comment

by:jonathan_mccoy
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:)
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article is for Object-Oriented Programming (OOP) beginners. An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Inter…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

733 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