• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1173
  • Last Modified:

Sendkey

how can i send keystroke to a dos program in win xp environment from a delphi application
is there any freeware component for this perpose  
0
mhyassin
Asked:
mhyassin
1 Solution
 
mikelittlewoodCommented:
You will need to get a handle to the window of the DOS application before you can send anything to it

h: THandle;
h := FindWindow(nil, <YourAppName>);

I think will do the first part of what you need

Just found a good link for sending keys to any application/window you have open
http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20533728.html
0
 
qqppwwooCommented:
I suppose that the dos program will run in a cmd window (console). Your code should look like this:

var hnd:hwnd;
begin
  hnd:=FindWindow('ConsoleWindowClass','_window-caption_');
  if hnd<>0 then
  begin
     SetForegroundWindow(hnd);
     sendkeys('bla');
  end;
end;

this is the code for the unit with the sendkeys:

unit Winctl32;

interface

uses WinTypes, WinProcs;

{ Delay program execution by n milliseconds }
procedure Delay(n: Integer);

{ Display a warning message dialog }
procedure ShowWarningDialog(const msg: string);

{ Execute a command, such as to run a program }
function ShellExec(const op, fn, par, dir: String; show: Word): Boolean;

{ Functions to obtain handle of desired window }
function GetHandleFromWindowTitle(const titletext: string): hWnd;
function GetHandleFromWindowClass(const classname: string): hWnd;
function GetHandleOfActiveWindow: hWnd;

{ Functions to obtain identification of a window }
function GetWindowTitleText(whandle: hWnd): string;
function GetWindowClassName(whandle: hWnd): string;

{ Procedure to make a specific window the active one }
procedure MakeWindowActive(whandle: hWnd);

{ Procedure to position and size a specified window }
procedure SetWindowPosition(whandle: hWnd; top, left, width, height: Integer);

{ Send key strokes to active window }
procedure SendKeys(const text: String);

{ Constant key codes for special keys }
{ Note: these use byte values 228 - 255 so  }
{ the actual ASCII characters corresponding }
{ to these codes cannot be used.            }
const
  SK_BKSP = #8;
  SK_TAB = #9;
  SK_ENTER = #13;
      SK_ESC = #27;
      SK_F1 = #228;
  SK_F2 = #229;
  SK_F3 = #230;
  SK_F4 = #231;
  SK_F5 = #232;
      SK_F6 = #233;
  SK_F7 = #234;
      SK_F8 = #235;
  SK_F9 = #236;
  SK_F10 = #237;
  SK_F11 = #238;
  SK_F12 = #239;
  SK_HOME = #240;
  SK_END = #241;
  SK_UP = #242;
  SK_DOWN = #243;
  SK_LEFT = #244;
  SK_RIGHT = #245;
      SK_PGUP = #246;
      SK_PGDN = #247;
      SK_INS = #248;
      SK_DEL = #249;
      SK_SHIFT_DN = #250;
      SK_SHIFT_UP = #251;
      SK_CTRL_DN = #252;
      SK_CTRL_UP = #253;
      SK_ALT_DN = #254;
      SK_ALT_UP = #255;

implementation

uses Forms, Messages, SysUtils, ShellAPI;

procedure Delay(n: Integer);
var
      start: LongInt;
begin
      start := GetTickCount;
      repeat
            Application.ProcessMessages;
      until (GetTickCount - start) >= n;
end;

procedure ShowWarningDialog(const msg: string);
begin
      Application.MessageBox(PChar(msg),PChar(Application.Title),mb_ICONEXCLAMATION+mb_OK);
end;

function ShellExec( const op, fn, par, dir: String; show: Word): Boolean;
var
      OK: Boolean;
      Info: TShellExecuteInfo;
begin
      FillChar(Info, SizeOf(Info), Chr(0));
      Info.cbSize := SizeOf(Info);
      Info.fMask := SEE_MASK_NOCLOSEPROCESS;
      Info.lpVerb := PChar(op);
      Info.lpFile := PChar(fn);
      Info.lpParameters := PChar(par);
      Info.lpDirectory := PChar(dir);
      Info.nShow := show;
      Result := ShellExecuteEx(@Info);
      CloseHandle(Info.hProcess);
