MapVirtualKey(Ex) problem with some virtual key codes

I have some problem converting my virtual key code to a scan code.

All works fine but not for some virtual key codes such as VK_INSERT, VK_HOME, VK_DELETE, VK_END, VK_PRIOR, VK_NEXT

The function is returns me the scan codes for the numpad keys.

After analysing, it seems that the lParam value returned by the WM_KEYDOWN message has a bit (24) set that the MapVirtualKey function doesn't set.

The bit 24 is : Extended-key flag. Distinguishes some keys on an enhanced keyboard

For example, for the VK_INSERT (0x2D) code, the WM_KEYDOWN returns 0x1520001 and the MapVirtualKey returns 0x520000

Here's the code of my function which converts a virtual key code to a string name representing the text (or character) pressed.

CString CKeyAssignatorEdit::TranslateVirtualCode(UINT nVirtualCode)
  HKL nHKL = GetKeyboardLayout( GetWindowThreadProcessId( GetForegroundWindow()->GetSafeHwnd() , NULL ) );

  UINT nScanCode = MapVirtualKeyEx(nVirtualCode, 0, nHKL);

  if (!lParam) lParam = MAKELONG(0, nScanCode);
  char szText[255];

  int nRet = GetKeyNameText(lParam, szText, sizeof(szText));
  if (!nRet) return "";
  if (nRet > 1) return szText;
  BYTE pData[256];
  WORD nChar;
  nRet = ToAsciiEx(nVirtualCode, nScanCode, pData, &nChar, 0, nHKL);
  if (nRet != 1) return szText;
  CString str;
  str.Format("%c", nChar);
  return str;
Who is Participating?
mahesh1402Connect With a Mentor Commented:
try with following function need to add extended bit for keys like VK_INSERT, VK_DELETE,VK_HOME etc....

//Pass virtual key code in 'nVK' and receive key name 'str'...

bool GetKeyName(UINT nVK, CString& str)
      UINT nScanCode = MapVirtualKeyEx(nVK, 0, GetKeyboardLayout(0));
      // Keys which are "extended" (except for Return which is Numeric Enter as extended)
      case VK_INSERT:
      case VK_DELETE:
      case VK_HOME:
      case VK_END:
      case VK_NEXT:  // Page down
      case VK_PRIOR: // Page up
      case VK_LEFT:
      case VK_RIGHT:
      case VK_UP:
      case VK_DOWN:
      nScanCode |= 0x100; // Add extended bit

      // GetKeyNameText() expects the scan code to be on the same format as WM_KEYDOWN Hence the left shift
            BOOL bResult = GetKeyNameText(nScanCode << 16, str.GetBuffer(20), 19);
            return bResult != FALSE;

Hi mike_marquet,

You don't happen to have a pNMHDR struct-ptr from an LVN_KEYDOWN event at your hands?

    switch (pLVKd->wVKey) //* always did the job for me.
               case VK_ADD:
               case VK_DELETE: ...

Well, first I should point out that a UINT on 32 bit macines is the same size as a Long, so the cal to MAKELON is actually erasing the top two bytes of the return code.

Also, I beleieve calling MapVirtualKeyEx with a map type of 0 is supposed to merge "equivalent" keys into a single keycode.  If you need to distinguish left and right you use a map type of 3.  I'm not sure if that affects the numeric keypad/cursor keys equivalence, though.

Hope this helps.
mike_marquetAuthor Commented:
To mahesh1402 :

One correction :

 nScanCode |= 0x100; // Add extended bit
 nScanCode |= 0x1000000; // Add extended bit
that makes any difference ?

if you try above function by passing directly vitual key code.. it shows correct value...


CString strKeyName;
MessageBox(strKeyName);  // This Gives You Correct Key Name VK_INSERT

All Courses

From novice to tech pro — start learning today.