Solved

Faking keyboard input

Posted on 1998-05-28
18
451 Views
Last Modified: 2013-12-03
Is there a way I can create a program that will "fake" keyboard input to a window not owned by that program ? For example, can I make a program that will launch Notepad (with ShellExecute, or something), and then cause it to type "Foo" ?
0
Comment
Question by:Sinclair
  • 4
  • 4
  • 3
  • +5
18 Comments
 
LVL 1

Expert Comment

by:Andy_Keys
ID: 1404618
You could try and find the window handle and send messages to it.  Rather clunky I know.
0
 
LVL 7

Expert Comment

by:faster
ID: 1404619
The best way to fake keyboard input is keybd_event API.
0
 
LVL 7

Expert Comment

by:faster
ID: 1404620
Of course you need to make sure that the target window is the active window before using keybd_event.
0
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

 
LVL 11

Expert Comment

by:alexo
ID: 1404621
I humbly suggest using a journal playback hook as a more foolproof method.
0
 
LVL 2

Author Comment

by:Sinclair
ID: 1404622
   Sorry, I am quite new at this. I saw the Journal Playback hook in the API docs, but it looks like I need to RECORD the keys first, somehow. I can't use that since I need to send an arbitrary sequence of keys.
    I also tried sending WM_KEYUP and WM_KEYDOWN messages, but they had absolutely no effect. What could I be doing wrong ?
0
 
LVL 7

Expert Comment

by:faster
ID: 1404623
did you try keybd_event()?
0
 
LVL 3

Expert Comment

by:jjmartin
ID: 1404624
Using Visual Basic, you can create a program that will shell execute a program and then using the SendKey command you can send keystrokes to the application as if they were coming from the keyboard.  This is not as easy as it sounds.  You have to delay your sendkeys until the app is completely up.  You can also check the return code from the Shell command to close the app once you are done.
0
 
LVL 11

Expert Comment

by:alexo
ID: 1404625
>> I saw the Journal Playback hook in the API docs, but it looks like I need to RECORD the keys first, somehow.

Not really.  You just have to fill the EVENTMSG structure with correct values.
0
 
LVL 2

Author Comment

by:Sinclair
ID: 1404626
Ah, sorry, I still don't get it :-(
What's an EVENTMSG structure ? I was just using standard Win API. I know about the VB SendKeys function, that's what I am trying to replicate.
0
 
LVL 11

Expert Comment

by:alexo
ID: 1404627
The EVENTMSG structure is what you use with a journalling playback hook.  It is usually filled by a journalling recording hook but you can do it yourself.  Check the SetWindowsHookEx() API.
0
 
LVL 13

Expert Comment

by:akb
ID: 1404628
You could try a program called WinBatch.  There's a trial version available somewhere on the web.
0
 
LVL 2

Author Comment

by:Sinclair
ID: 1404629
Thanks, I looked up the EVENTMSG structure. However, I still could not make the thing work. How do I prepare the lparam and wparam for the WM_KEY... messages ? And how do I get the "time" member of the structure ? Should I just use the current system time ? I understand that WinBatch works, but I would still like to implement the code myself. Is there any way this can be done ?
0
 
LVL 11

Expert Comment

by:alexo
ID: 1404630
>> How do I prepare the lparam and wparam for the WM_KEY... messages ?
Check the documentation of the WM_KEYxxx messages.  It is comprehensive.

>> Should I just use the current system time ?
Sounds good enough.

0
 
LVL 1

Accepted Solution

by:
vladimir_12345 earned 130 total points
ID: 1404631
Hi Sinclair!
This is a simple skileton that works (Win95, C).
 
#include <windows.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam,
                             LPARAM lParam);

void SendText(const char* Text);

#define CLASS   "KbdFake"
#define CAPTION "KbdFake"