end;

function GetHandleFromWindowTitle(const titletext: string): hWnd;
begin
      result := FindWindow(PChar(0),PChar(titletext));
end;

function GetHandleFromWindowClass(const classname: string): hWnd;
begin
      result := FindWindow(PChar(classname),PChar(0));
end;

function GetHandleOfActiveWindow: hWnd;
begin
      result := GetForegroundWindow;
end;

function GetWindowTitleText(whandle: hWnd): string;
begin
      SetLength(Result,256);
      GetWindowText(whandle,PChar(Result),255);
      SetLength(Result,StrLen(PChar(Result)));
end;

function GetWindowClassName(whandle: hWnd): string;
begin
      SetLength(Result,256);
      GetClassName(whandle,PChar(Result),255);
      SetLength(Result,StrLen(PChar(Result)));
end;

procedure MakeWindowActive(whandle: hWnd);
begin
      if IsIconic(whandle) then
            ShowWindow(whandle,SW_RESTORE)
      else
            SetForegroundWindow(whandle);
end;

procedure SetWindowPosition(whandle: hWnd; top, left, width, height: Integer);
var
      position: TRect;
      w,h: Integer;
begin
      GetWindowRect(whandle,position);
      if width > 0 then w := width else w := position.right - position.left;
      if height > 0 then h := height else h := position.bottom - position.top;
      if top >= 0 then position.top := top;
      if left >= 0 then position.left := left;
      MoveWindow(whandle,position.left,position.top,w,h,true);
end;

procedure SendKeys(const text: String);
var
      i: Integer;
      shift: Boolean;
      vk,scancode,ss: Word;
      ch: Char;
      c,s: Byte;
const
      vk_keys: Array[0..9] of Byte =
            ( VK_HOME, VK_END, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_PRIOR, VK_NEXT, VK_INSERT, VK_DELETE);
      vk_shft: Array[0..2] of Byte = ( VK_SHIFT, VK_CONTROL, VK_MENU );
      flags: Array[false..true] of Integer = ( KEYEVENTF_KEYUP, 0 );

begin
      shift := false;
      for i := 1 to Length(text) do
      begin
            ch := text[i];
            if ch >= #250 then
            begin
                  s := Ord(ch) - 250;
                  shift := not Odd(s);
                  c := vk_shft[s shr 1];
                  scancode := MapVirtualKey(c,0);
                  Keybd_Event(c,scancode,flags[shift],0);
            end
            else
            begin
                  vk := 0;
                  if ch >= #240 then
                        c := vk_keys[Ord(ch) - 240]
                  else if ch >= #228 then
                        c := Ord(ch) - 116                        {228 (F1) ==> $70 (vk_F1)}
                  else if ch < #32 then
                        c := Ord(ch)
                  else
                  begin
                        vk := VkKeyScan(ch);
                        c := LoByte(vk);
                  end;
      s := HiByte(vk);
//  writeln('Char: '+ch+'  vk: '+IntToHex(c,2)+' shift: '+IntToHex(s,2));
                  scancode := MapVirtualKey(c,0);
                  if not shift and (s > 0) then
      begin
        if s = 6 then
        begin
                          Keybd_Event(VK_CONTROL,MapVirtualKey(VK_CONTROL,0),0,0);                  { $2A = scancode of VK_SHIFT }
          ss := VK_MENU;
        end
        else
          ss := VK_SHIFT;
                        Keybd_Event(ss,MapVirtualKey(ss,0),0,0);                  { $2A = scancode of VK_SHIFT }
      end;
                  Keybd_Event(c,scancode,0,0);
                  Keybd_Event(c,scancode,KEYEVENTF_KEYUP,0);
                  if not shift and (s > 0) then
      begin
                        Keybd_Event(ss,MapVirtualKey(ss,0),KEYEVENTF_KEYUP,0);
        if s = 6 then Keybd_Event(VK_CONTROL,MapVirtualKey(VK_CONTROL,0),KEYEVENTF_KEYUP,0);
      end;
            end;
            Application.ProcessMessages;
      end;
end;

end.

0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now