Solved

PostMessage and SendMessage for my Game

Posted on 2010-11-25
9
730 Views
Last Modified: 2012-05-10
My doubt is the following

Using PostMessage or SendMessage

How can I send a command by the Delphi example to push a button in a program at my program.

Or How tightening an arrow.

And for that I want for example:
In the game that I play GTA, I would like for example to walk with the puppet, without playing.

Save the doll and directions go alone, even attacking what he sees.


It would be something like a bot, and do not know if permitted.

But this is an offline game and I always had this doubt, for many things.
0
Comment
Question by:RevangeSMill
  • 3
  • 2
  • 2
  • +2
9 Comments
 
LVL 14

Expert Comment

by:systan
ID: 34215140
uses windows,.......
procedure TForm1.Button1Click(Sender: TObject);

begin

     EnableWindow(Form1.Button1.Handle, False);

end;

Open in new window

0
 

Author Comment

by:RevangeSMill
ID: 34215147
EnableWindow(Form1.Button1.Handle, False);

EnableWindow ?

What effect this make ?
0
 
LVL 32

Expert Comment

by:ewangoya
ID: 34215159

You need to get the window handle of the application you intend to send the message to
Use FindWindow

Then use PostMessage
Your program has to handle the messsage sent
0
 
LVL 14

Expert Comment

by:systan
ID: 34215208
Oh, I though you want to disable a button, but from the other apps.
var

  DaHandle : HWND;

function GetHwnd(Handle : HWND; lParam : LPARAM) : Boolean;stdcall;

begin

  DaHandle := Handle;

  Result := True;

end;



function getwinname:string;

var

  n : array [0..MAX_PATH] of char;

begin

  if EnumThreadWindows(GetCurrentThreadId, @GetHwnd, 0) then begin

    GetWindowText(DaHandle, n, SizeOf(n));

    result := StrPas(n);

  end;

end;



procedure TForm1.Button1Click(Sender: TObject);

var

  h: HWND;

  s: array [0..MAX_PATH] of char;

begin

Form1.Caption := getwinname;

s:= Form1.Caption;

h := FindWindow(s, nil);

 if h <> 0 then

  begin

    //test

    SendMessage(h, WM_SYSCOMMAND, SC_CLOSE, 0);

  end;

end;

Open in new window

0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 14

Expert Comment

by:systan
ID: 34215216
try to look at from this link also;
http://www.swissdelphicenter.ch/torry/showcode.php?id=327
0
 
LVL 24

Expert Comment

by:jimyX
ID: 34215229
I am not sure if I got what you are trying to do:

I would like for example to walk with the puppet, without playing
Playing games is different than using applications. You can send WM_Command to the applications' controls (not all applications though) but games you will be sending keystrokes. Sending messages to games depends on mouse position and keyboard clicks.

Save the doll and directions go alone, even attacking what he sees.
Can not be done accurately without human interference.

something like a bot
What is bot ?

Have a look on the following example from Torry. It shows couple of methods that will help you.

http://www.swissdelphicenter.ch/torry/showcode.php?id=220

You will be interested in example 3:


{3. With keybd_event API}

procedure PostKeyExHWND(hWindow: HWnd; key: Word; const shift: TShiftState;
  specialkey: Boolean);
{************************************************************
 * Procedure PostKeyEx
 *
 * Parameters:
 *  hWindow: target window to be send the keystroke
 *  key    : virtual keycode of the key to send. For printable
 *           keys this is simply the ANSI code (Ord(character)).
 *  shift  : state of the modifier keys. This is a set, so you
 *           can set several of these keys (shift, control, alt,
 *           mouse buttons) in tandem. The TShiftState type is
 *           declared in the Classes Unit.
 *  specialkey: normally this should be False. Set it to True to
 *           specify a key on the numeric keypad, for example.
 *           If this parameter is true, bit 24 of the lparam for
 *           the posted WM_KEY* messages will be set.
 * Description:
 *  This procedure sets up Windows key state array to correctly
 *  reflect the requested pattern of modifier keys and then posts
 *  a WM_KEYDOWN/WM_KEYUP message pair to the target window. Then
 *  Application.ProcessMessages is called to process the messages
 *  before the keyboard state is restored.
 * Error Conditions:
 *  May fail due to lack of memory for the two key state buffers.
 *  Will raise an exception in this case.
 * NOTE:
 *  Setting the keyboard state will not work across applications
 *  running in different memory spaces on Win32 unless AttachThreadInput
 *  is used to connect to the target thread first.
 *Created: 02/21/96 16:39:00 by P. Below
 ************************************************************}
type
  TBuffers = array [0..1] of TKeyboardState;
var
  pKeyBuffers: ^TBuffers;
  lParam: LongInt;
