Solved

PostMessage and SendMessage for my Game

Posted on 2010-11-25
9
724 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
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

762 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

18 Experts available now in Live!

Get 1:1 Help Now