Link to home
Start Free TrialLog in
Avatar of knowlegdehunter
knowlegdehunter

asked on

Sending commands to a minimized application

Hi everybody ! I saw the same question in somewhere and i'm now so curious to know how to do it. In the example,  a minimized "windows Paint" was used, and the intention was a single click right in the middle creating then, a little dot in the blank window.Another example was a msn messenger window(minimized as well)and the intention was a click on "click here to sign in". But,,, none of them were working and the code was very complicated. Any easy way to accomplish this ?
Thanks !
Avatar of illusion_chaser
illusion_chaser

Take a look at this sample (includes Unit and Form files):

1. Open Minesweeper (Start -> Run -> winmine).
2. Minimize minesweeper window.
3. Run the program (which you compiled using included code, see below).
4. Click "Find Window" to get target window handle.
5. Click "send left mouse click" to send the mouse click.
6. Now check minesweeper window

----- Unit (Unit1.pas) -----

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Edit2: TEdit;
    Edit3: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var
  wndHandle: HWND;

procedure TForm1.Button1Click(Sender: TObject);
begin
  wndHandle := FindWindow(nil, PChar(Edit1.Text));
  Label2.Caption := 'window handle = ' + IntToStr(wndHandle);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  xpos, ypos, wParam, lParam: Integer;
begin
  xpos := StrToIntDef(Edit2.Text, 0); //x position
  ypos := StrToIntDef(Edit3.Text, 0); //y position

  wParam := MK_LBUTTON;
  lParam := ypos;
  lParam := lParam shl 16; //Set HiWord (ypos)
  //ShowMessage('ypos: ' + IntToStr(HiWord(lParam)));
  lParam := lParam + xpos; //Set LoWord (xpos)
  //ShowMessage('xpos: ' + IntToStr(LoWord(lParam)));

  SendMessage(wndHandle, WM_LBUTTONDOWN, wParam, lParam);
  SendMessage(wndHandle, WM_LBUTTONUP, wParam, lParam);
end;

end.

----- Form (Unit1.dfm) -----

object Form1: TForm1
  Left = 192
  Top = 107
  Width = 344
  Height = 170
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 8
    Top = 8
    Width = 77
    Height = 13
    Caption = 'window caption:'
  end
  object Label2: TLabel
    Left = 88
    Top = 56
    Width = 3
    Height = 13
  end
  object Label3: TLabel
    Left = 16
    Top = 72
    Width = 25
    Height = 13
    Caption = 'x pos'
  end
  object Label4: TLabel
    Left = 16
    Top = 96
    Width = 28
    Height = 13
    Caption = 'y pos:'
  end
  object Button1: TButton
    Left = 176
    Top = 24
    Width = 73
    Height = 25
    Caption = 'find window'
    TabOrder = 0
    OnClick = Button1Click
  end
  object Button2: TButton
    Left = 104
    Top = 72
    Width = 145
    Height = 41
    Caption = 'send left mouse button click'
    TabOrder = 1
    OnClick = Button2Click
  end
  object Edit1: TEdit
    Left = 8
    Top = 24
    Width = 161
    Height = 21
    TabOrder = 2
    Text = 'Minesweeper'
  end
  object Edit2: TEdit
    Left = 56
    Top = 72
    Width = 41
    Height = 21
    TabOrder = 3
    Text = '110'
  end
  object Edit3: TEdit
    Left = 56
    Top = 96
    Width = 41
    Height = 21
    TabOrder = 4
    Text = '90'
  end
end
Avatar of knowlegdehunter

ASKER

Hi buddy,
sorry for the late reply, i just tested your code,and for this specific example it's working fine. let me take a look with different app's and i'll get back to you !
Thanks again !
Hi  illusion_chaser,
I know it's not     "part of the game"  but ,could you just tell me if there's an easy way to get the app's coordinates ? Using minesweeper its easy because whatever you put in the edit1/edit2 you'll hit something. Could you help me on this too ? I think we're on the right path though, i'd like to make sure  its gonna work in different cases(applications).
Thank you !!
Hi there,

1. If you want to do it with your own application (if not, skip):
Well, the "easy" way to get the mouse button coordinates would be hooking up mouse and then intercepting API message of a target window. You will need to install the mouse hook using a dll (coz we need the hook to be global, in order to get API messages of other windows). And you will need an application, which will load that hook dll, and.... blah, blah...

2. Well, if you only need to know where you clicked another window (without writing your own code) there is an app. called WinSight32 (ws32.exe) it comes with Delphi (look in: start -> programs -> Borland Delphi 7 -> WinSight). Run WinSight, find your target window process, set needed options (select only mouse messages) and get your clicks.

Regards.
Just to make it shorter i would go through the second option. But even this one is giving me a hard time , after run winsight the computer gets too slow, any process takes too long and i can't figure how to use properly because i tried to see what i could get using windows messenger, i got tons of windows and now i didn't get any.I'll keep trying , if you have another good suggestion..that would be great !
Thanks !
If you can, download TestComplete software. It is a very good macro recorded/player. Click on record, click your target window, click stop recording, look at the script that TestComplete created from your clicks.

download/info url: http://www.automatedqa.com/downloads/testcomplete/index.asp
Hope this helps.
Avatar of CodedK
Listening...
...
knowlegdehunter this may come handy :
http://www.howtodothings.com/viewarticle.aspx?article=395
:)

Thanks for the link codedk, but illusion_chaser's solution is pretty much what i want i just need to make sure it works in different situations.(programs).