begin
  (* check if the target window exists *)
  if IsWindow(hWindow) then
  begin
    (* set local variables to default values *)
    pKeyBuffers := nil;
    lParam := MakeLong(0, MapVirtualKey(key, 0));

    (* modify lparam if special key requested *)
    if specialkey then
      lParam := lParam or $1000000;

    (* allocate space for the key state buffers *)
    New(pKeyBuffers);
    try
      (* Fill buffer 1 with current state so we can later restore it.
         Null out buffer 0 to get a "no key pressed" state. *)
      GetKeyboardState(pKeyBuffers^[1]);
      FillChar(pKeyBuffers^[0], SizeOf(TKeyboardState), 0);

      (* set the requested modifier keys to "down" state in the buffer*)
      if ssShift in shift then
        pKeyBuffers^[0][VK_SHIFT] := $80;
      if ssAlt in shift then
      begin
        (* Alt needs special treatment since a bit in lparam needs also be set *)
        pKeyBuffers^[0][VK_MENU] := $80;
        lParam := lParam or $20000000;
      end;
      if ssCtrl in shift then
        pKeyBuffers^[0][VK_CONTROL] := $80;
      if ssLeft in shift then
        pKeyBuffers^[0][VK_LBUTTON] := $80;
      if ssRight in shift then
        pKeyBuffers^[0][VK_RBUTTON] := $80;
      if ssMiddle in shift then
        pKeyBuffers^[0][VK_MBUTTON] := $80;

      (* make out new key state array the active key state map *)
      SetKeyboardState(pKeyBuffers^[0]);
      (* post the key messages *)
      if ssAlt in Shift then
      begin
        PostMessage(hWindow, WM_SYSKEYDOWN, key, lParam);
        PostMessage(hWindow, WM_SYSKEYUP, key, lParam or $C0000000);
      end
      else
      begin
        PostMessage(hWindow, WM_KEYDOWN, key, lParam);
        PostMessage(hWindow, WM_KEYUP, key, lParam or $C0000000);
      end;
      (* process the messages *)
      Application.ProcessMessages;

      (* restore the old key state map *)
      SetKeyboardState(pKeyBuffers^[1]);
    finally
      (* free the memory for the key state buffers *)
      if pKeyBuffers <> nil then
        Dispose(pKeyBuffers);
    end; { If }
  end;
end; { PostKeyEx }

Open in new window

0
 
LVL 25

Accepted Solution

by:
epasquier earned 500 total points
ID: 34216038
This implements the lookup of the main window using the application name (the caption of the main form), using FindWindow

it does the match with either a starting string in the window name, or a string in it, and can do that with/without case consideration.

Ex: find a window that has 'pad' in it without case sensitive :
SearchMainWindowByName( '', 'pad', True );  // Will find 'NotePad'

Var

 SearchWindowList:TStrings;



function SearchMainWindowByName(Start:String;Mid:String='';UpC:boolean=True):THandle;

type

 RR=Record

     S,M:String;

     L:integer;

     U:boolean;

     hWindow:HWND;

    end;

 pRR=^RR;

Var

 R:RR;

 function EnumProcess(hHwnd: HWND; lParam : integer): boolean; stdcall;

 var

  pPid : DWORD;

  title, ClassName : string;

  R:pRR;

 begin

  //if the returned value in null the

  //callback has failed, so set to false and exit.

  if (hHwnd=0) then result := false else

   begin

    R:=pRR(lParam);

    //additional functions to get more

    //information about a process.

    //get the Process Identification number.

{$ifdef VER140}

      GetWindowThreadProcessId(hHwnd,pPid);

{$else}

      GetWindowThreadProcessId(hHwnd,@pPid);

{$endif}

    SetLength(ClassName, 255);

    SetLength(ClassName,

              GetClassName(hHwnd,

                           PChar(className),

                           Length(className)));

    SetLength(title, 255);

    SetLength(title, GetWindowText(hHwnd, PChar(title), Length(title)));

    //Display the process information

    //by adding it to a list box

    if Assigned(SearchWindowList) Then SearchWindowList.Add

      ('Class Name = ' + className +

       '; Title = ' + title +

       '; HWND = '+ IntToStr(hHwnd) +

       '; Pid = ' + IntToStr(pPid));

    if R^.U Then title:=UpperCase(title);

    if Copy(title,1,R^.L)=R^.S Then

     begin

      if (R^.M='')

       Or (Pos(R^.M,title)>0)

        Then R^.hWindow:=hHwnd;

     end;

    Result := true;

  end;

 end;

begin

 R.hWindow:=0;

 if UpC Then

  begin

   R.S:=UpperCase(Start);

   R.M:=UpperCase(Mid);

  end Else

  begin

   R.S:=Start;

   R.M:=Mid;

  end;

 R.L:=Length(Start);

 R.U:=Upc;

 if Assigned(SearchWindowList) Then SearchWindowList.Clear;

 EnumWindows(@EnumProcess,Integer(@R));

 Result:=R.hWindow;

end;

Open in new window

0
 
LVL 25

Expert Comment

by:epasquier
ID: 34216068
I forgot to say :
SearchWindowList:TStrings global variable is for debuging convenience, to put in a stringlist (memo.Lines for example) all windows enumerated
initialize it to nil if you don't want to use it.

and when you found the window handle, use PostKeyExHWND as JimyX said, see add-ons below
// I personnally added some default values for the last 2 parameters of PostKeyExHWND

procedure PostKeyExHWND(hWindow: HWnd; key: Word; const shift: TShiftState=[]; specialkey: Boolean=False);



// and added a helper function to send a whole string

procedure SendStringEx (Handle : HWND; vString : String);

var

 i: integer;

begin

 for i:=1 to length(vString) do

  begin

   PostKeyExHWND(Handle,ord(vString[i]));

//   sleep(1);  // if you need some tempo between keys

  end;

end;

Open in new window

0
 

Author Closing Comment

by:RevangeSMill
ID: 34452565
This help me a partially

Thanks
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Delphi Mdi application Child forms get behind control 7 162
Dev Express grid collapse 2 39
Firemonkey webbrowser scrollbars ? 1 29
Graphics32 under Delphi 10.1 Berlin 2 38
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Migrating to Microsoft Office 365 is becoming increasingly popular for organizations both large and small. If you have made the leap to Microsoft’s cloud platform, you know that you will need to create a corporate email signature for your Office 365…
As a trusted technology advisor to your customers you are likely getting the daily question of, ‘should I put this in the cloud?’ As customer demands for cloud services increases, companies will see a shift from traditional buying patterns to new…

867 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now