Capturing a TAB key press event

S

supster

Hello, I'm trying to capture when users press the tab key. This is
scrolling through different fields with tab is broken in my form. I'm
not sure why, but it may have something to do with the fact that the
Windows Shell is creating the form (it is defined in a DLL). I copy
and pasted the form's code over to another application which created
the form through an executable, and tabbing worked fine - so that is
my only guess.

Anyway, I'd like to be able to manually recreate the tabbing feature
(including shift+tab and ctrl+tab), I have no problem writing the
functions to do this, however I cannot find out when tab (or
shift+tab) is pressed.

The KeyPressed event is not called, and the only solution I have found
is the following:

[System.Runtime.InteropServices.DllImport("User32",
EntryPoint="GetKeyState", ExactSpelling=false,
CharSet=System.Runtime.InteropServices.CharSet.Ansi,
SetLastError=true)]
private static extern int GetKeyState(long nVirtKey);
private const int VK_TAB = 0X9;
private const int VK_SHIFT = 0X10;

...

while(true)
{
iRetVal = GetKeyState(VK_TAB);
if ((iRetVal == -128 || iRetVal == -127) &&
this.isFocused)
{
MessageBox.Show("Tab Key Pressed");
}
System.Threading.Thread.Sleep(25);
}


I would rather not have a thread running this the whole time the form
is open. Also, another problem with this method is that it is called
even when the form is not the focused window, and the &&
this.isFocused does not seem to help this at all.

If anyone has a better solution, please let me know!

Thanks
 
L

Ludovic SOEUR

for each control that do not catch TAB key, override IsInputKey method like
following :
protected override bool IsInputKey(Keys keyData) {
if (keyData==Keys.Tab) return true;
return base.IsInputKey (keyData);
}

Now, KeyDown event will be called if TAB key is pressed.

Hope it helps,

Ludovic Soeur.



supster said:
Hello, I'm trying to capture when users press the tab key. This is
scrolling through different fields with tab is broken in my form. I'm
not sure why, but it may have something to do with the fact that the
Windows Shell is creating the form (it is defined in a DLL). I copy
and pasted the form's code over to another application which created
the form through an executable, and tabbing worked fine - so that is
my only guess.

Anyway, I'd like to be able to manually recreate the tabbing feature
(including shift+tab and ctrl+tab), I have no problem writing the
functions to do this, however I cannot find out when tab (or
shift+tab) is pressed.

The KeyPressed event is not called, and the only solution I have found
is the following:

[System.Runtime.InteropServices.DllImport("User32",
EntryPoint="GetKeyState", ExactSpelling=false,
CharSet=System.Runtime.InteropServices.CharSet.Ansi,
SetLastError=true)]
private static extern int GetKeyState(long nVirtKey);
private const int VK_TAB = 0X9;
private const int VK_SHIFT = 0X10;

..

while(true)
{
iRetVal = GetKeyState(VK_TAB);
if ((iRetVal == -128 || iRetVal == -127) &&
this.isFocused)
{
MessageBox.Show("Tab Key Pressed");
}
System.Threading.Thread.Sleep(25);
}


I would rather not have a thread running this the whole time the form
is open. Also, another problem with this method is that it is called
even when the form is not the focused window, and the &&
this.isFocused does not seem to help this at all.

If anyone has a better solution, please let me know!

Thanks
 
S

supster

Awsome, this works... however is there any easier way to catch tab
pressed anywhere on the form other than overriding the method for
each possible control that may be focused?
Posted at: http://www.groupsrv.com
 
L

Ludovic SOEUR

There is a simple way, maybe it is what you were looking for. The trick is
the use of Application AddMessageFilter method. You only have to design your
own TabKeyCatcher class to do exactly what you want.
Use the following lines :

using System;
using System.Windows.Forms;

public class Form1 : System.Windows.Forms.Form {
...
...
...
[STAThread]
static void Main() {
Application.AddMessageFilter(new TabKeyCatcher());
Application.Run(new Form1());
}
...
...
...
public Form2() {
InitializeComponent();

...
...
}
private void InitializeComponent() {
...
...
}
...
...
...
}

class TabKeyCatcher:IMessageFilter {
public const int WM_KEYDOWN=0x0100;
public bool PreFilterMessage(ref Message m) {
if (m.Msg==WM_KEYDOWN) {
if (m.WParam.ToInt32()==(int)Keys.Tab) {
MessageBox.Show("Tab Key was pressed");
}
}
return false;
}
}

Hope it helps,

Ludovic Soeur.


supster said:
Awsome, this works... however is there any easier way to catch tab
pressed anywhere on the form other than overriding the method for
each possible control that may be focused?
Posted at: http://www.groupsrv.com
 
S

supster

Thanks a lot!

However, I don't have a main function. The form is created by a call
from another program (this is a DLL). Can I call
Application.AddMessageFilter from the form's constructor?
Posted at: http://www.groupsrv.com
 
S

supster

Ok, well now I need to check if shift and control are down or not :)

Is there any better way to check other than something like:


if (m.Msg==WM_KEYDOWN)
{
if (m.WParam.ToInt32()==(int)Keys.Shift)
shiftDown = true;
}

if (m.Msg==WM_KEYUP)
{
if (m.WParam.ToInt32()==(int)Keys.Shift)
shiftDown = false;
}

Posted at: http://www.groupsrv.com
 
S

supster

Well surprise surprise... When I tested this earlier, I tested it in
my debugger program which is a simple windows application with a form
that simulates the Windows Shell making a call onto my DLL.

Everything worked fine and dandy.

Just now, I implemented this into my DLL to test it, and no go.
PreFilterMessage() is never even called, I think the Windows shell
reroutes messages to it's own function and it never gets to my
PreFilterMessage().

Anyone have any other ideas?
Posted at: http://www.groupsrv.com
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top