Textbox in ander programma bewerken, en "enteren"

Status
Niet open voor verdere reacties.

Mavamaarten

Gebruiker
Lid geworden
15 mei 2009
Berichten
94
Hallo iedereen.

Ik probeer een programma te maken, dat code in een gameconsole typt (en entert), wanneer er op een sneltoets wordt gedrukt. Alleen heb ik geen idee hoe dit aan te pakken. De console is een apart venster, en heeft als titel "aIW Console" (voor hwnd te bepalen ?)
screenies.png


Op google vond ik dat ik SendMessage moet gebruiken. Enkel weet ik niet helemaal hoe deze te gebruiken om tekst te sturen naar een textbox op een form. Ook heb ik er geen idee van hoe ik een enter moet sturen naar de textbox.
(Zonder natuurlijk sendkeys te gebruiken, want het programma dient ingame gebruikt te worden...)

Alvast bedankt,
Mavamaarten.
 
Het is toch niet helemaal duidelijk wat je nu wil.
Je wilt in de Console van het spel een opdracht typen en dan op Enter drukken,
waarbij de opdracht van kracht wordt in het spel, en dit automatiseren.
Wat die opdrachten zijn vermeld je niet, maar ik veronderstel dat het Cheats zijn.
Ik heb zelf het spel Modern Warfare 2 niet in mijn bezit,
maar Modern Warfare (COD4) bezit ik wel.
Ik gebruik de volgende methode om toetsen rechtstreeks te binden aan een Cheat.
Je rechtsklikt op de snelkoppeling waarmee je Modern Warfare 2 opstart,
en vervolgens klik je op Eigenschappen.
Onder het tabblad Snelkoppeling vind je het item Doel.
Plak de onderstaande vetgedrukte tekst achter het pad van de Executable in het item Doel.
Laat een spatie tussen het einde van het pad van de Executable en het begin van de nieuwe tekst.
Klik op Toepassen en OK

+seta thereisacow 1337 +bind A "give ammo" +bind Z "god" +bind E "notarget" +bind R "noclip"

Dit werkt voor COD4 en waarschijnlijk ook voor Modern Warfare 2.
Als je de aangepaste koppeling gebruikt om het spel op te starten,
dan zal je in het spel de bepaalde cheats krijgen,
door op de volgende toetsen te drukken.

A = Munitie aanvullen.
Z = God-modus (Onsterfelijkheid). Nogmaals indrukken schakelt God-modus terug uit.
E = Onzichtbaar voor de vijand. Nogmaals indrukken schakelt NoTarget terug uit.
R = Vlieg door obstakels en de lucht. Nogmaals indrukken schakelt NoClip terug uit.

Je kan de letters A, Z, E en R ook veranderen om andere toetsen te binden,
en het spreekt voor zich dat elke opdracht die je normaal in de Console zou typen,
ook geplaatst kan worden tussen de aanhalingstekens.

Het is ook mogelijk om het Configuratie-bestand van de speler te bewerken,
maar daar ga ik hier niet over uitweiden.
 
Laatst bewerkt:
Nee, je begrijpt idd niet echt wat ik wil.
Ik wil een friend join/invite systeem maken. Ik weet hoe ik alles moet maken met verbindingen,... het enige wat ik niet weet is hoe ik dingen in die console kan typen en enteren.

BIJVOORBEELD.

Ik wil met Jasper verbinden. Ik heb deze ingesteld op de toets F2.
Het programma typt dan "Connect 94.121.XXX.XXX" en drukt op enter.
Hierdoor verbind ik met Jasper. Snapje ?
 
Je kunt inderdaad het beste met SendMessage werken. Het gebruik ervan is an sich niet zo heel moeilijk.

[cpp]
LRESULT WINAPI SendMessage(
__in HWND hWnd,
__in UINT Msg,
__in WPARAM wParam,
__in LPARAM lParam
);
[/cpp]

SendMessage: http://msdn.microsoft.com/en-us/library/ms644950(VS.85).aspx
(klik op de link voor een volledige omschrijving)

