When VKs fail, using SendInput with keyboard scan codes instead often works.
The example below demonstrates how to simulate alt-tab with SendInput and keyboard scan codes.
The alt_tab function takes a count. It will simulate holding down the left alt key, hitting the tab key "count" times, then letting go of the left alt key.
The keypress delay is pretty big, mostly to give adequate time to visually demonstrate the effect. Shorter delays will be more efficient for automation, but you probably cannot remove them altogether.
I pass 1 as the input count to SendInput because I only want to send one at a time. Manipulating KEYBDINPUT timestamps does not work the way one might expect.
To build this example, start with a Win32 Console project.
#include <Windows.h>
void sendkey(WORD scan_code, bool tf_down_up, bool extended=false) {
INPUT input = {0};
input.type = INPUT_KEYBOARD;
input.ki.wScan = scan_code;
input.ki.dwFlags = KEYEVENTF_SCANCODE;
if(!tf_down_up) input.ki.dwFlags |= KEYEVENTF_KEYUP;
if(extended) input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
SendInput(1, &input, sizeof(input));
}
void keydown(WORD scan_code, bool extended=false) {
sendkey(scan_code, true, extended);
}
void keyup(WORD scan_code, bool extended=false) {
sendkey(scan_code, false, extended);
}
static const WORD TAB_SCANCODE = 0x0f;
static const WORD LEFT_ALT_SCANCODE = 0x38;
static const DWORD keypress_delay_ms = 500;
void alt_tab(int tab_count=1) {
keydown(LEFT_ALT_SCANCODE);
Sleep(keypress_delay_ms);
for(int i=0; i<tab_count; ++i) {
keydown(TAB_SCANCODE);
Sleep(keypress_delay_ms);
keyup(TAB_SCANCODE);
Sleep(keypress_delay_ms);
}
keyup(LEFT_ALT_SCANCODE);
}
int main() {
Sleep(1000);
alt_tab(3);
}