Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Detecting Ctrl from OnKeyDown?

824 views
Skip to first unread message

dav...@gmail.com

unread,
May 29, 2009, 2:35:59 PM5/29/09
to
I'm attempting to add some global hot keys to my application (Like Ctrl
+O to open, or Ctrl+P to print) I looked at the OnKeyDown method but
it appears to only tell me if Alt was pressed with the key, not Ctrl.

Is the OnKeyDown the right way to do this?
If so how do I get the Ctrl key info?

AliR (VC++ MVP)

unread,
May 29, 2009, 2:49:44 PM5/29/09
to
I would use an accelerator table instead. What type of app is this
(Doc/View or Dialog based)?

AliR.


<dav...@gmail.com> wrote in message
news:4626c8cb-2563-427b...@r3g2000vbp.googlegroups.com...

sg

unread,
May 29, 2009, 5:01:43 PM5/29/09
to

GetAsyncKeyState(VK_CONTROL)

other useful keystates are VK_LWIN, VK_RWIN, etc.

http://msdn.microsoft.com/en-us/library/ms927178.aspx

Tom Serface

unread,
May 29, 2009, 5:06:22 PM5/29/09
to
I would do this sort of thing in a PreTranslateMessage() function with code
similar to the following. Some here will argue about the use of
PreTranslateMessage(), but it works fine for me.

BOOL CMyClass::PreTranslateMessage(MSG* pMsg)
{

if(pMsg->message==WM_KEYDOWN) {
if (pMsg->wParam == 'p' && GetKeyState(VK_CONTROL) < 0) {
// Do something
return TRUE;
}
else if (pMsg->wParam == 'o' && GetKeyState(VK_CONTROL) < 0) {
// Do something
return TRUE;
}
}
return CMyClass::PreTranslateMessage(pMsg);
}


<dav...@gmail.com> wrote in message
news:4626c8cb-2563-427b...@r3g2000vbp.googlegroups.com...

Malachy Moses

unread,
May 29, 2009, 6:17:47 PM5/29/09
to

Global hot keys should be added using an accelerator table. Use of
OnKeyDown (or OnChar or whatever) is an abomination. In the words of
Paul DeLascia:

"Many programmers attempt to use OnChar. No, no, no! OnChar is a low-
level mungy-grungy sort of thing you want to avoid any time you can.
Even worse are WM_KEYDOWN, WM_ KEYUP, and the like. Who can deal with
that stuff? OnChar is OK if you want to restrict the characters
allowed in an edit control to, say, numeric digits, but any time you
want to map a key to a command, accelerators are the way to go."

See http://msdn.microsoft.com/en-us/magazine/cc301409.aspx

In addition, PreTranslateMessage should not be needed.
PreTranslateMessage would be needed only if you have a dialog-based
application and you need to override PreTranslateMessage in order to
add a call to ::TranslateAccelerator(). An MFC app with a CFrameWnd
already has this code; thus nothing more is needed beyond an entry in
the accelerator table if your app is not dialog-based. This is
explained at the DeLascia article cited above.

Stephen Myers

unread,
May 29, 2009, 6:19:54 PM5/29/09
to

Have you looked at using accelerators?

Steve

David Webber

unread,
May 30, 2009, 5:14:45 AM5/30/09
to

"sg" <s...@sg.com> wrote in message
news:%23$$PrCK4J...@TK2MSFTNGP05.phx.gbl...

> dav...@gmail.com wrote:
>>
>> I'm attempting to add some global hot keys to my application (Like Ctrl
>> +O to open, or Ctrl+P to print) I looked at the OnKeyDown method but
>> it appears to only tell me if Alt was pressed with the key, not Ctrl.
>>
>> Is the OnKeyDown the right way to do this?
>> If so how do I get the Ctrl key info?
>
> GetAsyncKeyState(VK_CONTROL)

If I remember right that tells you the state at the moment you call the
function, and GetKeyState() tells you the situation when the last keyboard
message arrived.

I wrote a utility function years ago and have never had to worry about it
since:

//===
// In a universally available header file:
//===

const UINT KBD_NONE = 0x00000000;
const UINT KBD_ALT = 0x00000004;
const UINT KBD_CTRL = 0x00000002;
const UINT KBD_SHIFT = 0x00000001;

const UINT KBD_CTRLSHIFT = (KBD_CTRL|KBD_SHIFT);
const UINT KBD_ALTCTRL = (KBD_ALT|KBD_CTRL);
const UINT KBD_ALTSHIFT = (KBD_ALT|KBD_SHIFT);
const UINT KBD_ALTCTRLSHIFT = (KBD_ALT|KBD_CTRL|KBD_SHIFT);


//===
// In my utilities library:
//===

UINT KeybdAltCtrlShift()
{
UINT uResult = 0;

if( GetKeyState( VK_MENU ) & 0x8000 ) uResult |= KBD_ALT;
if( GetKeyState( VK_CONTROL ) & 0x8000 ) uResult |= KBD_CTRL;
if( GetKeyState( VK_SHIFT ) & 0x8000 ) uResult |= KBD_SHIFT;

return uResult;
}


I use it in all sorts of places within responses to WM_CHAR and WM_KEYDOWN
and WM_SYSKEYDOWN.

Dave

--
David Webber
Author of 'Mozart the Music Processor'
http://www.mozart.co.uk
For discussion/support see
http://www.mozart.co.uk/mozartists/mailinglist.htm

Tom Serface

unread,
Jun 1, 2009, 5:00:09 PM6/1/09
to
That's a cool utility function. Thanks for sharing.

Tom

"David Webber" <da...@musical-dot-demon-dot-co.uk> wrote in message
news:OZAhjdQ4...@TK2MSFTNGP06.phx.gbl...

Tom Serface

unread,
Jun 1, 2009, 5:01:13 PM6/1/09
to
I think OP was doing a dialog application. That makes using an accelerator
key setup a little more difficult.

Tom

"Malachy Moses" <malach...@gmail.com> wrote in message
news:988a9b14-b09f-453c...@l32g2000vba.googlegroups.com...

AliR (VC++ MVP)

unread,
Jun 1, 2009, 5:17:42 PM6/1/09
to
Not that difficult, I think it's about 6 lines of code total. You just have
to call TranslateAccelerators in PreTranslateMessage. (Maybe 5 minutes worth
of work, but a lifetime of easy maintance.)

http://www.codeproject.com/KB/dialog/pretransdialog01.aspx

AliR.
P.S. I didn't see anything in the original post about the type of
application.


"Tom Serface" <t...@camaswood.com> wrote in message
news:4FA371AD-F448-4B40...@microsoft.com...

0 new messages