Mouse Click tylko w zminimalizowanej aplikacji

0

Witam,
pomimo moich bardzo obszernych poszukiwań nie bylem w stanie znaleźć nic odnośnie performu danych funkcji w zminimalizowanej aplikacji przy użyciu pointera.

Poniższy kod:

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {

        public class ClickOnPointTool
        {

            [DllImport("user32.dll")]
            static extern bool ClientToScreen(IntPtr hWnd, ref Point lpPoint);

            [DllImport("user32.dll")]
            internal static extern uint SendInput(uint nInputs, [MarshalAs(UnmanagedType.LPArray), In] INPUT[] pInputs, int cbSize);

#pragma warning disable 649
            internal struct INPUT
            {
                public UInt32 Type;
                public MOUSEKEYBDHARDWAREINPUT Data;
            }

            [StructLayout(LayoutKind.Explicit)]
            internal struct MOUSEKEYBDHARDWAREINPUT
            {
                [FieldOffset(0)]
                public MOUSEINPUT Mouse;
            }

            internal struct MOUSEINPUT
            {
                public Int32 X;
                public Int32 Y;
                public UInt32 MouseData;
                public UInt32 Flags;
                public UInt32 Time;
                public IntPtr ExtraInfo;
            }

#pragma warning restore 649


            public static void ClickOnPoint(IntPtr wndHandle, Point clientPoint)
            {
                var oldPos = Cursor.Position;

                /// get screen coordinates
                ClientToScreen(wndHandle, ref clientPoint);

                /// set cursor on coords, and press mouse
                Cursor.Position = new Point(clientPoint.X, clientPoint.Y);

                var inputMouseDown = new INPUT();
                inputMouseDown.Type = 0; /// input type mouse
                inputMouseDown.Data.Mouse.Flags = 0x0002; /// left button down

                var inputMouseUp = new INPUT();
                inputMouseUp.Type = 0; /// input type mouse
                inputMouseUp.Data.Mouse.Flags = 0x0004; /// left button up

                var inputs = new INPUT[] { inputMouseDown, inputMouseUp };
                SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT)));

                /// return mouse 
                Cursor.Position = oldPos;
            }
           
        }

        public Form1()
        {
            InitializeComponent();
        } 

        private void Form1_Load(object sender, EventArgs e)
        {
            webBrowser1.Navigate("URL");
        }

        private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {

        }
       
        private void timer1_Tick(object sender, EventArgs e)
        {
            ClickOnPointTool.ClickOnPoint(this.Handle, new Point(912, 93));
            Thread.Sleep(500);
            ClickOnPointTool.ClickOnPoint(this.Handle, new Point(777, 600));
        }
        

        private void timer2_Tick(object sender, EventArgs e)
        {
            //IntPtr hwnd = FindWindow(null, "Belas App v1.1");
            ClickOnPointTool.ClickOnPoint(this.Handle, new Point(927, 118));
            Thread.Sleep(500);
            ClickOnPointTool.ClickOnPoint(this.Handle, new Point(777, 600));
        }

        private void Start_Click(object sender, EventArgs e)
        {
            this.timer1.Enabled = true;
            this.timer2.Enabled = true;
        }

        private void Stop_Click(object sender, EventArgs e)
        {
            this.timer1.Enabled = false;
            this.timer2.Enabled = false;
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            
            ClickOnPointTool.ClickOnPoint(this.Handle, new Point(912, 93));
            Thread.Sleep(500);
            ClickOnPointTool.ClickOnPoint(this.Handle, new Point(777, 600));
            
            ClickOnPointTool.ClickOnPoint(this.Handle, new Point(927, 118));
            Thread.Sleep(500);
            ClickOnPointTool.ClickOnPoint(this.Handle, new Point(777, 600));
        }


    }
}

Ten kod świetnie odgrywa swoja role, mianowicie klika lewa myszka w dane koordynaty bez użycia myszki, teraz moje pytanie:

Czy jest możliwość aby dana symulacja była wykonywana tylko na mojej aplikacji, do tego zminimalizowanej, abym mógł wykonywać inne czynności, bez ingerencji w inne programy?

Znalazłem metode FindWindow:

// BM_CLICK to jest np. left button lick
        private const int BM_CLICK = 0x00F5;

        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        // Find window by Caption only. Note you must pass IntPtr.Zero as the first parameter.
        [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
        static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
 //IntPtr hwnd = FindWindow(null, "APP");
            IntPtr hwndChild = IntPtr.Zero;
            IntPtr hwnd = IntPtr.Zero;
            hwnd = FindWindow(null, "APP");
            hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "APP", "Add");
            SendMessage(hwndChild, BM_CLICK, IntPtr.Zero, IntPtr.Zero);

Niestety myślę, że dana funkcja to nie wszystko, dlatego zdecydowałem się zapytać na forum.

DZIĘKUJE Z GÓRY ZA POMOC.

0

A to nie jest tak, że symulowane jest klikanie w danym punkcie ekranu (bezwzględny lub względny) i na zminimalizowanej aplikacji po prostu nie da w ten sposób się tego zrobić?

