Solved

MapVirtualKey(Ex) problem with some virtual key codes

Posted on 2006-07-07
5
2,303 Views
Last Modified: 2013-11-20
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;
 }
0
Comment
Question by:mike_marquet
5 Comments
 
LVL 5

Expert Comment

by:bastibartel
ID: 17058247
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
 
LVL 11

Expert Comment

by:KurtVon
ID: 17058898
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
 
LVL 22

Accepted Solution

by:
mahesh1402 earned 50 total points
ID: 17070832
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
 

Author Comment

by:mike_marquet
ID: 17070981
To mahesh1402 :

One correction :

replace
 nScanCode |= 0x100; // Add extended bit
with
 nScanCode |= 0x1000000; // Add extended bit
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 17071058
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

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now