Het eerste argument is de handle waar het bericht naartoe moet worden verstuurd. In jouw geval wil je dat dus naar de textbox binnen de console sturen. Je zal daarom FindWindow en FindWindowEx moeten combineren om een handle naar die textbox te krijgen. Het tweede argument is het soort bericht dat verstuurd moet worden, wat in dit geval WM_SETTEXT wordt. Het derde argument is in dit geval niet van belang en krijgt daarom de waarde 0. Het vierde en laatste argument is in dit geval de tekst die je wenst in te stellen.

Een voorbeeld van wat je zou willen in C++ (zou vrij gemakkelijk te vertalen moeten zijn naar C#):

[cpp]
std::string tekst = "blaat";
HWND h1, h2;

h1 = FindWindow(0, "aIW Console");
h2 = FindWindowEx(h1, 0, "Edit", 0);

SendMessage(h2, WM_SETTEXT, 0, (LPARAM)tekst.c_str()); // verstuur tekst
SendMessage(h2, WM_CHAR, 13, 0); // verstuur enter
[/cpp]

(Je kunt Spy++ gebruiken om alle benodigde informatie te verkrijgen)
 
Laatst bewerkt:
Ahhh :)
bedankt voor je simpele en duidelijke uitleg, ik ben momenteel op vakantie, maar als ik thuis kom zal ik het dadelijk proberen !

Bedankt CoD_NL !!
 
Ahhh :)
bedankt voor je simpele en duidelijke uitleg, ik ben momenteel op vakantie, maar als ik thuis kom zal ik het dadelijk proberen !

Bedankt CoD_NL !!

Normaal gesproken moet je dan wel nog eerst controleren of je een geldige handle hebt teruggekregen, want anders gaat er uiteraard iets mis :p
 
Nogal moeilijk als je niet thuis bent :d
Ik programmeer in VB.Net, niet C#. Het zal mij echter wel moeten lukken om de code werkend te krijgen, kben er nu mee bezig.
SPYXX.exe kan ik in elk geval al nie vinden... :confused:

EDIT :

Dit is de code die ik gebruik op dit moment (omgezet van CoD_NL's code) :

Code:
Option Explicit Off
Public Class Form1
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Object) As Long
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWndParent As Long, ByVal hWndChildAfter As Long, ByVal lpszClass As String, ByVal lpszTitle As String) As Long
    Dim h1 As Long
    Dim h2 As Long

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        h1 = FindWindow(0, "aIW Console")
        h2 = FindWindowEx(h1, 0, "Edit", 0)
        SendMessage(h2, WM_SETTEXT, 0, "connect 127.0.0.1")
        SendMessage(h2, WM_CHAR, 13, 0)
    End Sub
End Class

Als ik het programma run en ik klik op Button1, dan krijg ik dit 2x :
"PInvokeStackImbalance was detected
Message: A call to PInvoke function 'WindowsApplication1!WindowsApplication1.Form1::FindWindowEx' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature."
Daarna doet het programma gewoon verder, maar in die textbox gebeurt er niets. Enig idee hoe ik dit kan fixen ? (volgens mij foute omzetting van code :S)

Verder kan ik op internet niet echt iets vinden.
 
Laatst bewerkt:
Verder kan ik op internet niet echt iets vinden.

Beter leren zoeken: http://lmgtfy.com/?q="Private+Declare+Function+SendMessage"+++wm_settext

(daar vind je denk ik wel een werkend voorbeeld tussen)

edit: en Spy++ zit gewoon bij Visual Studio (onder "Visual Studio Tools"). Want de waarde "Edit" zal waarschijnlijk niet kloppen.
edit2: ik ben zelf even aan de slag gegaan en heb een C# voorbeeld vertaald naar VB:

[cpp]
Imports System
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Imports vb = Microsoft.VisualBasic

'// For Windows Mobile, replace user32.dll with coredll.dll
' [DllImport("user32.dll", SetLastError = true)]
' static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

' [DllImport("User32.dll")]
' public static extern Int32 SendMessage(
' IntPtr hWnd, // handle to destination window
' int Msg, // message
' int wParam, // first message parameter
' [MarshalAs(UnmanagedType.LPStr)] string lParam);
' // second message parameter

' IntPtr _hwnd;

