c++builderkeydownwndproc

WM_KEYDOWN in WndProc - doesn't trigger


I am trying to capture WM_KEYDOWN to process some keyboard events at the Form level. I know I can use KeyPreview=true and use the OnKeyDown event of TForm. However, I'd like to do it in the WndProc() to simplify event processing in a single function. The problem is, it doesn't fire in the WndProc(). Is there a particular reason why it doesn't? Aside from using BEGIN_MESSAGE_MAP to handle WM_KEYDOWN, is there another way?

void __fastcall TForm1::WndProc(TMessage &fMessage)
{
    switch (fMessage.Msg)
    {
        default:            break;

        case WM_KEYDOWN:    {
            TWMKeyDown KDMsg = reinterpret_cast<TWMKeyDown&>(fMessage);
            TShiftState KDSs = KeyDataToShiftState(KDMsg.KeyData); 

            if (KDMsg.CharCode == 'C' && KDSs.operator ==(TShiftState() << ssCtrl))
            {
                // Process CTRL+C key
                fMessage.Result = 1;
                return;
            }
        }
        break;
    }

    TForm::WndProc(fMessage);
}

Solution

  • Keyboard (and mouse) messages are posted to the window that has input focus. If a TForm has a child control that has the focus, the messages will go directly to the child's WndProc, not the Form's WndProc.

    That is where KeyPreview comes into play. When true, it tells child controls to forward their keyboard messages to their parent TForm for processing.

    Otherwise, you can alternatively use the TApplication(Events)::OnMessage event to handle input messages before they are dispatched to their target windows.