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