Programmierter Mausklick funktioniert nicht immer...



  • Programmierter Mausklick funktioniert nicht immer...

    Meine Idee war es mehrere Fenster zeitgleich offen zu haben und nach einer bestimmten Aktion soll dann das jeweilige Fenster der Button gedrückt werden.

    Also mal Fenster 2, dann Fenster 3, dann Fenster 1... wie auch immer.

    Das ganze funktioniert wenn das Fenster noch im Fokus ist also die aktive Form ist.
    Bei den anderen Fenster funktioniert der Klick nicht mehr!

    Die Maus bewegt sich zwar hin, aber der Klick wird nicht ordentlich (wie wenn ich selber mit der Maus klicke)ausgeführt. Das Fenster wird auch nicht zum aktiven Fenster, also bleibt im "Hintergrund" - (Die Fenster sind alle nebeneinander).

    Ich hatte dieses Muster mit in mein Programm eingepflegt:

    // **MAUSSTEUERUNG**MAUSSTEUERUNG**MAUSSTEUERUNG**MAUSSTEUERUNG**MAUSSTEUERUNG**MAUSSTEUERUNG**MAUSSTEUERUNG**MAUSSTEUERUNG**MAUSSTEUERUNG**
    
            [DllImport("user32.dll", EntryPoint = "SendInput", SetLastError = true)]
            static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);
    
            [DllImport("user32.dll", EntryPoint = "GetMessageExtraInfo", SetLastError = true)]
            static extern IntPtr GetMessageExtraInfo();
    
            private enum InputType
            {
                INPUT_MOUSE = 0,
                INPUT_KEYBOARD = 1,
                INPUT_HARDWARE = 2,
            }
    
            [Flags()]
            private enum MOUSEEVENTF
            {
                MOVE = 0x0001,  // mouse move 
                LEFTDOWN = 0x0002,  // left button down
                LEFTUP = 0x0004,  // left button up
                RIGHTDOWN = 0x0008,  // right button down
                RIGHTUP = 0x0010,  // right button up
                MIDDLEDOWN = 0x0020,  // middle button down
                MIDDLEUP = 0x0040,  // middle button up
                XDOWN = 0x0080,  // x button down 
                XUP = 0x0100,  // x button down
                WHEEL = 0x0800,  // wheel button rolled
                VIRTUALDESK = 0x4000,  // map to entire virtual desktop
                ABSOLUTE = 0x8000,  // absolute move
            }
    
            [StructLayout(LayoutKind.Sequential)]
            private struct MOUSEINPUT
            {
                public int dx;
                public int dy;
                public int mouseData;
                public MOUSEEVENTF dwFlags;
                public int time;
                public IntPtr dwExtraInfo;
            }
    
            [StructLayout(LayoutKind.Sequential)]
            private struct INPUT
            {
                public InputType type;
                public MOUSEINPUT mi;
            }
    
            public static uint Move(int x, int y)
            {
                // Bildschirm Auflösung
                float ScreenWidth = Screen.PrimaryScreen.Bounds.Width;
                float ScreenHeight = Screen.PrimaryScreen.Bounds.Height;
    
                INPUT input_move = new INPUT();
                input_move.type = InputType.INPUT_MOUSE;
    
                input_move.mi.dx = (int)Math.Round(x * (65535 / ScreenWidth), 0);
                input_move.mi.dy = (int)Math.Round(y * (65535 / ScreenHeight), 0);
                input_move.mi.mouseData = 0;
                input_move.mi.dwFlags = (MOUSEEVENTF.MOVE | MOUSEEVENTF.ABSOLUTE);
                input_move.mi.time = 0;
                input_move.mi.dwExtraInfo = GetMessageExtraInfo();
    
                INPUT[] input = { input_move };
                return SendInput(1, input, Marshal.SizeOf(input_move));
            }
    
            public static uint Click()
            {
                INPUT input_down = new INPUT();
                input_down.type = InputType.INPUT_MOUSE;
    
                input_down.mi.dx = 0;
                input_down.mi.dy = 0;
                input_down.mi.mouseData = 0;
                input_down.mi.dwFlags = MOUSEEVENTF.LEFTDOWN;
                input_down.mi.time = 0;
                input_down.mi.dwExtraInfo = GetMessageExtraInfo();
    
                INPUT input_up = input_down;
                input_up.mi.dwFlags = MOUSEEVENTF.LEFTUP;
    
                INPUT[] input = { input_down, input_up };
                return SendInput(2, input, Marshal.SizeOf(input_down));
            }
    

    Wenn es geht Bitte um einfache Erklärung! Bin leider ist seit kurzem in der Programmierung und habe nur wenig Wissen.

    Also auf Lösungsvorschläge und Tipps bin ich sehr dankbar!

    P.s. In dem Fenster wo gedrückt werden soll, dieses Programm habe ich nicht selbst programmiert (ein Börsen-Programm), das heißt ein eingriff dort ist nicht möglich!!



  • Hast du mal versucht das jeweilige Fenster in den Fokus zu setzen? Wenn du Zugriff auf deine Forms hast, kannst du versuchen

    form.Show(); //um sicher zu gehen
    form.Activate();
    

    zu benutzen.
    Ansonsten schau dir mal die WinAPI Funktion SetForegroundWindow an.



  • using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            Process[] procs;
            private void GetProcesses()
            {
                procs = Process.GetProcesses();
                if (Convert.ToInt32(label2.Text) != procs.Length)
                {
                    listBox1.Items.Clear();
                    for (int i = 0; i < procs.Length; i++)
                    {
                        listBox1.Items.Add(procs[i].ProcessName+" _ "+procs[i].Id.ToString());
                    }
                    label2.Text=procs.Length.ToString();
                }
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                GetProcesses();
            }
    
            [DllImport("user32.dll")]
            private static extern
                bool SetForegroundWindow(IntPtr hWnd);
            [DllImport("user32.dll")]
            private static extern
                bool ShowWindowAsync(IntPtr hWnd,int nCmdShow);
            [DllImport("user32.dll")]
            private static extern
                bool IsIconic(IntPtr hWnd);
            private const int SW_RESTORE = 9;
    
            private void button1_Click(object sender, EventArgs e)
            {
                if(IsIconic(procs[listBox1.SelectedIndex].Handle))
                    ShowWindowAsync(procs[listBox1.SelectedIndex].Handle, SW_RESTORE);
    
                SetForegroundWindow(procs[listBox1.SelectedIndex].Handle);
    
                MessageBox.Show(procs[listBox1.SelectedIndex].Handle.ToString());   // In meiner Auflistung ist zwar 2mal der gleiche ProzessName (da das gleiche Programm 2mal geöffnet)
                                                                                    // Aber die Process_ID's und Process_Handle's sind eindeutig und jeweils verschieden
    
                //procs[listBox1.SelectedIndex].Kill();                             // FUNKTIONIERT IMMER; PROGRAMME WERDEN ORDENTLICH BEENDET!! 
    
                //####################################################################
    
            }
        }
    }
    

    Die DLL_Funktion SetForegroundWindow ist sehr sporadisch.
    z.B.:

    1.Versuch: ein Process öffnet sich, aber das zweite nicht mehr (der erste Process kann immer wieder geöffnet werden, auch wenn es wieder mal im Hintergrund war!)
    2.Versuch: Anfangs konnte man beide Process öffnen wie gewollt, danach geht garnichts mehr...
    3.Versuch: Es öffnet garkeins!

    Also sehr unzuverlässig.



  • Ich sehe gerade dass meine Maus den klick zwar hinbekommt, aber halt nur auf dem Desktop geklickt hat an der Koordinate wo ich es wollte, allerdings sehe ich den Desktop ja anders vor mir: Ich sehe ja noch die offenen Anwendungen vor dem DesktopBild!! Also muss ich irgendwie die Anwendung kurz vorher wieder aufblenden denke ich, aber selbst da komm ich nnicht weiter. Siehe Beitrag--;



  • Jemand eine Idee wie ich das Problem lösen kann?



  • werkla4 schrieb:

    Jemand eine Idee wie ich das Problem lösen kann?

    Hi werkla4,

    wenn Du ein kompilierbares Minimalbeispiel in Form eines VS-Projekts zur Verfügung stellst, würde ich es mir übers Wochenende mal anschauen.

    Grüße


Anmelden zum Antworten