Autor Beitrag
VampireSilence
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 109
Erhaltene Danke: 5


C# (VS 2008 Express), PHP/MySQL, Windows XP
BeitragVerfasst: Do 30.06.11 00:12 
Also ich will mal direkt mit offenen Karten spielen: Ich dachte ich programmiere mir mal einen Bot. ;)
Und zwar für Solar 2. Der Bot soll dann alle paar Sekunden [K] drücken. Das drücken an sich ist nicht das Problem, sondern eher, dass ich das Fenster zuerst in den Vordergrund holen muss und der ständige Wechsel bremst das Spiel derartig aus, dass es damit weniger Spaß macht, anstatt mehr. Die Frage ist also, ob das auch irgendwie geht, ohne dass ich das Zielfenster in den Vordergrund holen muss ?

mfg
- VampireSilence
norman2306
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 222
Erhaltene Danke: 16

Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
BeitragVerfasst: Do 30.06.11 07:28 
Den Bot aber nur für private Zwecke nutzen.
Das geht mit dem keyb_event. Damit arbeitet auch der Tastaturtreiber- du simulierst damit praktisch eine Tastatur.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
[DllImport("user32.dll")]
static extern void keybd_event(byte bVk, byte bScan, uint dwFlags,
   UIntPtr dwExtraInfo);

public enum KeyboardEventFlags {
KEYDOWN = 0,
KEYUP = 2
}


Aufruf:
ausblenden C#-Quelltext
1:
keybd_event(Keys.K, 0, KeyboardEventFlags.KEYDOWN, UIntPtr.Zero);					


Mit dem API-Befehl 'GetForeGroundWindow' kannst du das aktive Fenster erfragen und die Taste senden, sobald das Solar2-Fenster aktiv ist. Außerdem solltest du ein Thread.Sleep einbauen, sonst erlahmt dein Rechner so oder so.
VampireSilence Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 109
Erhaltene Danke: 5


C# (VS 2008 Express), PHP/MySQL, Windows XP
BeitragVerfasst: Do 30.06.11 20:41 
System.Windows.Forms.Keys kann nicht implizit in byte umgewandelt werden. ;) Hab das mal durch (byte)'k' ersetzt.

Aber egal, es gibt noch ein anderes Problem: Der Witz an der Sache war ja, dass das Fenster nicht aktiv sein müssen soll. Sonst könnte ich ja auch selber zocken. ^^
Und wenn ich den IntPtr-Handle aus dem GetForegroundWindow() speichere und dann als dwExtraInfo übergebe, scheint das keine Wirkung zu haben.

Und ja, den Bot verwende ich nur für mich selbst. Bei Solar 2 gibts leider eh keinen Multiplayer.

mfg
- VampireSilence
norman2306
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 222
Erhaltene Danke: 16

Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
BeitragVerfasst: Fr 01.07.11 10:54 
Also bei mir funktioniert das Prima:

Mach mal ein Konsolenprogramm und schieb das rein. Danach starten und einfach mal Notepad öffnen.

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
    class Program
    {
        [DllImport("user32.dll")]
        static extern void keybd_event(byte bVk, byte bScan, uint dwFlags,
           UIntPtr dwExtraInfo);

        [DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
        private static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
        private static extern Int32 GetWindowThreadProcessId(IntPtr hWnd, out Int32 lpdwProcessId);

        public enum KeyboardEventFlags
        {
            KEYDOWN = 0,
            KEYUP = 2
        }

        static void Main(string[] args)
        {

            while (true)
            {
                var fgw = GetForegroundWindow();
                int procID;
                var fwd_procID = GetWindowThreadProcessId(fgw, out procID);
                var proc = Process.GetProcessById(procID);

                if(proc != null && proc.ProcessName == "notepad")
                    keybd_event((byte)Keys.K, 0, (int)KeyboardEventFlags.KEYDOWN, UIntPtr.Zero);

                Thread.Sleep(500);
            }
             
        }
    }
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19341
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 01.07.11 11:23 
user profile iconnorman2306 hat folgendes geschrieben Zum zitierten Posting springen:
Mach mal ein Konsolenprogramm und schieb das rein. Danach starten und einfach mal Notepad öffnen.
Und jetzt nimm einmal ein anderes Fenster und pack das vor dein Notepadfenster, dann wirst du sehen, dass es nicht mehr geht. Und genau darum geht es ja...

Es kommt eben darauf an, ob das Spiel auch Tastendrücke, die per Windows Message ankommen, verarbeitet. Dann könnte man sich das Fensterhandle holen und mit SendMessage und WM_KEYDOWN, WM_KEYUP, ... die Tastendrücke dorthin senden.
norman2306
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 222
Erhaltene Danke: 16

Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
BeitragVerfasst: Fr 01.07.11 11:34 
Ich denke, es geht darum, wenn ein bestimmter Prozess, also z.B. "Solaris 2" im Vordergrund ist, einen Tastendruck zu senden? Und genau das macht der obige Code. Das funktioniert immer und mit jedem beliebigen Programm, da es direkt einen Hardwaretreiber emuliert. Wenn man die Überprüfung des Programms rausnimmt, sendet er an alles was gerade den Fokus hat eine Taste. Einfacher geht es nicht.
norman2306
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 222
Erhaltene Danke: 16

Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
BeitragVerfasst: Fr 01.07.11 11:40 
Jetzt, ich habe richtig gelesen... Dann geht es tatsächlich nur mit WM_KEYDOWN
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4807
Erhaltene Danke: 1061

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 01.07.11 11:54 
Hi,

wenn es um murudai.com/solar/ geht, dann ist das Spiel mit XNA (also DirectX) programmiert, so daß wohl DirectInput (anstatt der Win-Messages) benutzt wird.
Und dann ist es nur mit DirectX-Hooks möglich Tasten dorthin zu senden...
VampireSilence Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 109
Erhaltene Danke: 5


C# (VS 2008 Express), PHP/MySQL, Windows XP
BeitragVerfasst: Sa 02.07.11 13:58 
Dann wären ja nun endlich alle Klarheiten beseitigt. :)

@Th69
Ja, genau das ist es.
Also seine Variante funktioniert schon. Auch bei Solar 2. Aber eben nur, wenn dieses aktiv ist.
Wie würde das denn mit den DirectX-Hooks dann funktionieren ?

mfg
- VampireSilence