Solved

MapVirtualKey(Ex) problem with some virtual key codes

Posted on 2006-07-07
5
2,367 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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

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

Suggested Solutions

Title # Comments Views Activity
Folder Comparison 12 54
mapAB Challlenge 35 155
firstChar challenge 13 119
Authenticate using sesu from script 7 53
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 …
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
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.
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

792 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