using the WM_KEYUP, can i see if the shift\control\alt keys was uped too?
cambalinho 142 Practically a Posting Shark
Edited by pritaeas because: Moved.
Dani AI
Generated
Short summary and practical tips. already showed the two common approaches: parse the keyboard lParam in the WM_KEY* messages, or query the key state APIs. Both are valid, but they have different guarantees and edge cases — use lParam when you need per-message details (scan code, extended flag, left/right), and use key-state queries when you just need to know "is this modifier down right now".
Important lParam bits to use when parsing WM_KEYDOWN/WM_KEYUP:
- bits 0–15: repeat count
- bits 16–23: scan code (use this to distinguish left vs right SHIFT)
- bit 24: extended-key flag (helps distinguish right-control/right-alt on many keyboards)
- bit 29: context code (set when ALT is down)
- bit 30: previous key state
- bit 31: transition state (set on key up)
These let you reliably detect left/right and whether the message is an ALT-system key (WM_SYS*).
GetKeyState vs GetAsyncKeyState: use them correctly. The high bit (0x8000) indicates the key is currently down; the low bit indicates it was pressed since the last call. For “is down” checks use & 0x8000. Inside a message handler GetKeyState is usually preferable; GetAsyncKeyState is global and is for polling outside normal message flow. Watch for race conditions if you mix message parsing with polling — storing modifier state on key down/up messages is the simplest robust approach.
Other practical notes: ALT combinations generate WM_SYSKEY* messages, so handle those if you care about ALT. Don’t cast wParam straight to char for characters; use TranslateMessage/ToUnicodeEx or the text-message path if you need the actual character for the current layout. For app-level shortcuts prefer RegisterHotKey; for low-level or global capture use a keyboard hook (WH_KEYBOARD_LL) or Raw Input.
triumphost 120 Posting Whiz
There's multiple ways to do it.. First the manual way:
1:
union KeyState
{
LPARAM lparam;
struct
{
unsigned nRepeatCount : 16;
unsigned nScanCode : 8;
unsigned nExtended : 1;
unsigned nReserved : 4;
unsigned nContext : 1;
unsigned nPrev : 1;
unsigned nTrans : 1;
};
};
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int special = 0;
switch(message)
{
case WM_KEYUP:
{
bool stored = false;
KeyState state;
state.lparam = lParam;
if(state.nExtended)
{
special = wParam;
stored = true;
}
switch(wParam)
{
case VK_CONTROL:
case VK_RCONTROL:
case VK_SHIFT:
case VK_RSHIFT:
case VK_MENU:
special = wParam;
stored = true;
break;
}
if(!stored)
{
switch(special)
{
case VK_CONTROL:
case VK_RCONTROL:
std::cout<<"CONTROL + "<<(char)(wParam)<<"\n";
special = 0;
break;
case VK_SHIFT:
case VK_RSHIFT:
std::cout<<"SHIFT + "<<(char)(wParam)<<"\n";
special = 0;
break;
case VK_MENU:
std::cout<<"ALT + "<<(char)(wParam)<<"\n";
special = 0;
break;
default:
std::cout<<(char)wParam<<"\n";
special = 0;
break;
}
break;
}
}
break;
case WM_SYSKEYDOWN:
{
special = wParam;
}
break;
}
}
and then the easy way:
2:
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
case WM_KEYUP:
{
bool is_special = false;
if((GetAsyncKeyState(VK_LCONTROL) & 1) || (GetAsyncKeyState(VK_CONTROL) & 1) || (GetAsyncKeyState(VK_RCONTROL) & 1))
{
std::cout<<"CONTROL";
is_special = true;
}
if((GetAsyncKeyState(VK_LSHIFT) & 1) || (GetAsyncKeyState(VK_SHIFT) & 1) || (GetAsyncKeyState(VK_RSHIFT) & 1))
{
if(is_special)
std::cout<<" + ";
std::cout<<"SHIFT";
is_special = true;
}
if(GetAsyncKeyState(VK_MENU) & 1)
{
if(is_special)
std::cout<<" + ";
std::cout<<"ALT";
is_special = true;
}
switch(wParam)
{
case VK_CONTROL:
case VK_LCONTROL:
case VK_RCONTROL:
case VK_SHIFT:
case VK_LSHIFT:
case VK_RSHIFT:
case VK_MENU:
std::cout<<"\n";
break;
default:
{
if(is_special)
std::cout<<" + ";
std::cout<<(char)tolower(wParam)<<"\n";
}
break;
}
}
break;
}
Edited by triumphost
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.