Discussion:
PreTranslateMessage and Ctrl + A
(too old to reply)
Guido Franzke
2007-07-25 16:42:17 UTC
Permalink
Hello NG,

how can I check in PreTranslateMessage, if the user has pressed Ctrl and A?

if(pMsg->message==WM_KEYDOWN)
{
pMsg->wParam; //?? Ctrl+A ?
pMsg->lParam; //?? Ctrl+A ?
}

Thanks for help,
Guido
Doug Harrison [MVP]
2007-07-25 16:57:29 UTC
Permalink
Post by Guido Franzke
Hello NG,
how can I check in PreTranslateMessage, if the user has pressed Ctrl and A?
if(pMsg->message==WM_KEYDOWN)
{
pMsg->wParam; //?? Ctrl+A ?
pMsg->lParam; //?? Ctrl+A ?
}
Thanks for help,
Guido
The wParam will contain 'A', and you can check the state of the Ctrl key
(at the time the WM_KEYDOWN message was generated; this is important!) by
using GetKeyState.
--
Doug Harrison
Visual C++ MVP
Guido Franzke
2007-07-25 17:05:39 UTC
Permalink
Thanks, but this does not work:

if(pMsg->message==WM_KEYDOWN)
{
if (GetKeyState(VK_CONTROL)==1)
{
if (pMsg->wParam=='a')
{
MessageBox("Ctrl+A");
return TRUE;
}
}
}

I never run in the GetKeyState==1 clause.
What's wrong?
Post by Doug Harrison [MVP]
Post by Guido Franzke
Hello NG,
how can I check in PreTranslateMessage, if the user has pressed Ctrl and A?
if(pMsg->message==WM_KEYDOWN)
{
pMsg->wParam; //?? Ctrl+A ?
pMsg->lParam; //?? Ctrl+A ?
}
Thanks for help,
Guido
The wParam will contain 'A', and you can check the state of the Ctrl key
(at the time the WM_KEYDOWN message was generated; this is important!) by
using GetKeyState.
--
Doug Harrison
Visual C++ MVP
Doug Harrison [MVP]
2007-07-25 17:43:41 UTC
Permalink
Post by Guido Franzke
if(pMsg->message==WM_KEYDOWN)
{
if (GetKeyState(VK_CONTROL)==1)
{
if (pMsg->wParam=='a')
{
MessageBox("Ctrl+A");
return TRUE;
}
}
}
I never run in the GetKeyState==1 clause.
What's wrong?
GetKeyState
http://msdn2.microsoft.com/en-us/library/ms646301.aspx
<q>
If the high-order bit is 1, the key is down; otherwise, it is up.
</q>

Since GetKeyState returns SHORT, which is a signed 16-bit integer, you can
use either:

if (GetKeyState() & 0x8000) ...
if (GetKeyState() < 0) ...

Also, I'm pretty sure you need to compare wParam to 'A', as I stated in my
last message.
--
Doug Harrison
Visual C++ MVP
Joseph M. Newcomer
2007-07-25 19:53:39 UTC
Permalink
Yes, it must be 'A' not 'a'. The value 'a', 0x61, is actually VK_NUMPAD1.

But why not check for WM_CHAR and ask if it is 0x0001, the value of control-A as a
character.
joe
Post by Doug Harrison [MVP]
Post by Guido Franzke
if(pMsg->message==WM_KEYDOWN)
{
if (GetKeyState(VK_CONTROL)==1)
{
if (pMsg->wParam=='a')
{
MessageBox("Ctrl+A");
return TRUE;
}
}
}
I never run in the GetKeyState==1 clause.
What's wrong?
GetKeyState
http://msdn2.microsoft.com/en-us/library/ms646301.aspx
<q>
If the high-order bit is 1, the key is down; otherwise, it is up.
</q>
Since GetKeyState returns SHORT, which is a signed 16-bit integer, you can
if (GetKeyState() & 0x8000) ...
if (GetKeyState() < 0) ...
Also, I'm pretty sure you need to compare wParam to 'A', as I stated in my
last message.
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Doug Harrison [MVP]
2007-07-25 20:33:05 UTC
Permalink
On Wed, 25 Jul 2007 15:53:39 -0400, Joseph M. Newcomer
Post by Joseph M. Newcomer
Yes, it must be 'A' not 'a'. The value 'a', 0x61, is actually VK_NUMPAD1.
But why not check for WM_CHAR and ask if it is 0x0001, the value of control-A as a
character.
The question is, why wait that long? :) Seriously, two reasons:

1. Ctrl+A might be bound to an accelerator, in which case, you won't get a
WM_CHAR.

2. I don't know the numeric value of Ctrl+A and don't want to know. :) Is
it even the same for every keyboard and every localized Windows?
--
Doug Harrison
Visual C++ MVP
Joseph M. Newcomer
2007-07-25 21:22:10 UTC
Permalink
Oops. 1. is a good point.

