Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 282
  • Last Modified:

sending messages to windows

Hi,

I'm trying to build an application, in which you can press some keys, and then, send the key to an application by typing in its window title. I have written an event handler attached to application.onmessage, which handles all keyup and keydown messages, it stores the given tMsg-Object in a global array, called Msgs. When clicking on the SendBtn, I send the messages in the right order TimesEdit.Value-times to the window with TitleEdit.Text in the titlebar.

Example: User presses a;b;c; and wants these key to be sent twice to a window called "untitled - notepad", the notepad editfield should then contain "abcabc".

here's the code:

procedure TMainForm.SendBtnClick(Sender: TObject);
  var I: integer;
      H, N, X: Cardinal;
begin
  H := GetHandleFromWindowTitle (TitleEdit.Text);
  N := TimesEdit.Value;
  X := 0;
//  SetActiveWindow (H);
  try
    while (not Cancel) and (X < N)do begin
      for I := 0 to high (Msgs) do begin
        PostMessage (H, Msgs [I].message, Msgs [I].wParam, Msgs [I].lParam);
//        DefWindowProc (H, Msgs [I].message, Msgs [I].wParam, Msgs [I].lParam);
//        SendMessage (H, Msgs [I].message, Msgs [I].wParam, Msgs [I].lParam);
      end;
      Application.ProcessMessages;
      Inc (X);
    end;
  finally
//    SetActiveWindow (Handle);
  end;
end;

I tried SendMessage, DefWindowProc and PostMessage, and none of them seem to work (no error, but also no effect). I have the right handle (using findwindow).

What could be wrong? None of the applications i tested this with seems to react to the messages. Do they get the messages at all?

Thanks
Rainer jr.
0
rvjr
Asked:
rvjr
1 Solution
 
stanko1Commented:
Ok here is something i think u will find helpful. This Unit send keys to Active Window or to Window of your choise. This is SendKeys.pas text:
.......................................
unit Sendkeys;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  TSendkeys = class(TComponent)
  private
    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }
  published
    { Published declarations }
    procedure SendKeys(const text: String);
    procedure SendKeysTo(WindowTitle : string; const text: String);
    procedure Delay(n: Integer);
    procedure MakeWindowActive(whandle: hWnd);
    function GetHandleFromWindowTitle(const titletext: string): hWnd;
  end;

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;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TSendkeys]);
end;

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

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

function TSendkeys.GetHandleFromWindowTitle(const titletext: string): hWnd;
var
 strbuf: Array[0..255] of Char;
begin
   result := FindWindow(PChar(0),
              StrPCopy(strbuf,titletext));
end;

procedure TSendkeys.SendKeys(const text: String);
var
   i: Integer;
   shift: Boolean;
   vk,scancode: 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
            {228 (F1) => $70 (vk_F1)}
            c := Ord(ch) - 116
         else if ch < #32 then
            c := Ord(ch)
         else
         begin
            vk :=VkKeyScan(ch);
            c :=LoByte(vk);
         end;
         scancode := MapVirtualKey(c,0);
         if not shift and (Hi(vk) > 0) then
            { $2A = scancode of VK_SHIFT }
            Keybd_Event(VK_SHIFT,$2A,0,0);
         Keybd_Event(c,scancode,0,0);
         Keybd_Event(c,scancode,
               KEYEVENTF_KEYUP,0);
         if not shift and (Hi(vk) > 0) then
            Keybd_Event(VK_SHIFT,
               $2A,KEYEVENTF_KEYUP,0);
      end;
      Application.ProcessMessages;
   end;
end;

procedure TSendkeys.SendKeysTo(WindowTitle : string; const text: String);
var   Window : hWnd;
begin
   Window := GetHandleFromWindowTitle(WindowTitle);
   MakeWindowActive(Window);
   Sendkeys(text);
end;

end.
..................................................
How to use it:
------------

1) procedure SendKeysTo(Titletext:string; const text :string);
-----------------------------------------------------------

This sends the specified text string to the window with the
specified title.

EX.: SendKeysTo('mIRC32','Hello'+SK_ENTER);
       

2) procedure SendKeys(const text: String);
------------------------------------------

Sends the given text to the active window.
 
   
3) function  GetHandleFromWindowTitle(const titletext: string): hWnd;
-----------------------------------------------------------

Gets the handle of the window with the given text.

   
4) procedure MakeWindowActive(whandle: hWnd);
---------------------------------------------

Makes the specified window active for keyboard events  


5) Key Constants
----------------

         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;
0
 
rvjrAuthor Commented:
Yes, I know how to use the functions in sendkeys.pas, but I am trying to build something on my own. the question is just: why does it not work, to "forward" all key messages to the other window?
0
 
CleanupPingCommented:
rvjr:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
EXPERTS:
Post your closing recommendations!  No comment means you don't care.
0
 
kacorretiredCommented:
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area for this question:
       accept stanko1's answer
Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Merry Christmas and happy new year!

kacor
EE Cleanup Volunteer
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

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