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);
}
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.