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];
 
  GetKeyboardState(pData);
 
  WORD nChar;
 
  nRet = ToAsciiEx(nVirtualCode, nScanCode, pData, &nChar, 0, nHKL);
 
  if (nRet != 1) return szText;
 
  CString str;
 
  str.Format("%c", nChar);
 
  return str;
 }
mike_marquetAsked:
Who is Participating?
 
mahesh1402Connect With a Mentor Commented:
try with following function ....you 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));
              switch(nVK)
              {
      // 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);
            str.ReleaseBuffer();
            return bResult != FALSE;
}

-MAHESH
0
 
bastibartelCommented:
Hi mike_marquet,

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

LV_KEYDOWN *pLVKd = (LV_KEYDOWN*) pNMHDR;
                       
    switch (pLVKd->wVKey) //* always did the job for me.
    {
               case VK_ADD:
               case VK_DELETE: ...
    }

Cheers!
Sebastian
0
 
KurtVonCommented:
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.
0
 
mike_marquetAuthor Commented:
To mahesh1402 :

One correction :

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

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

e.g

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


-MAHESH
0
All Courses

From novice to tech pro — start learning today.