Link to home
Start Free TrialLog in
Avatar of chandas
chandas

asked on

processing key combinations

Hi guys. What's the best way for me to process Ctrl + VK_UP or Vtrl + VK_DOWN messages within a rich edit box? If a hook is in order, please show me the way.

Thanks

Senkwe
Avatar of jkr
jkr
Flag of Germany image

You can check the state of any key at any time using the 'GetKeyState()' function. This allows you to check any combination of keys cunsecutively. If you want to check a combination of keys using a single API call, you can accomplish taht using 'GetKeyboardState()'
Avatar of robpitt
robpitt

you can use a Keyboard Accelerator to map keypresses to wm_command messages.

To do this define an accelerator resource then load it with LoadAccelerator(). Now just add a call to TranslateAccelerator() in your main message loop, only if this returns false should you call TranslateMessage/DispatchMessage.

Search MSDN for "Keyboard Accelerators" for more info.

Try to filter the messages in PreTranslateMessage.
in this example COptionsPage2 inherits from CPropertyPage.
PreTranslateMessage is called for the application as well as for the relevant CWnd.

BOOL COptionsPage2::PreTranslateMessage(MSG* pMsg)
{
   int msg = pMsg->message;
   if (msg == WM_KEYDOWN || msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN) {
      //check if ctrl and what key was up or down
   }
   return CPropertyPage::PreTranslateMessage(pMsg);
}
Avatar of chandas

ASKER

Rob, thanks for the response. That looks like it would work for something other than my problem. I can't map key presses to a WM_COMMAND because all I want to do is move the cursor to a certain position in the rich edit box depending on the CTRL + VK_UP or DOWN combinations (via SetSel() for example) By the way, since it's a rich edit control, I'm effectively overriding the controls default behaviour.

Yarive...your second posting looks intriguing. I'm not sure I understand your "if" statement though. Not only that, I'm not sure that CTRL is a system key. I've tried to break in my code at the point when CTRL is pressed (in my OnSysKeyDown(...) method) and it only seems to recognise the ALT key.

The GetKeyboardState method actually works, just seems kludgy because I have to check in WM_KEYUP. By that time, if you've pressed the arrow key, WM_KEYDOWN will have been processed already and so the caret will move first before I check the state of the CTRL key. It's not bad, happens quite fast...but just doesn't feel right. I'll stick with that if it's the only way to go.

I actually thought setting a hook would be the best way. It probably is but I don't understand the code well.

Avatar of chandas

ASKER

Rob, thanks for the response. That looks like it would work for something other than my problem. I can't map key presses to a WM_COMMAND because all I want to do is move the cursor to a certain position in the rich edit box depending on the CTRL + VK_UP or DOWN combinations (via SetSel() for example) By the way, since it's a rich edit control, I'm effectively overriding the controls default behaviour.

Yarive...your second posting looks intriguing. I'm not sure I understand your "if" statement though. Not only that, I'm not sure that CTRL is a system key. I've tried to break in my code at the point when CTRL is pressed (in my OnSysKeyDown(...) method) and it only seems to recognise the ALT key.

The GetKeyboardState method actually works, just seems kludgy because I have to check in WM_KEYUP. By that time, if you've pressed the arrow key, WM_KEYDOWN will have been processed already and so the caret will move first before I check the state of the CTRL key. It's not bad, happens quite fast...but just doesn't feel right. I'll stick with that if it's the only way to go.

I actually thought setting a hook would be the best way. It probably is but I don't understand the code well.

Personally I reckon you could still go allong with the keyboard accelerator trick, you would bind Ctrl+Up to a unique command value and then upon recieving that unique command value message you do your SetSel() or whatever.

An alternative mechanism would be to subclass the entire control and intercept the WM_KEYUP/KEYDOWN messages.

Rob

BTW, what language/toolset are you using?
C/C++/WTL/MFC?
Avatar of chandas

ASKER

Hi Rob

I'm currently trying to wrap my head around WTL. Your keyboard accelerator trick sounds great. It seems though, that I have a bit of reading to do regarding that "unique command value" of yours.

I am actually subclassing the control and intercepting WM_KEYUP etc. Only problem is these messages refer to one key press, not two. WM_SYSKEYUP works great BUT...for some very strange reason, when I then use SetSel(...) and type a single character at the new caret position, it always prints out one of those funny ascii characters (typically a small square) I don't even WANT to get into how that could even possibly be happening. I'll take a kludge anyday if it saves me from days of traversing the innards of the Win32 API.

Thanks for all the help guys.

Senkwe
Avatar of chandas

ASKER

Hi Rob

I'm currently trying to wrap my head around WTL. Your keyboard accelerator trick sounds great. It seems though, that I have a bit of reading to do regarding that "unique command value" of yours.

I am actually subclassing the control and intercepting WM_KEYUP etc. Only problem is these messages refer to one key press, not two. WM_SYSKEYUP works great BUT...for some very strange reason, when I then use SetSel(...) and type a single character at the new caret position, it always prints out one of those funny ascii characters (typically a small square) I don't even WANT to get into how that could even possibly be happening. I'll take a kludge anyday if it saves me from days of traversing the innards of the Win32 API.

Thanks for all the help guys.

Senkwe
ASKER CERTIFIED SOLUTION
Avatar of robpitt
robpitt

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
>>and check the state of the Ctrl via
>>GetKeyState(VK_CONTROL)

That somewhat sounds familar to me - ooops, yes, saw it on this thread:

Question History
Comment
From: jkr  Date: 06/25/2001 11:22AM PST  
You can check the state of any key at any time using the 'GetKeyState()' function.