Detect when a + (Plus) key or = (equal) key has been pressed

Posted on 2006-10-29
Last Modified: 2013-11-20
It seemed like such a simple thing to do.  In PreTranslateMessage(), just look for the WM_KEYDOWN message, then look in wParam for one of the values.  Only when I look in Winuser.h, there is no value for VK_EQUAL or anything like it.  There is a value for VK_ADD which I assume to be the value passed when the + sign on the numeric keypad is pressed.  (I am out of the country, and using my laptop which has no keypad so I can't, at this point, be certain.)  When I press the +/= key at the top of the keyboard, it returns a 0xBB.  When I look in Winuser, there is no VK_???? that is equal to 0xBB.

Of course, I can catch the 0xBB, look for whether the shift key is pressed, and resolve the keystroke.  That is not a problem at all.  My question, is there a better way?  Is there another mneumonic or manifest that I am missing.  For all of the obvious reasons, it seems sort of jack-leg to resort to this.

One last thing, I need to catch the keystrokes very early in the process because the keystroke entered has very different results based on which control has focus at the time that the key is pressed.

Thanks in advance, Rick
Question by:rickatseasoft
  • 5
  • 3
  • 2
  • +1
LVL 48

Expert Comment

ID: 17828871
The better way is handling WM_CHAR message, where every key is translated to it's character value. You can compare wParam with '+' and "=" to know what key is pressed.
LVL 22

Expert Comment

ID: 17829429
As you said in your comments only Differnece is :

When you click on '+' sign from numpad you press just '+' otherwise you always press 'SHIFT+' which is not just plus but SHIFT & PLUS together so difference in virtual keycodes itself so you need to check both keys for SHIFT+ case
otherwise with numpad when you press '+' you always get VK_ADD..

      Son pretranslate you may check like :

            if(pMsg->wParam == 0xbb && ::GetKeyState(VK_SHIFT) & 0x8000 )
                                        // 'SHIFT' and '+' pressed

So as you said you need to check SHIFT along with + with virtual keycode except numpad + key.

LVL 48

Expert Comment

ID: 17829578
What about CapsLock? There is documented way to do this - WM_CHAR message.
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.


Author Comment

ID: 17833329
Alex and Mahesh:

Thanks for taking the time to comment.

Mahesh:  I believe that you missed my point.  I am able to do all that I want within PreTranslateMessage; however, since I am intercepting 0xbb which is not a manifest constant, it is inherently non-portable, and that problem is what I wanted to avoid.

Your answer seemed like the exact one that I was looking for; however, it doesn't work.  I should add that the keystrokes are passed straight through without any action unless the focus is on a specific CListCtrl, in which case the + or = keys have special meaning.  Whenever the CListCtrl has focus, the WM_CHAR message is being eaten somewhere else.  I haven't investigated enough to determine where it is being eaten, perhaps somewhere else in my code, but I am certain that it is not in PreTranslateMessage.

LVL 48

Expert Comment

ID: 17833547
Do you call CDialog::PreTranslateMessage? It is supposed to call TranslateMessage API which procuces WM_CHAR message from other keyboard messages. Remove your PreTranslateMessage temporary and check keyboard messages with Spy++.
Take a look also at ToAsciiEx and ToAscii functions.

Expert Comment

ID: 17839580
What about comparing to char('=')?

Expert Comment

ID: 17839643
Basically if your CListCtrl has focus it is getting the WM_CHAR messages so you need to make sure it is passing these messages up to its parent (I would guess a dialog) than just intercept them there.

Something like this in the message map

ON_NOTIFY(LVN_KEYDOWN, IDC_LIST1, &CtabDemoDlg::OnLvnKeydownList1)

Am I even on the right track here?

Expert Comment

ID: 17839731
One more note.


Expert Comment

ID: 17839826
Little code that might help:

SHORT aEqualKey = LOBYTE(VkKeyScan(TCHAR('=')));
SHORT aEqualKey_Modifier = HIBYTE(VkKeyScan(TCHAR('=')));

SHORT aPlusKey = LOBYTE(VkKeyScan(TCHAR('+')));
SHORT aPlusKey_Modifier = HIBYTE(VkKeyScan(TCHAR('+')));

ASSERT(aPlusKey_Modifier != aEqualKey_Modifier);
ASSERT(aEqualKey == aPlusKey);

Author Comment

ID: 17888366

Are you suggesting that I add VK_OEM_PLUS as a manifest?  I ask because a search of my computer yeilds no file containing that text.

As for the rest of your suggested code, I'll try to get to it this week.  Thanks!

Accepted Solution

mac-will01 earned 250 total points
ID: 17915697

What version of MFC are you using?

VK_OEM_PLUS should already be defined in "winuser.h"

I have the following lines in my winuser.h:

#define VK_OEM_1          0xBA   // ';:' for US
#define VK_OEM_PLUS       0xBB   // '+' any country
#define VK_OEM_COMMA      0xBC   // ',' any country
#define VK_OEM_MINUS      0xBD   // '-' any country
#define VK_OEM_PERIOD     0xBE   // '.' any country
#define VK_OEM_2          0xBF   // '/?' for US
#define VK_OEM_3          0xC0   // '`~' for US

Of course if you don't have it defined just redefine it it won't hurt.

#ifndef VK_OEM_PLUS
#define VK_OEM_PLUS       0xBB

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering 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
Creating Labels and Frequency list style reports in SAS code 9 105
isEverywhere  challenge 19 82
mapAB Challlenge 35 156
Problem to event 3 102
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: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
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.
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

860 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