Point 2 deals with whether or not the program is looking for Ctrl + A (as a key
combination) or is looking for the shortcut key for "Select All", for example. How would
it be possible to look for an 'A' key on, say Korean, Hebrew, Japanese, or Arabic
keyboards, that as far as I can tell have no letter 'A' on them. So looking for the Ctrl
key plus the VK_A code is itself a culturally-biased test...if the purpose was to simulate
an accelerator, it would be more culturally-neutral to actually use an accelerator key, so
it can be localized to the appropriate key combination used. So perhaps the correct
question is whether or not it would actually be more appropriate to use an accelerator
table, thus eliminating issue 1, because in that case it would mean that an accelerator
*should* be used.

(Perhaps someone who is familiar with these keyboards can suggest how select-all, copy,
cut, and paste commands are described; are the numeric codes the same as for
roman-alphabet keyboards?).

So perhaps the question was, like many questions, far too narrow; instead of asking how to
solve a problem, it asked about how to implement a solution, which is not necessarily the
solution to the problem, but is just an implementation of something which may or may not
be related to solving whatever the problem is.
joe
Post by Doug Harrison [MVP]
On Wed, 25 Jul 2007 15:53:39 -0400, Joseph M. Newcomer
Post by Joseph M. Newcomer
Yes, it must be 'A' not 'a'. The value 'a', 0x61, is actually VK_NUMPAD1.
But why not check for WM_CHAR and ask if it is 0x0001, the value of control-A as a
character.
1. Ctrl+A might be bound to an accelerator, in which case, you won't get a
WM_CHAR.
2. I don't know the numeric value of Ctrl+A and don't want to know. :) Is
it even the same for every keyboard and every localized Windows?
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Guido Franzke
2007-07-26 11:14:58 UTC
Permalink
Ok, GetKeyState is < 0. I think I misunderstood the documentation.
VK_A does not exist, I regret. So I compared wParam with 'a', did not work,
with 'A', didn't work either. Other chars didn't work either.
The value is 65 that I must compare with. But I don't know why because 'a'
is ASCII 65. Do you know why?

Now this works well:

if(pMsg->message==WM_KEYDOWN)
{
if (pMsg->wParam==65 && GetKeyState(VK_CONTROL)<0)
{
MessageBox("yippie!");
return TRUE;
}
}
return CPropertyPage::PreTranslateMessage(pMsg);

Just another question. Is it ok to return TRUE instead of calling the base
class function?

Thanks for your help,
Guido
Doug Harrison [MVP]
2007-07-26 12:47:23 UTC
Permalink
Post by Guido Franzke
Ok, GetKeyState is < 0. I think I misunderstood the documentation.
VK_A does not exist, I regret. So I compared wParam with 'a', did not work,
with 'A', didn't work either. Other chars didn't work either.
The value is 65 that I must compare with. But I don't know why because 'a'
is ASCII 65. Do you know why?
No, I don't, because 'A' is the correct value to compare to. The value of
'A' is 65. The value of 'a' is 65+32 or 97.
Post by Guido Franzke
if(pMsg->message==WM_KEYDOWN)
{
if (pMsg->wParam==65 && GetKeyState(VK_CONTROL)<0)
Replace the 65 with 'A'. You must have done something else wrong if it
wasn't working before. And spaces are cheap! Use them:

if (pMsg->wParam == 'A' && GetKeyState(VK_CONTROL) < 0)
Post by Guido Franzke
{
MessageBox("yippie!");
return TRUE;
}
}
return CPropertyPage::PreTranslateMessage(pMsg);
Just another question. Is it ok to return TRUE instead of calling the base
class function?
If you don't want the base class to have any say in processing the message,
don't call it. For this function, it's perfectly reasonable not to call the
base class version.
--
Doug Harrison
Visual C++ MVP
Guido Franzke
2007-07-26 13:22:16 UTC
Permalink
Ok, thank you. Everything is working fine now :-)
Joseph M. Newcomer
2007-07-26 14:12:50 UTC
Permalink
There is a disclaimer somewhere that says VK_A through VK_Z have no symbolic names but are
represented by 'A' through 'Z'

Why write 65 when you can write 'A' which has the same effect but is readable?
joe
Post by Guido Franzke
Ok, GetKeyState is < 0. I think I misunderstood the documentation.
VK_A does not exist, I regret. So I compared wParam with 'a', did not work,
with 'A', didn't work either. Other chars didn't work either.
The value is 65 that I must compare with. But I don't know why because 'a'
is ASCII 65. Do you know why?
if(pMsg->message==WM_KEYDOWN)
{
if (pMsg->wParam==65 && GetKeyState(VK_CONTROL)<0)
{
MessageBox("yippie!");
return TRUE;
}
}
return CPropertyPage::PreTranslateMessage(pMsg);
Just another question. Is it ok to return TRUE instead of calling the base
class function?
Thanks for your help,
Guido
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Guido Franzke
2007-07-26 14:41:28 UTC
Permalink
You're right. I already write 'A' instead. I only thought I should use 'a'
because when you press Ctrl+A you actually press the Ctrl key and the 'a'.
Then I rememberd the ASCII table in a wrong way (because of 65)...
Thanks for your help.
Regards, Guido

Loading...