tags:

views:

43

answers:

1

I have an application using the following code to get input based on a file generated from a third party application.

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        const int WM_KEYDOWN = 0x100;
        const int WM_SYSKEYDOWN = 0x104;

        if ((msg.Msg == WM_KEYDOWN) || (msg.Msg == WM_SYSKEYDOWN))
        {
            switch (keyData)
            {
                case Keys.F1:
                    clicked_F1(null, null);
                    break;

                case Keys.F2:
                    clicked_F2(null, null);
                    break;

                case Keys.F3:
                    clicked_F3(null, null);
                    break;
            }
            return true;
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }

Form.TopMost is set to true and this.Activate() is called during the OnShown callback. This works on most machines but occasionally the keyboard input will not be passed to my application, windows help for example will pop up if F1 is pressed.

Can anyone explain this behavior? I need to ensure my form will receive these keyboard events.

Cheers, Richard

+3  A: 

Having your form TopMost is not sufficient to ensure this method runs. Your form also needs to have the focus. That requires calling its Activate() method (SetForegroundWindow in the Win32 API). Which is not guaranteed to run, you cannot steal the focus away from a window that the user is actively using. Only when enough time has passed since the last input event can you grab the focus.

Not sure what you are really trying to do, maybe you need a keyboard hook or use RegisterHotKey.

Hans Passant
Thanks Hans. I am setting the Activate() method in the OnShown callback. I need to place a window above a legacy Till application which is always running with TopMost set to provide an additional option for the users.
Richard
Well, Windows doesn't care much for that. I think pinvoking AttachThreadInput() might help, you'll need to get the TID of the UI thread of that program. GetWindowThreadProcessId().
Hans Passant
Absolutely correct it's not a conventional situation - I would love to be able to do it another way. I might get back to the drawing board and see if there is another option.
Richard