Solved

MapVirtualKey(Ex) problem with some virtual key codes

Posted on 2006-07-07
5
2,479 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
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.
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…

627 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