Three F-keys Gotchas

We recently did a small internal app, that had to use all 12 F-keys – which turned out to be surprisingly cumbersome. I hadn’t found this stuff concentrated on a single place, and certainly it could have saved me some trouble.

F1 Gotcha

Quote:

On Win32 systems, the operating system will generate the WM_HELP message when F1 is pressed.”

This isn’t much trouble if you don’t handle the message, as VK_F1 key message is still being sent. On MFC (and other) wizard generated apps, you might have to explicitly disable OnHelp on message maps:

BEGIN_MESSAGE_MAP(CMyWinApp, CWinApp)
…
  //ON_COMMAND(ID_HELP, CWinApp::OnHelp)   ! comment this
…
END_MESSAGE_MAP()

F10 Gotcha

Quote:

If the F10 key is pressed, the DefWindowProc function sets an internal flag. When DefWindowProc receives the WM_KEYUP message, the function checks whether the internal flag is set and, if so, sends a WM_SYSCOMMAND message to the top-level window. The WM_SYSCOMMAND parameter of the message is set to SC_KEYMENU.

So to get proper VK_F10 notifications, you can either bypass DefWindowProc completely – which is unfeasible, or handle specifically the WM_SYSCOMAND message. On MFC apps, that amounts to something like:

void MyWnd::OnSysCommand( UINT nID, LPARAM lParam )
{
  if(nID == SC_KEYMENU) // F10 pressed
    ::SendMessage(m_Child->GetHwnd(), WM_KEYDOWN, VK_F10, NULL);
    // The NULL in LPARAM is kinda sloppy. If you use key-message nuances, invest here a bit further.
  else
    __super::OnSysCommand(nID, lParam);
}

F12 Gotcha

This one is the most obscure – on some developer machines, pressing F12 seems to give a weird error message:

…This may be due to a corruption of the heap…  This may also be due to the user pressing F12…

To cut a long search short, this is a built in Win32 debugging feature. It can indeed be disabled through this registry key:

HKLM\Software\Microsoft\Windows NT\CurrentVersion\AeDebug\UserDebuggerHotkey

But contrary to what the connect page says, I wouldn’t advise to change it into just any nonzero value: this value is the scan code for the key that that would force a breakpoint!  If, for example, you change it to 0x9, you’d have the same problem while using the Tab key (on standard keyboards). I suggest setting the value to 0xFF – looking at some scan code tables around, I saw none that map it to an actual key.

Of course this issue would never manifest itself on customer machines, but solving it can make dev work much easier.

Afterthought

It seems an odd design choice to bake something as basic as F-keys handling so deep into the OS. I’m guessing this was done back when the wildest applications imaginable were word processors and spreadsheets, and the main design goals were to save what was perceived as boilerplate code rather than allow for flexibility. I still think modern app wizards should generate code that lets you opt-in, rather than opt out of these old key handling mechanisms.

Advertisements
This entry was posted in MFC, Win32. Bookmark the permalink.

4 Responses to Three F-keys Gotchas

  1. spritkopf says:

    I am currently struggling with connecting a function key with a command in an SDI application under MFC and Visual Studio 2010. Some time ago I introduced a function triggered by the F5 key and this works well. The F5 key is shown in the adjacent menu entry and the function is correctly called when pressing the key.

    Unfortunately I don’t remember what I did exactly to achieve this. I now wanted to assign F8 to another command and therefore I assigned VK_F8 in the accelerator table to the ID of the according menu entry (and hence to the function that is called by this menu entry). Unfortunately F8 is neither shown in the menu nor is the function called when F8 is pressed. Calling the function by clicking on the menu entry works. F8 isn’t used elsewhere in my programme and if I change the accelerator table entry to F9 or an unused Ctrl-Letter combination that doesn’t work either. The entries for F5 and F8 in the accelerator table look exactly the same (apart from the key and the command ID of course).

    Maybe you have a suggestion what I did wrong or what I forgot here.

    • Ofek Shilon says:

      Maybe you can search for VK_F5 in your project and see what you’ve done with it that you’ve missed for VK_F8?

      • spritkopf says:

        I searched for that as well as for the handling function and the command ID. Found nothing extraordinary.
        The funny thing: I made a quick SDI test application under my old Visual Studio 6 and then under VS 2010 again where I created a new menu entry, then a handler and finally an accelerator key for it. In VS 6 the accelerator worked, in VS 2010 it didn’t. Weird.

        I’ll keep you updated.

  2. spritkopf says:

    Ok, I’ve found it. Seems the workspace info in the registry was somehow clogged up and prevented the newly created accelerator key from showing up. How that happened I have no idea.

    Anyway – I called the Customize dialog (menu “View | Toolbars and Docking Windows | Customize…”) which was created by the MFC app wizard and on the Keyboard tab I clicked the button “Reset all”. That did it!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s