illusion_chaser : I got another tool to give me the coordinates already.Now i now i'm passing to the program the right info about the target window.But i got no clicks at all. As a last try, i would ask you to give me an example using MSN if you can. as i said befoe we're almost there, and if you can provide me with a working example  I'll close the question and give you the points, a little more actually(i don't have much more than that).  Could you  ?
Sorry and thanks ! :-)
Here is a code that clicks "Sign In" button on a minimized MSN Messenger (Unit + Form files).

----- Unit1.pas -----

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Edit2: TEdit;
    Edit3: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var
  hwndHandle, hwndButton: HWND;

procedure TForm1.Button1Click(Sender: TObject);
begin
  //Get messanger window handle
  hwndHandle := FindWindow(nil, PChar(Edit1.Text));

  //Get the button window handle
  hwndButton := GetWindow(hwndHandle, GW_CHILD);
  hwndButton := GetWindow(hwndButton, GW_HWNDNEXT);
  hwndButton := GetWindow(hwndButton, GW_CHILD);

  Label2.Caption := 'window handle = ' + IntToStr(hwndHandle) + ', button = ' + IntToStr(hwndButton);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  xpos, ypos, wParam, lParam: Integer;
begin
  xpos := StrToIntDef(Edit2.Text, 0); //x position
  ypos := StrToIntDef(Edit3.Text, 0); //y position

  wParam := MK_LBUTTON;
  lParam := ypos;
  lParam := lParam shl 16; //Set HiWord (ypos)
  //ShowMessage('ypos: ' + IntToStr(HiWord(lParam)));
  lParam := lParam + xpos; //Set LoWord (xpos)
  //ShowMessage('xpos: ' + IntToStr(LoWord(lParam)));

  SendMessage(hwndButton, WM_LBUTTONDOWN, wParam, lParam);
  SendMessage(hwndButton, WM_LBUTTONUP, wParam, lParam);
end;

end.

----- Unit1.dfm -----

object Form1: TForm1
  Left = 192
  Top = 107
  Width = 344
  Height = 170
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 8
    Top = 8
    Width = 77
    Height = 13
    Caption = 'window caption:'
  end
  object Label2: TLabel
    Left = 88
    Top = 56
    Width = 3
    Height = 13
  end
  object Label3: TLabel
    Left = 16
    Top = 72
    Width = 25
    Height = 13
    Caption = 'x pos'
  end
  object Label4: TLabel
    Left = 16
    Top = 96
    Width = 28
    Height = 13
    Caption = 'y pos:'
  end
  object Button1: TButton
    Left = 176
    Top = 24
    Width = 73
    Height = 25
    Caption = 'find window'
    TabOrder = 0
    OnClick = Button1Click
  end
  object Button2: TButton
    Left = 104
    Top = 72
    Width = 145
    Height = 41
    Caption = 'send left mouse button click'
    TabOrder = 1
    OnClick = Button2Click
  end
  object Edit1: TEdit
    Left = 8
    Top = 24
    Width = 161
    Height = 21
    TabOrder = 2
    Text = 'MSN Messenger'
  end
  object Edit2: TEdit
    Left = 56
    Top = 72
    Width = 41
    Height = 21
    TabOrder = 3
    Text = '35'
  end
  object Edit3: TEdit
    Left = 56
    Top = 96
    Width = 41
    Height = 21
    TabOrder = 4
    Text = '15'
  end
end
Ok, ok. Didn't work again, let me tell you what's going on before i give up.I tried different values on the edit boxes (x,y) using that program i told you, and nothing. The find window button gives me " button = 0 " .This last piece of information (button) is relevant for you ?
Thanks !
ASKER CERTIFIED SOLUTION
Avatar of illusion_chaser
illusion_chaser

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
All right man, i'll see what i can do based on your codes and the informations you provided me with. I'm not gonna bug you anymore, you did a great job showing me 2 examples and the explanation for that must be ( i really believe ) on the button or wherever i wanna click.I mean.... i need to find it's coordinates or something like that as described at the link above.I'll try that solution, and combining all the info i got so far from you,  including some other mouse emulation sutff, i may be able to end up with something usefull. Thank you very much !
Thanks and best regards.
ic
Hi again.
Actually, you need to get a handle of the "Sign In" button, and then send it a mouse click.
I was thinking... If you need to programatically sign into MSN (or control the Messenger in other way), there have to be some API (or a COM interface) you could use.

Resources I have found:
http://www.codeproject.com/com/msn_messenger.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_foxhelp/html/samcontrolling_msn_messenger.asp
http://www.mess.be/msnmessengerfaq/

Or you can always run a search on Google with "MSN Messenger API" and see what you get.
ic
Hey ....... Thanks guy !!!! i came back to this thread  by mistake when i clicked on the wrong bookmarked page.Not even took a look at the links yet, I don't care if i'll find what i need or not, your help was the most important thing in this matter thanks again. And.. as it could not be different if i get something that works i'll tell you here .
See you !
God bless you :-)

Note: i was already trying to get something like you suggested above ,emulate a mouse click on the button. Well... i'll let you know !
Hi IC ! are you there ?
as i asked you above..  " button = 0 " ???? Any comments ??
Hi there.

When I ran the last code I sent you I was getting a real button handle (not zero). So I was able to emulate the click on the "Sign In" button. I used MSN Messenger version 6.2.0205 (rather old).

ic
Well, i'm running 7.0 is there any reason for that ? Handle/coordinates are what they are, why the code doesn't catch it in differents versions or applications ??