Solved

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

Posted on 2006-10-29
12
484 Views
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
0
Comment
Question by:rickatseasoft
  • 5
  • 3
  • 2
  • +1
12 Comments
 
LVL 48

Expert Comment

by:AlexFM
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.
0
 
LVL 22

Expert Comment

by:mahesh1402
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.

-MAHESH
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 17829578
What about CapsLock? There is documented way to do this - WM_CHAR message.
0
 

Author Comment

by:rickatseasoft
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.

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
 
LVL 48

Expert Comment

by:AlexFM
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.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 1

Expert Comment

by:mac-will01
ID: 17839580
What about comparing to char('=')?
0
 
LVL 1

Expert Comment

by:mac-will01
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?
0
 
LVL 1

Expert Comment

by:mac-will01
ID: 17839731
One more note.

VK_OEM_PLUS == 0xBB
0
 
LVL 1

Expert Comment

by:mac-will01
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);
ASSERT(VK_OEM_PLUS == aPlusKey);
0
 

Author Comment

by:rickatseasoft
ID: 17888366
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
 
LVL 1

Accepted Solution

by:
mac-will01 earned 250 total points
ID: 17915697
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

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

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: 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 …
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.
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…

708 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now