Instead of tracking the Tab
key, you can use the WM_MOUSEACTIVATE message to detect activation of the control with the mouse. You could either sub-class each control type you use and override the WndProc
method or use a NativeWindow listener class like the one presented below. Depending on how many types of controls you use, it may be less work and clutter to just sub-class those controls to provide a property that indicates that the control was selected using the mouse. It is your decision to make, but the pattern will be the same.
This code is a slight modification of the example shown in the MS documentation.
public class MouseActivateListener : NativeWindow
{
private Control parent;
public MouseActivateListener(Control parent)
{
parent.HandleCreated += this.OnHandleCreated;
parent.HandleDestroyed += this.OnHandleDestroyed;
parent.Leave += Parent_Leave;
this.parent = parent;
if (parent.IsHandleCreated)
{
AssignHandle(parent.Handle);
}
}
private void Parent_Leave(object sender, EventArgs e)
{
MouseActivated = false;
}
private void OnHandleCreated(object sender, EventArgs e)
{
AssignHandle(((Form)sender).Handle);
}
private void OnHandleDestroyed(object sender, EventArgs e)
{
ReleaseHandle();
}
public bool MouseActivated { get; set; }
[System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
protected override void WndProc(ref Message m)
{
const Int32 WM_MouseActivate = 0x21;
base.WndProc(ref m);
if (m.Msg == WM_MouseActivate && m.Result.ToInt32() < 3)
{
MouseActivated = true;
}
}
}
Example Usage:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private MouseActivateListener textBox1Listener;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
textBox1Listener = new MouseActivateListener(textBox1);
}
private void textBox1_Enter(object sender, EventArgs e)
{
if (textBox1Listener.MouseActivated)
{
MessageBox.Show("Mouse Enter");
}
else
{
MessageBox.Show("Tab Enter");
}
}
}