Handling Keystrokes on a MFC Dialog

This is an easy topic that seems to stump most MFC newbies. Imagine this: You build a Dialog for your MFC application, all works great, until you need to keep track of keystrokes on your dialog. Having experience doing the same on your View (Mainframe) classes, you add a WM_KEYDOWN handler, confident that it will do it’s job.

Soon you discover that it doesn’t work, and after quick examination, you know it will never work. Why? Simply because the Dialog window (the parent of all controls on the dialog) never has the input focus. Focus is always on the hands of one of the child windows or controls.

What to do? The answer is easier than you think: Take advantage of a CWnd (from which CDialog is derived) virtual method: PreTranslateMessage(). By overriding PreTranslateMessage() on your CDialog derived class, you can easily peek on messages sent to your window before they are delegated to your child windows.

Knowing this, all you have to do is write a piece of code like this:


BOOL CMyDialog::PreTranslateMessage(MSG* pMsg)
{
   // TODO: Add your specialized code here and/or call the base class
   if (pMsg->message == WM_KEYDOWN)
   {
      // Do your thing here
      // Remember not to return without calling CDialog::PreTranslateMessage()
      // Unless you really know the consequences
   }
   return CDialog::PreTranslateMessage(pMsg);
}

A you can see, PreTranslateMessage() is a powerful method, and much more useful than just getting keystrokes. I’m sure you’ll put it to good use.