#define NOTEPAD_TEXT "Foo"

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR
                   szCmdline, int iCmdShow)
{
 WNDCLASS wc;
 HWND     hwndMain;
 MSG      msg;

 wc.lpszClassName = CLASS;
 wc.hInstance     = hInst;
 wc.lpfnWndProc   = MainWndProc;
 wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
 wc.hIcon         = NULL;
 wc.lpszMenuName  = NULL;
 wc.hbrBackground = GetStockObject(LTGRAY_BRUSH);
 wc.style         = 0;
 wc.cbClsExtra    = 0;
 wc.cbWndExtra    = 0;
 if(!RegisterClass(&wc))
 {
  MessageBox(NULL, "Init Class Error.", CAPTION,
             MB_OK | MB_ICONSTOP);
  return FALSE;
 }

 hwndMain = CreateWindow(CLASS, CAPTION, WS_OVERLAPPEDWINDOW,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         NULL, NULL, hInst, NULL);
 if(!hwndMain)
 {
  MessageBox(NULL, "Create Window Error.", CAPTION,
             MB_OK | MB_ICONSTOP);
  return FALSE;
 }

 ShowWindow(hwndMain, iCmdShow);
 UpdateWindow(hwndMain);

 while(GetMessage(&msg, NULL, 0, 0))
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }

 return TRUE;
}

LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam,
                             LPARAM lParam)
{
 switch(msg)
 {
  case WM_DESTROY:
  {
   PostQuitMessage(0);
   return 0;
  }

  case WM_RBUTTONDOWN:
  {
   if((int)ShellExecute(NULL, NULL, "NOTEPAD.EXE", NULL, NULL,
                        SW_SHOWNORMAL) <= 32)
    MessageBox(NULL, "ShellExecute() Error.", CAPTION,
               MB_OK | MB_ICONSTOP);

   while(GetForegroundWindow() == hwnd);

   SendText(NOTEPAD_TEXT);
   return 0;
  }
 }

 return DefWindowProc(hwnd, msg, wParam, lParam);
}

void SendText(const char* Text)
{
 int i;
 int Len = strlen(Text);

 for(i=0; i<Len; i++)
 {
  BOOL IsUpperKey     = isupper(Text[i]);
  BOOL IsCapsLockDown = GetKeyState(VK_CAPITAL);
  BOOL UseShift       = ( IsUpperKey  && !IsCapsLockDown) ||
                      (!IsUpperKey  &&  IsCapsLockDown);
  BYTE VirtKey        = toupper(Text[i]);
  BYTE ScanCode       = MapVirtualKey(VirtKey, 0);

  if(UseShift)
   keybd_event(VK_SHIFT, (BYTE)MapVirtualKey(VK_SHIFT, 0), 0, 0);

  keybd_event(VirtKey, ScanCode, 0, 0);
  keybd_event(VirtKey, ScanCode, KEYEVENTF_KEYUP, 0);

  if(UseShift)
   keybd_event(VK_SHIFT, (BYTE)MapVirtualKey(VK_SHIFT, 0),
               KEYEVENTF_KEYUP, 0);
 }
}

0
 
LVL 2

Author Comment

by:Sinclair
ID: 1404632
Hi,
  How to simulate "ctrl+alt+del" sequence to start winnt login with user intervention. Above piece of code works for all key combination except this one.
0
 
LVL 1

Expert Comment

by:shankar_ms
ID: 1404633
Hi Shankar_ms! WIN works in the next sequence:
kbd interrupt -> kbd driver -> keybd_event() -> kbd message

"ctrl+alt+del" is processed in kbd driver only (system level) and
doesn't go to keybd_event() (there is no kbd message for this
key combination). I think to simulate "ctrl+alt+del" you have
to use kbd driver service.


0
 
LVL 1

Expert Comment

by:vladimir_12345
ID: 1404634
Hi vladmir

Do you know how to doit? I am new to keyboard driver?

ThANKS
Shankar
0
 
LVL 1

Expert Comment

by:shankar_ms
ID: 1404635
I work in Win95/98 and have no info about NT "ctrl+alt+del".
But I think you will not have a big problem to find anything
suitable in Internet. In the other side if you can find WIN NT
API call that have at the same result as "ctrl+alt+del"- this is
a better way.

0

Featured Post

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
error email attachment VB2010 5 39
Vb.Net Loading Word 11 103
Microsoft Query from QuickBooks 9 66
windbg taking it's time 32 90
This tutorial is about how to put some of your C++ program's functionality into a standard DLL, and how to make working with the EXE and the DLL simple and seamless.   We'll be using Microsoft Visual Studio 2008 and we will cut out the noise; that i…
This article describes a technique for converting RTF (Rich Text Format) data to HTML and provides C++ source that does it all in just a few lines of code. Although RTF is coming to be considered a "legacy" format, it is still in common use... po…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

785 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question