dev/win32/ SyntheticKeyStrokes


Use SendInput

Prototype

UINT SendInput(
  [in] UINT    cInputs,
  [in] LPINPUT pInputs,
  [in] int     cbSize
);

Example 1

//**********************************************************************
//
// Sends Win + D to toggle to the desktop
//
//**********************************************************************
void ShowDesktop()
{
    OutputString(L"Sending 'Win-D'\r\n");
    INPUT inputs[4] = {};
    ZeroMemory(inputs, sizeof(inputs));

    inputs[0].type = INPUT_KEYBOARD;
    inputs[0].ki.wVk = VK_LWIN;

    inputs[1].type = INPUT_KEYBOARD;
    inputs[1].ki.wVk = VK_D;

    inputs[2].type = INPUT_KEYBOARD;
    inputs[2].ki.wVk = VK_D;
    inputs[2].ki.dwFlags = KEYEVENTF_KEYUP;

    inputs[3].type = INPUT_KEYBOARD;
    inputs[3].ki.wVk = VK_LWIN;
    inputs[3].ki.dwFlags = KEYEVENTF_KEYUP;

    UINT uSent = SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT));
    if (uSent != ARRAYSIZE(inputs))
    {
        OutputString(L"SendInput failed: 0x%x\n", HRESULT_FROM_WIN32(GetLastError()));
    } 
}

Example2

#include <windows.h>
#include <stdio.h>

typedef enum {
  kShift = 1,
  kCtrl = 2,
  kAlt = 4,
  kMeta = 8,
  kWin = 8
} ModifierKeys;

void SendKeys(const char* keys, size_t nkeys, ModifierKeys modifiers);

int main() {
  SendKeys("hello",5,kShift);
  SendKeys("v",1,kCtrl|kShift);
}

void SendKeys(const char* keys, size_t nkeys, ModifierKeys modifiers) {
  INPUT* inputs = (INPUT*)calloc(nkeys+8,sizeof(INPUT));
  ZeroMemory(inputs,2*nkeys*sizeof(INPUT));
  int j = 0;
  if( modifiers & kShift ) { 
    printf("shift\n"); 
    inputs[j].type = INPUT_KEYBOARD;
    inputs[j].ki.wVk = VK_SHIFT;
    j++;
  }
  if( modifiers & kCtrl ) { 
    printf("ctrl\n"); 
    inputs[j].type = INPUT_KEYBOARD;
    inputs[j].ki.wVk = VK_CONTROL;
    j++;
  }
  if( modifiers & kAlt ) { 
    printf("alt\n"); 
    inputs[j].type = INPUT_KEYBOARD;
    inputs[j].ki.wVk = VK_MENU;
    j++;
  }
  if( modifiers & kMeta ) { 
    printf("meta\n"); 
    inputs[j].type = INPUT_KEYBOARD;
    inputs[j].ki.wVk = VK_LWIN;
    j++;
  }
  for(int i=0; i<nkeys; i++ ) {
    char k = keys[i];
    printf("send %x\n",k);
    if( k >= 'a' && k <= 'z' ) {
      k -= 'a' - 'A';
      inputs[j].type = INPUT_KEYBOARD;
      inputs[j].ki.wVk = k;
      inputs[j+1].type = INPUT_KEYBOARD;
      inputs[j+1].ki.wVk = k;
      inputs[j+1].ki.dwFlags = KEYEVENTF_KEYUP;
      j += 2;
    } else if( k >= 'A' && k <= 'Z' ) {
      inputs[j].type = INPUT_KEYBOARD;
      inputs[j].ki.wVk = k;
      inputs[j+1].type = INPUT_KEYBOARD;
      inputs[j+1].ki.wVk = k;
      inputs[j+1].ki.dwFlags = KEYEVENTF_KEYUP;
      j += 2;
    } else if( k >= '0' && k <= '9' ) {
      inputs[j].type = INPUT_KEYBOARD;
      inputs[j].ki.wVk = k;
      inputs[j+1].type = INPUT_KEYBOARD;
      inputs[j+1].ki.wVk = k;
      inputs[j+1].ki.dwFlags = KEYEVENTF_KEYUP;
      j += 2;
    } 
  }
  if( modifiers & kMeta ) { 
    printf("meta up\n"); 
    inputs[j].type = INPUT_KEYBOARD;
    inputs[j].ki.wVk = VK_LWIN;
    inputs[j].ki.dwFlags = KEYEVENTF_KEYUP;
    j++;
  }
  if( modifiers & kAlt ) { 
    printf("alt up\n"); 
    inputs[j].type = INPUT_KEYBOARD;
    inputs[j].ki.wVk = VK_MENU;
    inputs[j].ki.dwFlags = KEYEVENTF_KEYUP;
    j++;
  }
  if( modifiers & kCtrl ) { 
    printf("ctrl up\n"); 
    inputs[j].type = INPUT_KEYBOARD;
    inputs[j].ki.wVk = VK_CONTROL;
    inputs[j].ki.dwFlags = KEYEVENTF_KEYUP;
    j++;
  }
  if( modifiers & kShift ) { 
    printf("shift up\n"); 
    inputs[j].type = INPUT_KEYBOARD;
    inputs[j].ki.wVk = VK_SHIFT;
    inputs[j].ki.dwFlags = KEYEVENTF_KEYUP;
    j++;
  }

  UINT uSent = SendInput(j, inputs, sizeof(INPUT));
  if( uSent != j ) {
    printf("SendInput failed: 0x%x\n", HRESULT_FROM_WIN32(GetLastError()));
  }
}

Add a few more keys

#include <windows.h>
#include <stdio.h>

