• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 567
  • Last Modified:

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
0
rickatseasoft
Asked:
rickatseasoft
  • 5
  • 3
  • 2
  • +1
1 Solution
 
AlexFMCommented:
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.
0
 
mahesh1402Commented:
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
0
 
AlexFMCommented:
What about CapsLock? There is documented way to do this - WM_CHAR message.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
rickatseasoftAuthor Commented:
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
0
 
AlexFMCommented:
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.
0
 
mac-will01Commented:
What about comparing to char('=')?
0
 
mac-will01Commented:
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?
0
 
mac-will01Commented:
One more note.

VK_OEM_PLUS == 0xBB
0
 
mac-will01Commented:
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);
0
 
rickatseasoftAuthor Commented:
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
0
 
mac-will01Commented:
No.

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
#endif
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 5
  • 3
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now