Zobacz tutaj:
http://www.codeproject.com/Questions/379518/Can-I-SIMULATE-a-MOUSE-CLICK-in-a-minimized-window

Z tego co pobieżnie patrzyłem to nie jest 100% rozwiązanie, ale może na coś cię naprowadzi.

0

Widziałem już ten temat, jednak tam jest właśnie na FindWindow, a generalnie to bedzie mi jeżeli dobrze rozumiem na nim operowało pierw przywracając go na główny ekran, czyli co określony czas będzie mi ingerował w moje inne prace .

Dodatkowo cieżko mi to zastosować u siebie w timerze:

 private int BM_CLICK = ClickOnPointTool.ClickOnPoint(this.Handle, new Point(912, 93));

        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
        static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
         private void timer3_Tick(object sender, EventArgs e)
        {
            IntPtr hwndChild = IntPtr.Zero;
            IntPtr hwnd = IntPtr.Zero;
            hwnd = FindWindow(null, "APP");
            hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "APP", "Add");
            SendMessage(hwndChild, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
        }

Wyskakują mi błędy, mianowicie:

Error 1 Keyword 'this' is not available in the current context
Error 2 The best overloaded method match for 'WindowsFormsApplication1.Form1.SendMessage
Error 3 Argument 2: cannot convert from 'int' to 'uint'

z którymi nie bardzo wiem jak sobie poradzić...: (

0

Nie można Ci pomóc, jeżeli dajesz sprzeczne informacje:

jakim cudem przypisujesz do zmiennej wynik funkcji

private int BM_CLICK = ClickOnPointTool.ClickOnPoint(this.Handle, new Point(912, 93));

skoro ona zwraca void?

public static void ClickOnPoint(IntPtr wndHandle, Point clientPoint)

PS.
Błędy 2 i 3 wyeliminujesz rzutowaniem na uint
Błąd 1 - skąd mamy wiedzieć gdzie jest to this?

0

Przepraszam za tak chaotyczna wypowiedź,

Spróbowałem rzutowania na unit jednak dalej nie mogę wynaleźć jak przekontrastować void to int, może kod podam poniżej :

private void button1_Click_1(object sender, EventArgs e)
        {
            
            ClickOnPointTool.ClickOnPoint(this.Handle, new Point(912, 93));
            Thread.Sleep(500);
            ClickOnPointTool.ClickOnPoint(this.Handle, new Point(777, 600));
            
            ClickOnPointTool.ClickOnPoint(this.Handle, new Point(927, 118));
            Thread.Sleep(500);
            ClickOnPointTool.ClickOnPoint(this.Handle, new Point(777, 600));
        }

        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
        static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);

        private void timer3_Tick(object sender, EventArgs e)
        {
            uint cz = button1_Click_1(this.Handle, EventArgs.Empty);
            IntPtr hwndChild = IntPtr.Zero;
            IntPtr hwnd = IntPtr.Zero;
            hwnd = FindWindow(null, "Belas App v1.1");
            hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Belas App v1.1", "Add");
            SendMessage(hwndChild, cz, IntPtr.Zero, IntPtr.Zero);
        }

Bląd następujacy: "Cannot implicitly convert 'void' to 'unit'."

Bardzo proszę o pomoc.

0

"Cannot implicitly 'void' to 'unit'."

przestań z pamięci przepisywać kody błędów i kod tylko je kopiuj

0

Error 1 Cannot implicitly convert type 'void' to 'uint' teraz lepiej?:P

1

BM_CLICK to stała liczba o wartości 0x00F5 a nie zdarzenie kliknięcia

przestań robić losowe rzeczy w programie, nie da się zamienić "nicości" (void) w liczbę (uint) chyba że się bawisz w boga
nie można zdarzenia przypisać do zmiennej liczbowej

w ogóle to wszystko działa inaczej niż Ci się chyba wydaje

0

Tak, wiem BM_CLICK , patrzysz troszkę za wysoko, w ostatnim poście jest aktualny kodzik.
Chodzi o to żeby program wywoływał zdarzenie klickniecia (opisaną) przez void w zminimalizowanym oknie, to jedyny trop na jaki natrafiłem jednak niestety nie jestem w stanie przekazać zdefiniowanego void Buttonu do Timera, który wskazywał będzie na zminimalizowane okno dlatego proszę o pomoc...

0

pisałem na podstawie najnowszego kodu
bardzo ciężko Cię zrozumieć bo używasz terminów wymyślając sobie ich znaczenie

beli napisał(a):

wywoływał zdarzenie klickniecia (opisaną) przez void w zminimalizowanym oknie

nic nie rozumiem

nie jestem w stanie przekazać zdefiniowanego void Buttonu do Timera

nie rozumiem

wskazywał będzie na zminimalizowane okno

nie rozumiem

opisz prostymi słowami, nie używaj terminów technicznych które wydaje Ci się że rozumiesz

0

Może inaczej, mam kod, który teraz nie zwraca mi żadnego błędu, jednak na zminimalizowanej aplikacji nie wykonuje przycisku:

 namespace WindowsFormsApplication1
{
    public partial class APP : Form
    {

