Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

MapVirtualKey(Ex) problem with some virtual key codes

Posted on 2006-07-07
5
Medium Priority
?
2,599 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 150 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

[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
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 shows how to quickly and easily deploy an email signature for all users in Office 365 and prevent it from being added to replies and forwards. (the resulting signature is applied on the server level in Exchange Online) The email signat…

916 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