typedef enum {
  kShift = 1,
  kCtrl = 2,
  kAlt = 4,
  kMeta = 8,
  kWin = 8
} ModifierKeys;

void SendKeys(const char* keys, size_t nkeys, ModifierKeys modifiers);

int main() {
  char *str = "echo hello worldR";
  printf("%s %d\n",str,strlen(str));
  SendKeys(str,strlen(str),0);
  //SendKeys("v",1,kCtrl|kShift);
}

// alt l r
// ctrl l r
// lwin rwin
// back delete end insert home
// return tab
//
const WORD specials[26] = {
  VK_MENU,VK_BACK,VK_CONTROL,VK_DELETE,VK_END, // A-E
  VK_LMENU,VK_RMENU,VK_HOME,VK_INSERT,0, // FGHIJ
  VK_LCONTROL,VK_RCONTROL,VK_LWIN,VK_RWIN,VK_APPS, // KLMNO
  VK_CAPITAL,VK_PAUSE,VK_RETURN,VK_SNAPSHOT,VK_TAB,// PQRST
  VK_PRIOR,VK_NEXT,// UV
  VK_LEFT,VK_RIGHT,VK_UP,VK_DOWN // WXYZ
};

void SendKeys(const char* keys, size_t nkeys, ModifierKeys modifiers) {
  INPUT* inputs = (INPUT*)calloc(nkeys+8,sizeof(INPUT));
  ZeroMemory(inputs,2*nkeys*sizeof(INPUT));
  int j = 0;
  if( modifiers & kShift ) { 
    printf("shift\n"); 
    inputs[j].type = INPUT_KEYBOARD;
    inputs[j].ki.wVk = VK_SHIFT;
    j++;
  }
  if( modifiers & kCtrl ) { 
    printf("ctrl\n"); 
    inputs[j].type = INPUT_KEYBOARD;
    inputs[j].ki.wVk = VK_CONTROL;
    j++;
  }
  if( modifiers & kAlt ) { 
    printf("alt\n"); 
    inputs[j].type = INPUT_KEYBOARD;
    inputs[j].ki.wVk = VK_MENU;
    j++;
  }
  if( modifiers & kMeta ) { 
    printf("meta\n"); 
    inputs[j].type = INPUT_KEYBOARD;
    inputs[j].ki.wVk = VK_LWIN;
    j++;
  }
  for(int i=0; i<nkeys; i++ ) {
    char k = keys[i];
    printf("send %c == %x\n",k,k);
    if( k >= 'a' && k <= 'z' ) {
      char s = k - ('a' - 'A');
      printf("char '%c' == '%c' == %x\n",k,s,s);
      inputs[j].type = INPUT_KEYBOARD;
      inputs[j].ki.wVk = s;
      inputs[j+1].type = INPUT_KEYBOARD;
      inputs[j+1].ki.wVk = s;
      inputs[j+1].ki.dwFlags = KEYEVENTF_KEYUP;
      j += 2;
    } else if( k >= 'A' && k <= 'Z' ) {
      char s = k-'A';
      printf("special %d = %x\n",k,s);
      k = specials[k-'A'];
      if( k ) {
        inputs[j].type = INPUT_KEYBOARD;
        inputs[j].ki.wVk = k;
        inputs[j+1].type = INPUT_KEYBOARD;
        inputs[j+1].ki.wVk = k;
        inputs[j+1].ki.dwFlags = KEYEVENTF_KEYUP;
        j += 2;
      }
    } else if( k >= '0' && k <= '9' ) {
      inputs[j].type = INPUT_KEYBOARD;
      inputs[j].ki.wVk = k;
      inputs[j+1].type = INPUT_KEYBOARD;
      inputs[j+1].ki.wVk = k;
      inputs[j+1].ki.dwFlags = KEYEVENTF_KEYUP;
      j += 2;
    } else if( k == ' ' || k == '-' || k == '=' || k == ';' || 
               k == '\'' || k == '#' || k == ',' || k == '.' || 
               k == '/' || k == '\\' || k == '`' ) {
      inputs[j].type = INPUT_KEYBOARD;
      inputs[j].ki.wVk = k;
      inputs[j+1].type = INPUT_KEYBOARD;
      inputs[j+1].ki.wVk = k;
      inputs[j+1].ki.dwFlags = KEYEVENTF_KEYUP;
      j += 2;
    }
  }
  if( modifiers & kMeta ) { 
    printf("meta up\n"); 
    inputs[j].type = INPUT_KEYBOARD;
    inputs[j].ki.wVk = VK_LWIN;
    inputs[j].ki.dwFlags = KEYEVENTF_KEYUP;
    j++;
  }
  if( modifiers & kAlt ) { 
    printf("alt up\n"); 
    inputs[j].type = INPUT_KEYBOARD;
    inputs[j].ki.wVk = VK_MENU;
    inputs[j].ki.dwFlags = KEYEVENTF_KEYUP;
    j++;
  }
  if( modifiers & kCtrl ) { 
    printf("ctrl up\n"); 
    inputs[j].type = INPUT_KEYBOARD;
    inputs[j].ki.wVk = VK_CONTROL;
    inputs[j].ki.dwFlags = KEYEVENTF_KEYUP;
    j++;
  }
  if( modifiers & kShift ) { 
    printf("shift up\n"); 
    inputs[j].type = INPUT_KEYBOARD;
    inputs[j].ki.wVk = VK_SHIFT;
    inputs[j].ki.dwFlags = KEYEVENTF_KEYUP;
    j++;
  }

  UINT uSent = SendInput(j, inputs, sizeof(INPUT));
  if( uSent != j ) {
    printf("SendInput failed: 0x%x\n", HRESULT_FROM_WIN32(GetLastError()));
  }
}