WM_CHAR and eating keystrokes
-
I have an EDIT box and I'd like to silently trap and eat certain characters. I can catch WM_CHAR, check for the key, and return 0. I guess I'm asking if this is the right thing to do? I'd prefer to catch WM_KEYDOWN, and somehow return something that says "don't bother translating this key. Do not translate. Do not send out WM_CHAR ..." But to no avail. ------ Here is another example. I want to convert every character typed to +2. So, if the user enters "abc" I want to print "cde" to the window. "ejv" == "glx". Following the above approach, if I capture and eat the "a" character in WM_CHAR, and then resend "c" ... naively, I'd capture the "c" and cancel it ... and send "e" ... etc etc. and I've got a crazy endless loop. Some languages have event handlers that include the character code by reference -- and if you change the character code - whatever you changed it to is what is passed to the underlying window. Is there a low level facility to do that in win32? Can I capture WM_KEYDOWN and change the key so that WM_CHAR is correct. Or, do I just need to manage some tricky key issues (if user didn't send this key, process it, else, cancel it and resend the new key). Should I bother with with the TranslateMessage function? I'm just sure this is a common enough idiom that someone else has asked this and has an elegant solution ... any pointers would be great! ---- One more example - I'm implementing vi or emacs ... and I've got a slew of keyboard commands. There are just times when converting keys to WM_CHAR is a waste of CPU. If I'm in vi's navigation mode - I really don't need to send any characters to the window. I guess I can keep canceling them in WM_CHAR -- but it seems there should be a more elegant way to do so ... I'm not a big fan of global hooks - but maybe they are warranted in this case? Thanks in advance for any suggestions, -Luther
-
I have an EDIT box and I'd like to silently trap and eat certain characters. I can catch WM_CHAR, check for the key, and return 0. I guess I'm asking if this is the right thing to do? I'd prefer to catch WM_KEYDOWN, and somehow return something that says "don't bother translating this key. Do not translate. Do not send out WM_CHAR ..." But to no avail. ------ Here is another example. I want to convert every character typed to +2. So, if the user enters "abc" I want to print "cde" to the window. "ejv" == "glx". Following the above approach, if I capture and eat the "a" character in WM_CHAR, and then resend "c" ... naively, I'd capture the "c" and cancel it ... and send "e" ... etc etc. and I've got a crazy endless loop. Some languages have event handlers that include the character code by reference -- and if you change the character code - whatever you changed it to is what is passed to the underlying window. Is there a low level facility to do that in win32? Can I capture WM_KEYDOWN and change the key so that WM_CHAR is correct. Or, do I just need to manage some tricky key issues (if user didn't send this key, process it, else, cancel it and resend the new key). Should I bother with with the TranslateMessage function? I'm just sure this is a common enough idiom that someone else has asked this and has an elegant solution ... any pointers would be great! ---- One more example - I'm implementing vi or emacs ... and I've got a slew of keyboard commands. There are just times when converting keys to WM_CHAR is a waste of CPU. If I'm in vi's navigation mode - I really don't need to send any characters to the window. I guess I can keep canceling them in WM_CHAR -- but it seems there should be a more elegant way to do so ... I'm not a big fan of global hooks - but maybe they are warranted in this case? Thanks in advance for any suggestions, -Luther
You didn't say if you are using MFC or not. If you are using MFC (and possibly WTL:confused: ) you can do this quite easily by overriding your CEdit derived class's PreTranslateMessage function and handling the WM_KEYDOWN message there.
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03 "Obviously ??? You're definitely a superstar!!!" - mYkel - 21 Jun '04 "There's not enough blatant self-congratulatory backslapping in the world today..." - HumblePie - 21 Jun '05 Within you lies the power for good - Use it!
-
You didn't say if you are using MFC or not. If you are using MFC (and possibly WTL:confused: ) you can do this quite easily by overriding your CEdit derived class's PreTranslateMessage function and handling the WM_KEYDOWN message there.
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03 "Obviously ??? You're definitely a superstar!!!" - mYkel - 21 Jun '04 "There's not enough blatant self-congratulatory backslapping in the world today..." - HumblePie - 21 Jun '05 Within you lies the power for good - Use it!
Ahh ... nice suggestion! I am not using WTL per se, but my own OO framework. I mimic several parts of the WTL including THUNKING the wndproc - but I've not worried about the PreTranslateMessage mechanism ... till now. So, conceptually, I don't want to translate WM_KEYDOWN to the WM_CHAR if it is a tab character ... I will read up - but I am guessing that PreTranslateMessage leads to TranslateMessage unless you return 0 or something like that ... I wonder if I can also change the keydown here as well ... At any rate, I think your point is ... I need to intercept the message before calling TranslateMessage - and the WTL lib provides an easy way to do this on a per HWND basis. Seems like alot of overhead ... does the MFC or WTL message loop call PreTranslateMessage for EVERY window class object? Thanks, -Luther
-
You didn't say if you are using MFC or not. If you are using MFC (and possibly WTL:confused: ) you can do this quite easily by overriding your CEdit derived class's PreTranslateMessage function and handling the WM_KEYDOWN message there.
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03 "Obviously ??? You're definitely a superstar!!!" - mYkel - 21 Jun '04 "There's not enough blatant self-congratulatory backslapping in the world today..." - HumblePie - 21 Jun '05 Within you lies the power for good - Use it!
This is EXACTLY what I was looking for Thanks PJ! BOOL DialogName::PreTranslateMessage(MSG* pMsg) { // TODO: Add your specialized code here and/or call the base class if(pMsg->message==WM_KEYDOWN) { if(pMsg->wParam==VK_RETURN || pMsg->wParam==VK_ESCAPE) pMsg->wParam=NULL ; } return CDialog::PreTranslateMessage(pMsg); }