Trap the KeyUp Event in my Usercontrol

Hi have a usercontrol (WinForms) which has multiple buttons which are clickable/selectable.

i want to be able to select multiple buttons at a time, for that I want to use the CTRL-Button. And as soon as I release the CTRL-Key all the selected buttons in my usercontrol should be processed.
I know that only the currently focused control can react to a keyup event, so I tried it with overriding the WndProc method (see below)

The method gets never called when I click a key (apart from the ALT-Key). What could be the problem, or is there a better way to do what I want?
protected override void WndProc(ref Message m)
        {
            System.Diagnostics.Debug.WriteLine(m.Msg.ToString("X"));
            if(m.Msg == (int)0x0101)
            {
                System.Diagnostics.Debug.WriteLine("test");
            }

            base.WndProc(ref m);
        }

Open in new window

LVL 3
ArikaelAsked:
Who is Participating?
 
Mike TomlinsonConnect With a Mentor Middle School Assistant TeacherCommented:
I feel like this is a kludge...

One way to "globally" trap the control key is to implement the IMessageFilter() interface.  This will allow you to preview all messages intended for your ENTIRE app before it gets routed to current form/control.

As such, you'll get notified even if your UserControl (and the form it's contained by) does NOT have focus.

What I've done below is Clip the cursor so that the mouse cannot leave the UserControl while the Control key is down.  Even if the Control key was down while outside the UserControl...it will be clipped once the mouse enters.

Thus we can perform some action if the Control key is released while within the UserControl (which it will be if the Control key was ever down at some time when the mouse is moved within!).  The cursor is released when the Control key goes up.

Here's the code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
            MyFilter mf = new MyFilter();
            mf.CtrlKeyDown += new MyFilter.CtrlKeyDelegate(mf_CtrlKeyDown);
            mf.CtrlKeyUp +=new MyFilter.CtrlKeyDelegate(mf_CtrlKeyUp);
            Application.AddMessageFilter(mf);
        }

        private void mf_CtrlKeyDown()
        {
            Rectangle RC = this.RectangleToScreen(this.ClientRectangle);
            if (RC.Contains(Cursor.Position))
            {
                Cursor.Clip = RC; // keep the mouse within the UserControl
            }
        }

        private void mf_CtrlKeyUp()
        {
            Rectangle RC = this.RectangleToScreen(this.ClientRectangle);
            if (RC.Contains(Cursor.Position))
            {
                Cursor.Clip = new Rectangle(); // release the mouse
                MessageBox.Show("Control KeyUp while Cursor within the UserControl");

                // .. process your "buttons" here...

            }
        }

    }

    public class MyFilter : IMessageFilter
    {
        public delegate void CtrlKeyDelegate();
        public event CtrlKeyDelegate CtrlKeyUp;
        public event CtrlKeyDelegate CtrlKeyDown;

        private const int WM_KEYDOWN = 0x100;
        private const int WM_KEYUP = 0x101;

        public bool PreFilterMessage(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_KEYDOWN:
                    if (m.WParam.ToInt32() == (int)Keys.ControlKey)
                    {
                        this.CtrlKeyDown();
                    }
                    break;

                case WM_KEYUP:
                    if (m.WParam.ToInt32() == (int)Keys.ControlKey)
                    {
                        this.CtrlKeyUp();
                    }
                    break;
            }
            return false;
        }

    }

}

Open in new window

0
 
rajvjaCommented:
0
 
ArikaelAuthor Commented:
Hi

I tried the suggestions (ProcessDialogKEy) given in the link, but it doesn't work because I need an event which gets fired when I release a key, ProcessDialogKey fires when I press a key.
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

 
Gene_CypCommented:
You can work this in a different way. Have your program recognize that you've selected buttonA, button C, etc

Then, upon releasing the Ctrl button, work through that list of buttons.
0
 
ArikaelAuthor Commented:
Unfortunately this doesn't help.

I know how to use the event. The Problem is none of my usercontrol's Key-Events (keyup, keypress, keydown) get fired.
I also tried the suggested code here:
http://social.msdn.microsoft.com/Forums/fi-FI/winforms/thread/74d938e3-79d3-438f-b740-9a3910633cdb

WndProc doesn't get fired when I press a key
0
 
ArikaelAuthor Commented:
@Gene_Cyp
Sorry, haven't seen your comment :-)

Problem is, I'm not able to raise any key event on my user control.
My user Control resides in a Panel.Control, which resides in a form (keypreview is set to false)
0
 
Gene_CypCommented:
Arikael:

1) Detect Ctrl+Click
2) Recognize which button was selected
3) Save that to a list of sorts
4) Rinse and repeat
5) When Ctrl is released begin searching through that list
6) button.perform click
7) remove from temp list
8) repeat until list is empty

Giving you the thought if you need help with the code let me know
0
 
ArikaelAuthor Commented:
hi

well I could call the KeyDown event on every single button, but can't do that with the releasing of ctrl because this could happen "outside" of a button.

Like I said, problem is, I'm not able at all to trap Key events in my usercontrol
0
 
Gene_CypCommented:
So, is your problem detecting this:

"5) When Ctrl is released begin searching through that list"

?
0
 
ArikaelAuthor Commented:
Hi

thanks for your answers

Idle_Mind
I will have a look at your solution as soon as I'm in my office

Gene_Cyp
yes and 1)
The searching through the list is no problem but the detection of releasing a button (ctrl) is not working
0
 
ArikaelAuthor Commented:
sorry I forgot:

Shouldn't WndProc do what I want?
0
 
Gene_CypCommented:
Arikael, have you been able to solve your problem?
0
 
ArikaelAuthor Commented:
Hi

Sorry, I totally forgot this question.
Yes I was able to solve my problem, I'll post the code I used as soon as I am in the office (tomorrow)
0
 
ArikaelAuthor Commented:
ah, sorry
I did use the following link: http://www.codeproject.com/KB/cs/ProcessKeyPreview.aspx

but Idle_Minds code does work too.
0
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.