        public class ClickOnPointTool
        {

            [DllImport("user32.dll")]
            static extern bool ClientToScreen(IntPtr hWnd, ref Point lpPoint);

            [DllImport("user32.dll")]
            internal static extern uint SendInput(uint nInputs, [MarshalAs(UnmanagedType.LPArray), In] INPUT[] pInputs, int cbSize);

#pragma warning disable 649
            internal struct INPUT
            {
                public UInt32 Type;
                public MOUSEKEYBDHARDWAREINPUT Data;
            }

            [StructLayout(LayoutKind.Explicit)]
            internal struct MOUSEKEYBDHARDWAREINPUT
            {
                [FieldOffset(0)]
                public MOUSEINPUT Mouse;
            }

            internal struct MOUSEINPUT
            {
                public Int32 X;
                public Int32 Y;
                public UInt32 MouseData;
                public UInt32 Flags;
                public UInt32 Time;
                public IntPtr ExtraInfo;
            }

#pragma warning restore 649


            public static void ClickOnPoint(IntPtr wndHandle, Point clientPoint)
            {
                var oldPos = Cursor.Position;

                /// get screen coordinates
                ClientToScreen(wndHandle, ref clientPoint);

                /// set cursor on coords, and press mouse
                Cursor.Position = new Point(clientPoint.X, clientPoint.Y);

                var inputMouseDown = new INPUT();
                inputMouseDown.Type = 0; /// input type mouse
                inputMouseDown.Data.Mouse.Flags = 0x0002; /// left button down

                var inputMouseUp = new INPUT();
                inputMouseUp.Type = 0; /// input type mouse
                inputMouseUp.Data.Mouse.Flags = 0x0004; /// left button up

                var inputs = new INPUT[] { inputMouseDown, inputMouseUp };
                SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT)));

                /// return mouse 
                Cursor.Position = oldPos;
            }
           
        }

        public APP()
        {
            InitializeComponent();
        } 

        private void Form1_Load(object sender, EventArgs e)
        {
            webBrowser1.Navigate("URL");
        }

        private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {

        }
        private const int BM_CLICK = 0x00F5;
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
        static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);

        private void button1_Click_1(object sender, EventArgs e)
        {
            ClickOnPointTool.ClickOnPoint(this.Handle, new Point(912, 93));
            Thread.Sleep(500);
            ClickOnPointTool.ClickOnPoint(this.Handle, new Point(777, 600));
        }
        private void button2_Click(object sender, EventArgs e)
        {
            ClickOnPointTool.ClickOnPoint(this.Handle, new Point(927, 118));
            Thread.Sleep(500);
            ClickOnPointTool.ClickOnPoint(this.Handle, new Point(777, 600));
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            IntPtr hwndChild = IntPtr.Zero;
            IntPtr hwnd = IntPtr.Zero;
            hwnd = FindWindow(null, "APP");
            hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "WindowsForms10.BUTTON.app.0.bf7771_r16_ad1", "APP");//WindowsForms10.BUTTON.app.0.bf7771_r16_ad1 pobrane z winspy
            SendMessage(hwndChild, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
        }

        private void timer3_Tick(object sender, EventArgs e)
        {
            IntPtr hwndChild = IntPtr.Zero;
            IntPtr hwnd = IntPtr.Zero;
            hwnd = FindWindow(null, "APP");
            hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "WindowsForms10.BUTTON.app.0.bf7d44_r16_ad1", "APP");//WindowsForms10.BUTTON.app.0.bf7d44_r16_ad1 pobrane z winspy
            SendMessage(hwndChild, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
        }

        private void Start_Click(object sender, EventArgs e)
        {
            this.timer1.Enabled = true;
            this.timer3.Enabled = true;
        }

        private void Stop_Click(object sender, EventArgs e)
        {
            this.timer1.Enabled = false;
            this.timer3.Enabled = false;
        }
    }
}
0

UP

1

Z tego co zrozumiałem chcesz zasymulować programowe kliknięcie myszą w obszar innej aplikacji nawet gdy jest ona zminimalizowana.
Niestety jest to raczej niemożliwe. Dotychczasowy kod niezupełnie symuluje kliknięcie myszą bez poruszania jej - metoda ClickOnPoint zapamiętuje położenie myszy, przesuwa kursor na nową pozycję, symuluje kliknięcie i na koniec przesuwa kursor na pierwotną zapamiętaną pozycję.
Dla użytkownika jest ruch myszki jest niezauważalny ale nadal jest to przesunięcie kursora nad jakąś pozycję na ekranie - jeśli nie widać okna aplikacji to nie uda się wykonać kliknięcia w jego obszarze.
Takie "klikanie" w zminimalizowanym oknie często występuje w botach do gier ale tam zazwyczaj jest realizowane przez modyfikację pamięci gry albo, w przypadku gier sieciowych, przez modyfikację pakietów w połączeniu serwer - klient.

1 użytkowników online, w tym zalogowanych: 0, gości: 1