Link to home
Start Free TrialLog in
Avatar of rickatseasoft
rickatseasoft

asked on

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

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
Avatar of AlexFM
AlexFM

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.
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.

-MAHESH
What about CapsLock? There is documented way to do this - WM_CHAR message.
Avatar of rickatseasoft

ASKER

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.

Alex:
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.

Rick
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.
What about comparing to char('=')?
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?
One more note.

VK_OEM_PLUS == 0xBB
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);
ASSERT(VK_OEM_PLUS == aPlusKey);
mac_will01:

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!
Rick
ASKER CERTIFIED SOLUTION
Avatar of mac-will01
mac-will01

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial