Trên thực tế, hãy phân biệt L / R Ctrl / Alt khi bạn bắt WM_KEYDOWN / WM_KEYUP, bạn có thể. Dễ thôi, không phải vậy, nhưng mã mà tôi sử dụng, ở đây bạn có thể có, hmm hmm.
Hy vọng điều này vẫn hoạt động, tôi làm.
// Receives a WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN or WM_SYSKEYUP message and
// returns a virtual key of the key that triggered the message.
//
// If the key has a common virtual key code, that code is returned.
// For Alt's and Ctrl's, the values from the KeyCodes enumeration are used.
int translateKeyMessage (MSG& Msg);
// Virtual key codes for keys that aren't defined in the windows headers.
enum KeyCodes
{
VK_LEFTCTRL = 162,
VK_RIGHTCTRL = 163,
VK_LEFTALT = 164,
VK_RIGHTALT = 165
};
// ======================================================================================
int translateKeyMessage (MSG& Msg)
{
// Determine the virtual key code.
int VirtualKeyCode = Msg.wParam;
// Determine whether the key is an extended key, e.g. a right
// hand Alt or Ctrl.
bool Extended = (Msg.lParam & (1 << 24)) != 0;
// If this is a system message, is the Alt bit of the message on?
bool AltBit = false;
if (Msg.message == WM_SYSKEYDOWN || Msg.message == WM_SYSKEYUP)
AltBit = (Msg.lParam & (1 << 29)) != 0;
if ((Msg.message == WM_SYSKEYUP || Msg.message == WM_KEYUP) && !Extended && !AltBit && VirtualKeyCode == 18)
{
// Left Alt
return KeyCodes::VK_LEFTALT;
}
// Left Ctrl
if (!Extended && !AltBit && VirtualKeyCode == 17)
{
// Peek for the next message.
MSG nextMsg;
BOOL nextMessageFound = PeekMessage(&nextMsg, NULL, 0, 0, PM_NOREMOVE);
// If the next message is for the right Alt:
if (nextMessageFound && nextMsg.message == Msg.message && nextMsg.wParam == 18)
{
//
bool nextExtended = (nextMsg.lParam & (1 << 24)) != 0;
//
bool nextAltBit = false;
if (nextMsg.message == WM_SYSKEYDOWN || nextMsg.message == WM_SYSKEYUP)
nextAltBit = (nextMsg.lParam & (1 << 29)) != 0;
// If it is really for the right Alt
if (nextExtended && !nextAltBit)
{
// Remove the next message
PeekMessage(&nextMsg, NULL, 0, 0, PM_REMOVE);
// Right Alt
return KeyCodes::VK_RIGHTALT;
}
}
// Left Ctrl
return KeyCodes::VK_LEFTCTRL;
}
if (Msg.message == WM_SYSKEYUP && !Extended && AltBit && VirtualKeyCode == 17)
{
// Peek for the next message.
MSG nextMsg;
BOOL nextMessageFound = PeekMessage(&nextMsg, NULL, 0, 0, PM_NOREMOVE);
// If the next message is for the right Alt:
if (nextMessageFound && nextMsg.message == WM_KEYUP && nextMsg.wParam == 18)
{
//
bool nextExtended = (nextMsg.lParam & (1 << 24)) != 0;
//
bool nextAltBit = false;
if (nextMsg.message == WM_SYSKEYDOWN || nextMsg.message == WM_SYSKEYUP)
nextAltBit = (nextMsg.lParam & (1 << 29)) != 0;
// If it is really for the right Alt
if (nextExtended && !nextAltBit)
{
// Remove the next message
PeekMessage(&nextMsg, NULL, 0, 0, PM_REMOVE);
// Right Alt
return KeyCodes::VK_RIGHTALT;
}
}
}
// Right Ctrl
if (Extended && !AltBit && VirtualKeyCode == 17)
return KeyCodes::VK_RIGHTCTRL;
// Left Alt
if (!Extended && AltBit && VirtualKeyCode == 18)
return KeyCodes::VK_LEFTALT;
// Default
return VirtualKeyCode;
}