Solved

Keyboard Hook - TextBox

Posted on 2009-04-10
7
1,522 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
PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

 
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

Independent Software Vendors: 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!

Question has a verified solution.

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

Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…

696 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