views:

195

answers:

3

I am trying to use PostMessage to send a tab key.

Here is my code:

// This class allows us to send a tab key when the the enter key
//  is pressed for the mooseworks mask control.   
public class MaskKeyControl : MaskedEdit
{
//  [DllImport("coredll.dll", SetLastError = true, CharSet = CharSet.Auto)]
//  static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam);

    [return: MarshalAs(UnmanagedType.Bool)]
    // I am calling this on a Windows Mobile device so the dll is coredll.dll
    [DllImport("coredll.dll", SetLastError = true)]
    static extern bool PostMessage(IntPtr hWnd, uint Msg, Int32 wParam, Int32 lParam);

    public const Int32 VK_TAB = 0x09;
    public const Int32 WM_KEYDOWN = 0x100;

    protected override void OnKeyDown(KeyEventArgs e)
    {
        if (e.KeyData == Keys.Enter)
        {
            PostMessage(this.Handle, WM_KEYDOWN, VK_TAB, 0);
            return;
        }
        base.OnKeyDown(e);
    }

    protected override void OnKeyPress(KeyPressEventArgs e)
    {
        if (e.KeyChar == '\r') 
            e.Handled = true;
        base.OnKeyPress(e);
    }
}

When I press enter the code gets called, but nothing happens. Then I press TAB and it works fine. (So there is something wrong with my sending of the Tab Message.)

+4  A: 

You really shouldn't post windows messages related to user input directly to windows controls. Rather, if you want to simulate input, you should rely on the SendInput API function instead to send the key presses.

Also, as Chris Taylor mentions in his comment, the SendKeys class can be used to send key inputs to an application in the event that you want to use an existing managed wrapper (instead of calling SendInput function yourself through the P/Invoke layer).

casperOne
For manageded code SendKeys might be a better option.http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx
Chris Taylor
I ended up using the keybd_event function. It is in the coredll.dll that is on the Windows Mobile device. This was the closest to that, so I am giving it the nod.
Vaccano
+1  A: 

PostMessage on key events does really really odd things.

In this case, maybe SendMessage with KEYDOWN, KEYPRESS, KEYUP (three calls) might work better.

Joshua
+1  A: 

An alternative to sending input messages to the control, you could be more explicit and do the following.

protected override void OnKeyDown(KeyEventArgs e)
{
  if (e.KeyCode == Keys.Enter)
  {
    if (Parent != null)
    {
      Control nextControl = Parent.GetNextControl(this, true);
      if (nextControl != null)
      {
        nextControl.Focus();
        return;
      }
    }
  }
  base.OnKeyDown(e);
}

This will set the focus to the next control on the parent when the enter key is pressed.

Chris Taylor
I have tried doing this and it does not work for some reason. Thanks though...
Vaccano