Laden...

Keyboardevent greift nicht oder lässt sich nicht auflösen

Erstellt von megamacy vor 17 Jahren Letzter Beitrag vor 16 Jahren 3.594 Views
M
megamacy Themenstarter:in
94 Beiträge seit 2005
vor 17 Jahren
Keyboardevent greift nicht oder lässt sich nicht auflösen

Hallo,

habe ein seltsames problem, ich möchte einen keyboardevent ausführen, zwischendurch nen mouseevent und dann den keyboardevent auflösen. das alles in einem DX spiel

die kosntanten sind folgendermaßen deklariert:
const int KEYEVENTF_EXTENDEDKEY = 0x1;
const int KEYEVENTF_KEYUP = 0x2;

Das problem was ich nun habe ist folgendes:


 keybd_event((int)Keys.ControlKey, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
MausClick("ld");
MausClick("lu");
keybd_event((int)Keys.ControlKey, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);

Hiermit funktioniert es garnicht. der mausklick wird ausgeführt durch meine methode, aber das drücken der STRG taste wird nicht simuliert


 keybd_event((int)Keys.ControlKey, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
MausClick("ld");
MausClick("lu");

So wird es richtig ausgeführt, allerdings wird das drücken der STRG taste nicht mehr aufgelöst und sie bleibt gedrückt was natürlich nicht gut ist


 keybd_event((int)Keys.ControlKey, 0, 0, 0);
MausClick("ld");
MausClick("lu");
keybd_event((int)Keys.ControlKey, 0, KEYEVENTF_KEYUP, 0);

So wird STRG zwar gedrückt, aber vor dem drücken der maus schon wieder losgelassen. auch nicht gut

Also wie kann ich es hinbekommen das STRG gehalten wird, dann meine mausmethoden ausgeführt werden und anschließend STRG wieder gelöst wird?

B
1.529 Beiträge seit 2006
vor 17 Jahren

Ich kombiniere deine obigen Versionen mal zu:

keybd_event((int)Keys.ControlKey, 0, KEYEVENTF_EXTENDEDKEY, 0);
MausClick("ld");
MausClick("lu");
keybd_event((int)Keys.ControlKey, 0, KEYEVENTF_KEYUP, 0);
M
megamacy Themenstarter:in
94 Beiträge seit 2005
vor 17 Jahren

Der weg bringt dasselbe ergebnis wie mein 2. code. die taste wird nicht gelöst

B
1.529 Beiträge seit 2006
vor 17 Jahren

Was ist damit:

keybd_event((int)Keys.ControlKey, 0, KEYEVENTF_EXTENDEDKEY, 0);
MausClick("ld");
MausClick("lu");
keybd_event((int)Keys.ControlKey, 0, KEYEVENTF_KEYUP, 0);
keybd_event((int)Keys.ControlKey, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
M
megamacy Themenstarter:in
94 Beiträge seit 2005
vor 17 Jahren

Wie mein erstes code beispiel, der tasten event wird nicht ausgelöst 🙁

B
1.529 Beiträge seit 2006
vor 17 Jahren

Irgendwie versteh ich das nicht. Werden die MouseClicks asynchron ausgelöst? Wie können denn Funktionsaufrufe nach dem MouseClick diesen verändern? Kann man bei MouseClick nicht irgenwie gedrückte Tasten mitliefern?

M
megamacy Themenstarter:in
94 Beiträge seit 2005
vor 17 Jahren

Gute frage, da ich einen backgroundworker benutze ist es ohl das was du mit asyncron meinst ^^

also das ganze sieht verkürzt etwa so aus:


//DLL Import für Tastureingabe
[DllImport("user32.dll")]
private static extern void keybd_event(int vk, byte bScan, int dwFlags, int dwExtraInfo);
private const byte KEYUP = 0x0002;

//DLL Import für Mausklicks
[DllImport("User32.dll", SetLastError = true)]
public static extern int SendInput(int nInputs, ref INPUT pInputs, int cbSize);

//Mausclick Events
 internal class MOUSEEVENTF
        {
            public const int MOVE = 0x0001; /* mouse move */
            public const int LEFTDOWN = 0x0002; /* left button down */
            public const int LEFTUP = 0x0004; /* left button up */
            public const int RIGHTDOWN = 0x0008; /* right button down */
            public const int RIGHTUP = 0x0010; /* right button up */
            public const int MIDDLEDOWN = 0x0020; /* middle button down */
            public const int MIDDLEUP = 0x0040; /* middle button up */
            public const int XDOWN = 0x0080; /* x button down */
            public const int XUP = 0x0100; /* x button down */
            public const int WHEEL = 0x0800; /* wheel button rolled */
            public const int VIRTUALDESK = 0x4000; /* map to entire virtual desktop */
            public const int ABSOLUTE = 0x8000; /* absolute move */
        }

        const int INPUT_MOUSE = 0;

        public struct MOUSEINPUT
        {
            public int dx;
            public int dy;
            public int mouseData;
            public int dwFlags;
            public int time;
            public IntPtr dwExtraInfo;
        }

        public struct INPUT
        {
            public uint type;
            public MOUSEINPUT mi;
        }

        private void MausClick(string Ereignis)
        {
            INPUT i = new INPUT();
            i.type = INPUT_MOUSE;
            i.mi.dx = 0;
            i.mi.dy = 0;

            if (Ereignis == "ld")
            {
                i.mi.dwFlags = MOUSEEVENTF.LEFTDOWN;
                SendInput(1, ref i, Marshal.SizeOf(i));
            }
            else if (Ereignis == "lu")
            {
                i.mi.dwFlags = MOUSEEVENTF.LEFTUP;
                SendInput(1, ref i, Marshal.SizeOf(i));
            }
            else if (Ereignis == "rd")
            {
                i.mi.dwFlags = MOUSEEVENTF.RIGHTDOWN;
                SendInput(1, ref i, Marshal.SizeOf(i));
            }
            else if (Ereignis == "ru")
            {
                i.mi.dwFlags = MOUSEEVENTF.RIGHTUP;
                SendInput(1, ref i, Marshal.SizeOf(i));
            }
        }

//Backgroundworker mit versch. Aufgaben
private void bgw_DoWork(object sender, DoWorkEventArgs e)
{
     //Auslösen der Methode mit den Klicks und Tastatureingaben
     EingabeSimulation();
}

//Die Methode mit den Perepherie Eingabe Simultionen
private void EingabeSimulation()
{
      const int KEYEVENTF_EXTENDEDKEY = 0x1;
      const int KEYEVENTF_KEYUP = 0x2;

      keybd_event((int)Keys.ControlKey, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
      MausClick("ld");
      MausClick("lu");
}

B
1.529 Beiträge seit 2006
vor 17 Jahren

Das Problem ist, dass du zwei unterschiedliche Funktionen nutzt. Mittels SendInput kannst du alle deine Aktionen atomar ausführen.

[DllImport("user32.dll", SetLastError = true)]
private static extern int SendInput(int nInputs, ref INPUT[] pInputs, int cbSize);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool GetCursorPos( ref POINT coord );

[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct POINT
{
   public Int32 x;
   public Int32 y;
}

[Flags()]
private enum MOUSEEVENTF
{
   MOVE = 0x0001,
   LEFTDOWN = 0x0002, LEFTUP = 0x0004,
   RIGHTDOWN = 0x0008, RIGHTUP = 0x0010,
   MIDDLEDOWN = 0x0020, MIDDLEUP = 0x0040,
   XDOWN = 0x0080, XUP = 0x0100,
   WHEEL = 0x0800,
   VIRTUALDESK = 0x4000,
   ABSOLUTE = 0x8000,
   none = 0x0;
}

[Flags()]
private enum KEYEVENTF
{
   EXTENDEDKEY  = 0x0001,
   KEYDOWN = 0x0, KEYUP = 0x0002,
   UNICODE = 0x0004, SCANCODE = 0x0008,
   none = 0x0
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct MOUSEINPUT
{
   public Int32 dx;
   public Int32 dy;
   public UInt32 mouseData;
   public UInt32 dwFlags;
   public UInt32 time;
   public IntPtr dwExtraInfo;
   public MOUSEINPUT( Int32 x, Int32 y, UInt32 mD, MOUSEEVENTF dwF, UInt32 t, IntPtr dwEI )
   {
      dx = x; dy = y; mouseData = mD; dwFlags = (UInt32)dwF; time = t; dwExtraInfo = dwEI;
   }
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct KEYBDINPUT
{
   public UInt16 wVk;
   public UInt16 wScan;
   public UInt32 dwFlags;
   public UInt32 time;
   public IntPtr dwExtraInfo;
   public KEYBDINPUT( UInt16 wV, UInt16 wS, KEYEVENTF dwF, UInt32 t, IntPtr dwEI )
   {
      wVK = wV; wScan = wS, dwFlags = (UInt32)dwF; time = t; dwExtraInfo = dwEI;
   }
}

[StructLayout(LayoutKind.Explicit)]
private struct INPUT
{
   [FieldOffset(0)]
   public UInt32 type;
   [FieldOffset(4)]
   public MOUSEINPUT mi;
   [FieldOffset(4)]
   public KEYBDINPUT ki;
   public INPUT( MOUSEINPUT mouse )
   {
      type = INPUT_MOUSE;
      ki = new KEYBDINPUT( 0, 0, KEYEVENTF.none, 0, IntPtr.Zero );
      mi = mouse;
   }
   public INPUT( KEYBDINPUT keybd )
   {
      type = INPUT_KEYBD;
      mi = new MOUSEINPUT( 0, 0, 0, MOUSEEVENTF.none, 0, IntPtr.Zero );
      ki = keybd;
   }
   private const UInt32 INPUT_MOUSE = 0;
   private const UInt32 INPUT_KEYBD = 1;
   private const UInt32 INPUT_HARDWARE = 2;
}

// ....

private const UInt16 VK_CONTROL = 0x11;
public void DoSomeAction()
{
   // Mauskoordinaten holen
   POINT coord;
   GetCursorPos( coord );
   // Strg runter, Maus links runter, Maus links hoch, Strg hoch
   INPUT[] inputs = new INPUT[4];
   inputs[0] = new INPUT(new KEYBDINPUT(VK_CONTROL,0,KEYEVENTF.KEYDOWN,0,IntPtr.Zero));
   inputs[1] = new INPUT(new MOUSEINPUT(coord.x,coord.y,0,MOUSEEVENTF.LEFTDOWN,0,IntPtr.Zero));
   inputs[2] = new INPUT(new MOUSEINPUT(coord.x,coord.y,0,MOUSEEVENTF.LEFTUP,0,IntPtr.Zero));
   inputs[3] = new INPUT(new KEYBDINPUT(VK_CONTROL,0,KEYEVENTF.KEYUP,0,IntPtr.Zero));

   int result = SendInput( inputs.Length, ref inputs, Marshal.SizeOf( typeof(INPUT) ) );
   // ...
}
M
megamacy Themenstarter:in
94 Beiträge seit 2005
vor 17 Jahren

ok, sieht sauberer aus, aber der spuckt mir aus das er nen anderen typ als UInt32 erwartet bei den beiden hier:


        [Flags()]
        private enum MOUSEEVENTF : UInt32
        {
           //...
        }

        [Flags()]
        private enum KEYEVENTF : UInt32
        {
          //...
        }

B
1.529 Beiträge seit 2006
vor 17 Jahren

Probier einfach nur uint.

M
megamacy Themenstarter:in
94 Beiträge seit 2005
vor 17 Jahren

auchnicht, dann erwartet der beim gesammten inhalt ein , statt ;
Und welche using Direktive brauch ich für "FieldOffset"

B
1.529 Beiträge seit 2006
vor 17 Jahren

Muss ja auch hin. Habe das oben verpeilt. Ist jetzt aber geändert.

B
1.529 Beiträge seit 2006
vor 17 Jahren

Ebenfalls System.Runtime.InteropServices. Müsstest du doch aber schon drin haben!?

M
megamacy Themenstarter:in
94 Beiträge seit 2005
vor 17 Jahren

Original von Borg
Ebenfalls System.Runtime.InteropServices. Müsstest du doch aber schon drin haben!?

ja, sorry, da war ein tippfehle rin deinem code, das D fehlte ^^

jetzt muss ich mal gucken wie ich das alles in mein programm rien bekomme, wegen dem verändertem mauszugriff muss ich ne menge abändern.

Danke erstmal, ich hoffe ich komme jetzt klar 😁

B
1.529 Beiträge seit 2006
vor 17 Jahren

Habe das fehlende "d" ergänzt.

Ansonsten ist die Verwendung durch die Konstruktoren doch sehr einfach...

B
1.529 Beiträge seit 2006
vor 17 Jahren

Und hör mal bitte auf deine Beiträge zu editieren. Beziehungsweise - so wie ich - nur um Fehler zu verbessern. Aber nicht um Fragen hinzuzufügen oder zu entfernen. Lies dir doch mal deine Posts durch und dann meine jetzt plötzlich völlig zusammenhanglosen Antworten...

Das ist hier ein Forum, kein Chat...

M
megamacy Themenstarter:in
94 Beiträge seit 2005
vor 17 Jahren

ok, ich dachte ich bekomm es noch weg bevor du es liest, weil mir der fehler da aufgefallen ist ^^

Ich bekomme nun einen neuen fehler


public static extern int SendInput(int nInputs, ref INPUT[] pInputs, int cbSize);

Hier sagt er:
Inkonsistenter Zugriff: Parametertyp "ref Emulator.Form1.INPUT[]" ist weniger zugreifbar als Methode "Emulator.Form1.SendInput(int, ref Emulator.Form1.INPUT[], int)"

B
1.529 Beiträge seit 2006
vor 17 Jahren

Ein solch kleines Problemchen solltest du aber durchaus alleine lösen können...
Daher: Syntaxfehler selbst lösen (Compilerfehlermeldungen)

Code oben angepasst.

M
megamacy Themenstarter:in
94 Beiträge seit 2005
vor 17 Jahren

jo, hatt eich auch im internet gefunden das man das private setzen soll. allerdings ruft das mehrere andere fehler herbei, also dachte ich "einen weg machen und andere erscheinen kanns nicht sein"

4-Argument: kann nicht von "Emulator.Form1.MOUSEEVENTF" in "uint" konvertiert werden.

Die beste Übereinstimmung für die überladene Emulator.Form1.KEYBDINPUT.KEYBDINPUT(ushort, ushort, uint, uint, System.IntPtr)-Methode hat einige ungültige Argumente.

Das Feld "Emulator.Form1.INPUT.ki" muss vollständig zugewiesen werden, bevor das Steuerelement den Konstruktor verlässt.

und abwandlungen davon mit anderen betroffenen teilen.

hast du den code eigentlich mal getestet? ^^

B
1.529 Beiträge seit 2006
vor 17 Jahren

Nein, ich habe den Code nicht getestet.
Ich habe den direkt hier rein getippt. Weil ich dir nämlich auch bloß helfen wollte.
Da wusste ich aber noch nicht, dass du nicht mit ein paar Compilerfehlermeldungen klar kommst.

Code wiederum angepasst.

M
megamacy Themenstarter:in
94 Beiträge seit 2005
vor 17 Jahren

Mit den Compilermeldungen nicht klar zu kommen ist leicht wenn man den code größtenteils nicht versteht ^^

Die fehlermeldungen sind jetzt aufjedenfall ausgemerzt. allerdings funktioniert es auch nicht. beim ausführen werden die maustasten lahm gelegt, das tasten drücken greift garnicht

B
1.529 Beiträge seit 2006
vor 17 Jahren

Mit den Compilermeldungen nicht klar zu kommen ist leicht wenn man den code größtenteils nicht versteht ^^

Da ist doch kaum Code. Ein paar Structs, ein paar Konstruktoren und Erzeugung und Füllen eines Arrays. Wenn du das nicht verstehst, solltest du eventuell noch mal an den Grundlagen feilen.

das tasten drücken greift garnicht

Möglicherweise muss man beim Mausklicken auch noch die aktuellen Koordinaten in dx und dy mitliefern. Um diese zu erhalten, kannst du GetCursorPos benutzen.
EDIT: Code angepasst.

beim ausführen werden die maustasten lahm gelegt

Das bedeutet was?

M
megamacy Themenstarter:in
94 Beiträge seit 2005
vor 17 Jahren

Original von Borg

Mit den Compilermeldungen nicht klar zu kommen ist leicht wenn man den code größtenteils nicht versteht ^^
Da ist doch kaum Code. Ein paar Structs, ein paar Konstruktoren und Erzeugung und Füllen eines Arrays. Wenn du das nicht verstehst, solltest du eventuell noch mal an den Grundlagen feilen.

genau der teil ist nicht da sproblem, auch wenn ich weiß das ein auto aus blech, reifen und nem motor besteht kann ich ncoh lange keins bauen

Original von Borg

das tasten drücken greift garnicht
Möglicherweise muss man beim Mausklicken auch noch die aktuellen Koordinaten in dx und dy mitliefern. Um diese zu erhalten, kannst du GetCursorPos benutzen.

Ich versteh nicht wie mauskoordinaten das drücken von tastaturtasten beeinflussen soll?
Ich hab die methode so zusammen gesetzt das es nur tasten drückt. aber es kommt nirgendwo was an

Original von Borg

beim ausführen werden die maustasten lahm gelegt
Das bedeutet was?

Beim ersten test ließen sich die maustasten nicht mehr drücken, egal wo ich hinklickte, die maus reagierte nicht mehr. allerdings wechselt es seine funktionen jedesmal beim starten. einmal hat es eben kontextmenus geöffnet, also rechtsklick betätigt obwohl linksklick angegeben war, noch einen versuch später passierte wieder garnichts.

M
megamacy Themenstarter:in
94 Beiträge seit 2005
vor 17 Jahren

Auch mit den mauspositionen geht das klicken nicht. wobei ich


MousePosition.X
MousePosition.Y

benutzt habe. ist irgendwie kürzer als deins (und deine curser funktion machte fehler)^^

M
megamacy Themenstarter:in
94 Beiträge seit 2005
vor 17 Jahren

ich hänge immernoch an dem problem. habe schon mehrere andere ansetze fürs tasten klicken und mausklicken im netz gefunden, allerdings haben die alle dasselbe problem sobald man sie kombiniert.

hat denn niemand eine lösung wie man das funktionierend hinbekommt? büdde 🙂

Hie rmal ein ganz verienfachter weg (der halt auch den fehler produziert die STRG taste nicht mehr zu lösen)


        //Import mouse_event
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);

        //Import keybd_eventl
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern void keybd_event(byte bVk, byte bScan, long dwFlags, long dwExtraInfo);

        //Konstanten
        public const int MOUSEEVENTF_LEFTDOWN = 0x02;
        public const int MOUSEEVENTF_LEFTUP = 0x04;
        public const int MOUSEEVENTF_RIGHTDOWN = 0x08;
        public const int MOUSEEVENTF_RIGHTUP = 0x10;

        //Codes
        public const byte VK_CONTROL = 0x11;

        public const int KEYEVENTF_EXTENDEDKEY = 0x01;
        public const int KEYEVENTF_KEYUP = 0x02;

        private void btn_start_Click(object sender, EventArgs e)
        {
            keybd_event(VK_CONTROL, 0x45, KEYEVENTF_EXTENDEDKEY, 0);
            mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
            mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);            
            keybd_event(VK_CONTROL, 0x45, KEYEVENTF_KEYUP, 0);
        }

230 Beiträge seit 2007
vor 17 Jahren

_Original von megamacy_hat denn niemand eine lösung wie man das funktionierend hinbekommt? büdde 🙂

Dafür muß man folgendes wissen: Welches Windows Ereignis willst du simulieren? Ein Klick auf den Button?

//Edit001: '*' + '"' entfernt!

B
1.529 Beiträge seit 2006
vor 17 Jahren

@sarabande: Bevor du jetzt mit Windows Messages ankommst:
Lies doch bitte mal einen Thread durch, bevor du postest. megamacy möchte einen (mit Steuerung behafteten) Mausklick auf eine bestimmte Koordinate in einem DirectX-Spiel simulieren. Also vermutlich in irgendeinem Spiel cheaten.
Und das funktioniert nicht so wie gedacht.

EDIT: Und nachdem du wegen bunt und fett und groß (vermutlich) eine Verwarnung bekommen hast, arbeitest du jetzt mit Asterik und Gänsefüßchen und der gleichen Aggressivität.

B
1.529 Beiträge seit 2006
vor 16 Jahren

Nachricht von sarabande vom 09.05.2007 21:14:44
Keyboardevent greift nicht oder lässt sich nicht auflösen

Zitat:
Original von Borg
@sarabande: Bevor du jetzt mit Windows Messages ankommst:
Lies doch bitte mal einen Thread durch, bevor du postest. megamacy möchte einen (mit Steuerung behafteten) Mausklick auf eine bestimmte Koordinate in einem DirectX-Spiel simulieren. Also vermutlich in irgendeinem Spiel cheaten. Und das funktioniert nicht so wie gedacht.

Wenn mit der Koordinate (x/y) kein Ereignis verknüpft ist, kann es auch nicht fünktionieren. Voraussetzung ist auch, dass man SendInput, keybd_event, mouse_event oder SendMessage mit VK_* korrekt implementiert.

Zitat:
EDIT: Und nachdem du wegen bunt und fett und groß (vermutlich) eine Verwarnung bekommen hast, arbeitest du jetzt mit Asterik und Gänsefüßchen und der gleichen Aggressivität.

@Borg - ich mag dich auch nicht!

M
2 Beiträge seit 2007
vor 16 Jahren

In meinen Programmen ersetze ich die long-Deklarationen der Import-Anweisungen durch int. Als diese API-Funktionen geschrieben wurden, stand long für eine 32-Bit-Variable. Heute wird dafür der Integer verwendet.

    [DllImport("user32.dll")]  

    public static extern void mouse_event(int dwFlags,   
        int dx,   
        int dy,   
        int cButtons,   
        int dwExtraInfo);  

Außerdem lasse ich stets die weiteren Parameter hinter der Import-Anweisung weg. Vielleicht hilft Dir das in Deinem Programm.