Public Class Form1
Private Declare Auto Function FindWindow Lib "user32.dll" (<MarshalAs(UnmanagedType.LPTStr), [In]()> ByVal lpClassName As String, <MarshalAs(UnmanagedType.LPTStr), [In]()> ByVal lpWindowName As String) As IntPtr
Private Declare Auto Function FindWindowEx Lib "user32.dll" (ByVal hWndParent As IntPtr, ByVal hWndChildAfter As IntPtr, <MarshalAs(UnmanagedType.LPTStr), [In]()> ByVal lpszClass As String, <MarshalAs(UnmanagedType.LPTStr), [In]()> ByVal lpszWindow As String) As IntPtr
Private Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, <MarshalAs(UnmanagedType.LPTStr), [In]()> ByVal lParam As String) As Int32

Private Const WM_SETTEXT = &HC

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim hwnd As IntPtr = FindWindow(vbNullString, "aIW Console")
If hwnd.Equals(IntPtr.Zero) Then
MsgBox("error 1")
Else
Dim hTextbox As IntPtr = FindWindowEx(hwnd, IntPtr.Zero, "Edit", vbNullString) 'Edit moet dus aangepast worden
If hTextbox.Equals(IntPtr.Zero) Then
MsgBox("error 2")
Else
Dim test As Integer = SendMessage(hTextbox, WM_SETTEXT, 0, "Hallo" + vbCrLf) 'vbCrLf is hier nu de enter
' ...
End If
End If
End Sub
End Class
[/cpp]

(heb het zelf even getest met een ander programma en het werkt gewoon)
 
Laatst bewerkt:
Ik heb die visual studio tools nergens. (Ik gebruik Visual Basic 2010 Express, waarschijnlijk daarom...)
De code die jij schreef werkt perfect, behalve dat hij niet entert. K heb de code nog wat versimpeld, en dit is het (werkende) eindresultaat :

Code:
Imports System.Runtime.InteropServices

Public Class Form1

    Private Declare Auto Function FindWindow Lib "user32.dll" (<MarshalAs(UnmanagedType.LPTStr), [In]()> ByVal lpClassName As String, <MarshalAs(UnmanagedType.LPTStr), [In]()> ByVal lpWindowName As String) As IntPtr
    Private Declare Auto Function FindWindowEx Lib "user32.dll" (ByVal hWndParent As IntPtr, ByVal hWndChildAfter As IntPtr, <MarshalAs(UnmanagedType.LPTStr), [In]()> ByVal lpszClass As String, <MarshalAs(UnmanagedType.LPTStr), [In]()> ByVal lpszWindow As String) As IntPtr
    Private Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, <MarshalAs(UnmanagedType.LPTStr), [In]()> ByVal lParam As String) As Int32
    Private Const WM_SETTEXT = &HC
    Private Const WM_CHAR = &H102


    Public Function SendToConsole(ByVal Command As String) As Boolean
        Dim hwnd As IntPtr = FindWindow(vbNullString, "aIW Console")
        If hwnd.Equals(IntPtr.Zero) Then
            Return False
        Else
            Dim hTextbox As IntPtr = FindWindowEx(hwnd, IntPtr.Zero, "Edit", vbNullString)
            If Not hTextbox.Equals(IntPtr.Zero) Then
                Dim test As Integer = SendMessage(hTextbox, WM_SETTEXT, 0, Command)
                Dim test2 As Integer = SendMessage(hTextbox, WM_CHAR, 13, 0)
                Return True
            End If
        End If
    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        If Not SendToConsole("Bedankt CoD_NL !!!") Then MsgBox("Error")
    End Sub
End Class

Enorm bedankt voor je code, CoD_NL !
 
Laatst bewerkt:
[cpp]
If Not hTextbox.Equals(IntPtr.Zero) Then
retiurn SendMessage(hTextbox, WM_SETTEXT, 0, Command) + SendMessage(hTextbox, WM_CHAR, 13, 0)
End If
[/cpp]

Het bovenstaande moet volgens mij ook werken (true = niet gelijk aan 0)
 
Hmm, ja, moet lukken.
Ach, de code werkt, dat er nog een aantal schoonheidsfoutjes inzitten maakt niet echt uit voor mij.
Ik ben nu bezig met het eigenlijke programma.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan