Symulacja LPM

0

witam

otoz chodzi mi o zasymulowanie klikniecia lewym przyciskiem myszki

szukalem przyklady na necie ale polegaja one na tym ze przesowaja kursor myszki i klikaja ;)
a mnie chodzi o taki przyklad w ktorym na wybranym miejscy by klikalo a ja moglbym normalnie dalej poslugiwac sie myszka :)

z gory dziekuje

pzdr Andrzej

0

Na wybranym miejscu czego chcesz kliknąć?
Bo na 99% zabierasz się do tego ze złej strony.

0
somekind napisał(a)

Na wybranym miejscu czego chcesz kliknąć?
Bo na 99% zabierasz się do tego ze złej strony.

pewnie tak nie zaprzeczam , wkoncu to moje początki c sharp

a co do klikniecia to w innym programie na buttona

pzdr Andrzej

0

Więc chcesz użyć WinAPI, żeby dostać się do tego buttona. Użyj wyszukiwarki forumowej albo lepiej Google.

0

szukalem szukale i znalazlem ale nie wiem dlaczego nie dziala :(

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

        [DllImport("user32.dll")]
        static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

        public enum WMessages : int
        {
            WM_LBUTTONDOWN = 0x201, //Left mousebutton down 
            WM_LBUTTONUP = 0x202,  //Left mousebutton up 
            WM_LBUTTONDBLCLK = 0x203, //Left mousebutton doubleclick 
            WM_RBUTTONDOWN = 0x204, //Right mousebutton down 
            WM_RBUTTONUP = 0x205,   //Right mousebutton up 
            WM_RBUTTONDBLCLK = 0x206, //Right mousebutton doubleclick 
            WM_KEYDOWN = 0x100,  //Key down 
            WM_KEYUP = 0x101,   //Key up 
        } 
  private void button1_Click(object sender, EventArgs e)
        {
            if (PositionX.Text.Length > 0 && PositionY.Text.Length > 0 && WinowsName.Text.Length > 0)
            {
                int x = Convert.ToInt16(PositionX.Text);
                int y = Convert.ToInt16(PositionY.Text);
                ControlClickWindow(WinowsName.Text, "left", x,y, false);
            }
        }

        public void _SendMessage(IntPtr handle, int Msg, int wParam, int lParam)
        {
            IntPtr test = SendMessage(handle, Msg, wParam, lParam);
            button1.Text = test.ToString();// wynik 0
        }


        public int MakeLParam(int LoWord, int HiWord)
        {
            return ((HiWord << 16) | (LoWord & 0xffff));

        }


        public IntPtr FindWindow(string wndName)
        {
            return FindWindow(null, wndName);
        }

        public void ControlClickWindow(string wndName, string button, int x, int y, bool doubleklick)
        {
            IntPtr hWnd = FindWindow(null, wndName);
            //button1.Text = hWnd.ToString();
            int LParam = MakeLParam(x, y);
            //button1.Text = LParam.ToString();
            int btnDown = 0;
            int btnUp = 0;

            if (button == "left")
            {
                btnDown = (int)WMessages.WM_LBUTTONDOWN;
                btnUp = (int)WMessages.WM_LBUTTONUP;
            }

            if (button == "right")
            {
                btnDown = (int)WMessages.WM_RBUTTONDOWN;
                btnUp = (int)WMessages.WM_RBUTTONUP;
            }


            if (doubleklick == true)
            {
                _SendMessage(hWnd, btnDown, 0, LParam);
                _SendMessage(hWnd, btnUp, 0, LParam);
                _SendMessage(hWnd, btnDown, 0, LParam);
                _SendMessage(hWnd, btnUp, 0, LParam);
            }

            if (doubleklick == false)
            {
                _SendMessage(hWnd, btnDown, 0, LParam);
                _SendMessage(hWnd, btnUp, 0, LParam);
            }

        } 

prosze o pomoc
po wpisaniu parametrow zero reakcji

pzdr Andrzej

0

uproscilem kod do takiej postaci i dalej nic :(

[DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
 private void button1_Click(object sender, EventArgs e)
        {
            if (PositionX.Text.Length > 0 && PositionY.Text.Length > 0 && WinowsName.Text.Length > 0)
            {
                int x = Convert.ToInt16(PositionX.Text);
                int y = Convert.ToInt16(PositionY.Text);
                IntPtr handle = FindWindow(null, WinowsName.Text);
                IntPtr lParam = (IntPtr)((y << 16) | x);
                IntPtr wParam = IntPtr.Zero;
                const uint downCode = 0x201; 
                const uint upCode = 0x202; 
                SendMessage(handle, downCode, wParam, lParam); 
                SendMessage(handle, upCode, wParam, lParam); 
            }
        }
1

Sprawź w debbugerze czy znajduje ci okno (czy handle = 0), bo to jest prawdopodobna przyczyna :D

0

int handle= FindWindow(null, "Kalkulator");

handle wynosi 197994

wiec to raczej nie to bedzie przyczyna ?? chyba ze zle sprawdzam wartosc uchwytu ;)

pzdr

1

Heh, skoro coś ci zwraca to znaczy że uchwyt jest OK ;). Mi jakoś zwracało zero - pewnie źle wpisałem nazwę albo coś...

Poczekaj chwilę, właśnie szukam książki z której uczyłem się podstaw C#, wydaje mi się że tam było coś o WINapi... Za chwilę napiszę czy coś znalazłem :]

0

Skoro handle jest okej, to może popróbuj powysyłać wiadomości na forme z której to uruchamiasz, i czy będzie działać :)

0

w taki sposób działa :]

        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindowEx(IntPtr hwndParent,IntPtr hwndChildAfter,string lpszClass,string lpszWindow); 


        private void button1_Click(object sender, EventArgs e)
        {
                IntPtr handle = FindWindow(null, "Kalkulator");
                IntPtr fiveKey = FindWindowEx(handle, IntPtr.Zero, "Button", "5");
                SendMessage(fiveKey, (int)WMessages.WM_LBUTTONDOWN, 0, 0);
                SendMessage(fiveKey, (int)WMessages.WM_LBUTTONUP, 0, 0);            
        }

tak jest prościej, znajdujemy uchwyt do okna, do kontrolki, i wysyłamy wiadomość do kontrolki x)

1

Kontynuuję w nowym poście bo astray mi wskoczył :]

Zrobiłem sobie dwa projekty - masz tutaj kod

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        [DllImport("user32.dll")]
        private static extern IntPtr SendMessage(IntPtr Hwnd, uint Msg, int Wparan, int lparam);

        [DllImport("user32.dll")]
        private static extern IntPtr FindWindow(string className, string WinName);

        private void button1_Click(object sender, EventArgs e)
        {
            IntPtr handle = FindWindow(null, "TheForm");

            UInt16 x = 100;
            UInt16 y = 50;

            // Nie wiem czy z IntPtr poniżej to był (będzie) dobry pomysł, nogą na różnych platformach mieć różne ilości bitów...
            // Na przykład ja mam system 64 bitowy, i intptr ma, z tego co pamiętam, 8 bajtów a nie 4 jak na 32bitowych.

            Int32 lParam = (Int32)((y << 16) | x);
            Int32 wParam = 0;

            const uint downCode = 0x201; 

            SendMessage(handle, 0x201, lParam, wParam);
        }
    }

I drugi projekt:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg != 308)
            {
                listBox1.Items.Add(m.Msg);
                base.WndProc(ref m);
            }
        }

        private void listBox1_MouseDown(object sender, MouseEventArgs e)
        {
            throw new Exception("lol :)!");
        }
    }

Po przyciśnięciu przycisku na formie 1 rzeczywiście coś dochodzi do formy 2, więc nie wszystko stracone ;) Komunikat 513 jeśli kojarzysz, bo ja nie za bardzo :/

0

nie działa najprawdodobniej dla tego że wiadomość dociera na głowne okno, byćmoże nawet jezeli podacie punkty przycisku to klikniecie będzie jakby pod nim?

Potestujcie tak jak napisałem wcześniej, działa na 100%

0
dark_astray napisał(a)

nie działa najprawdodobniej dla tego że wiadomość dociera na głowne okno, byćmoże nawet jezeli podacie punkty przycisku to klikniecie będzie jakby pod nim?

Potestujcie tak jak napisałem wcześniej, działa na 100%

wszystko jest ok ale cza znac uchwyt kontrolki a Kalkulatorze to nie problem znalezc
gorzej z programem ktory chce uzyc do tego
pzdr Andrzej

MSM napisał(a)

Kontynuuję w nowym poście bo astray mi wskoczył :]

Zrobiłem sobie dwa projekty - masz tutaj kod

    public partial class Form1 : Form
    {
        ...................................

            SendMessage(handle, 0x201, lParam, wParam);
        }
    }

Po przyciśnięciu przycisku na formie 1 rzeczywiście coś dochodzi do formy 2, więc nie wszystko stracone ;) Komunikat 513 jeśli kojarzysz, bo ja nie za bardzo :/

moze dlatego zw pomyliles pozycje w SendMessage lParam i wParam

0

wszedzie w necie sa przykaldy na podstawie kalkulatora
i zaden z nich mi nie dziala :(

przegladajac message przez spy++
tak wyglada dla przycisku 9
SendMessage(handle, 0x111, 0x00000085, 0);

pzdr Andrzej

0

Jeżeli użyjecie po prostu findform i wyslecie wiadomość. To wiadomość z mousedown/up/click zostanie wysłana prosto na głowna forme.
@msm dodaj sobie zdarzenie dla głownej formy(tej co kilkasz na nią z innego programu) mousedown i niech Ci wyświetla wtedy messageBoxa i faktycznie messageBox się pojawi. Nawet jeśli walniesz buttona na całą formę, i tak wiadomość dotrze do głownej formy. Wysłanie wiadomości to zapewne nie to samo co klikniecie, ponieważ klikamy na to co jest na samym wierzchu. Aby "kliknąć", tak wiadomościowo ( ;P ) na kontrolkę trzeba mieć jej uchwyt (chyba)

        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindowEx(IntPtr hwndParent,IntPtr hwndChildAfter,string lpszClass,string lpszWindow); 
1

Fajna dyskusja na temat winAPI się robi ;) szkoda tylko że niezbyt się na tym (przynajmniej ja) znamy :]

Ale masz rację astray, jeśli do sendmessage dam handle buttona to wszystko działa :/
tylko jak on ma niby znaleźć to handle...

gibon - podaj linki do tych przykładów to będzie prościej... Zresztą zaciekawiłeś mnie tym winAPI :P

0

Racja, gdybyśmy się na tym znali :D

"tylko jak on ma niby znaleźć to handle..."
No właśnie... problem. Zapewne ma klikać na jakiś bardziej skomplikowany program, a nie na kalkulator x)

0

np to :
http://www.edgeofnowhere.cc/viewtopic.php?t=396398
i w google szukalem pod
C# SendMessage Click

tu jest tez ciekawa stronka :) niestety bez przykaldow :(
http://custom.programming-in.net/articles/art9-1.asp?f=FindWindowEx
itp

a co do programu w jakim chce kliknac to jest platforma brookerska FXCM Trade Station
pzdr Andrzej

0

A może zrobić to za pomocą SendInput?
Będzie wyglądało jak prawdziwe klikniecie.

Za pomoca FindWindow dostajemy handle
następnie SetForegroundWindow(handle); SetFocus(handle)? ja robiłem z tym pierwszym
i na koniec SendInput
http://homeofcox-cs.blogspot.com/2008/07/c-simulate-mouse-and-keyboard-events.html

Testowałem i działa. Tylko nie wiem czy w sposób jakiego oczekujesz.

  1. wywołujesz metody
    2.ustawia dane okno na aktywne
  2. ewentualnie przemieszcza kursor myszy, i wykonuje klikniecie
  3. dajemy jakiegos sleepa i ustawiamy na aktywne nasze okno.
0
dark_astray napisał(a)

A może zrobić to za pomocą SendInput?
Będzie wyglądało jak prawdziwe klikniecie.

Za pomoca FindWindow dostajemy handle
następnie SetForegroundWindow(handle); SetFocus(handle)? ja robiłem z tym pierwszym
i na koniec SendInput
http://homeofcox-cs.blogspot.com/2008/07/c-simulate-mouse-and-keyboard-events.html

Testowałem i działa. Tylko nie wiem czy w sposób jakiego oczekujesz.

  1. wywołujesz metody
    2.ustawia dane okno na aktywne
  2. ewentualnie przemieszcza kursor myszy, i wykonuje klikniecie
  3. dajemy jakiegos sleepa i ustawiamy na aktywne nasze okno.

ten punkt 3 da sie ta metoda ominac ?? bo mnie zalezy na tym zebym mogl w trakcie pracy programu mogl wykonywac inne czynosci

pzdr Andrzej

0

no juz wiem i dziala :)

mianowicie
ten przyklad z :
FindWindowEx
dziala w wysmienicie :)
tylko mylace sa okreslenia w przykaladach ze "Button","5" to jest uchywyt do buttona a tak naprawde to jest uchwyt do Classy
wiec wystarczy miec uchwyt do Classy podac parametry i zrobic klikniecie :D
jednak nalezy pamietac ze X i Y to jest polozenie od krancow Classy nie calego ekranu :)
ale ogolnie dziala wysmienicie :)

a i wParam powinien byc 0x00000001 a nie zreo :)

tak to wygląda na prodstawie programu w ktorym chcialem kliknac w w ybrane miejsce

        [DllImport("user32.dll")]
        public static extern int FindWindow(string lpClassName, string lpWindowName);
        [DllImport("user32.dll")]
        public static extern int SendMessage(int hWnd, uint Msg, int wParam, IntPtr lParam);
        [DllImport("user32.dll")]
        private static extern int FindWindowEx(int parentHandle, int childAfter, string className, string windowTitle);
        [DllImport("user32.dll", CharSet = CharSet.Auto)] // used for button-down & button-up
        private static extern int PostMessage(int hWnd, int msg, int wParam, int lParam);
        private void button1_Click(object sender, EventArgs e)
        {
            int x = 0;
            int y = 0;
            if (PositionX.Text.Length > 0) x = Convert.ToInt16(PositionX.Text);
            if (PositionY.Text.Length > 0) y = Convert.ToInt16(PositionY.Text);
            int hwnd1 = FindWindow(null, "FXCM Trading Station");
            int hwnd2 = FindWindowEx(hwnd1, 0, "Afx:00400000:8:00010011:00000000:00000000", "");
            int hwnd3 = FindWindowEx(hwnd2, 0, "GSGridContainer", "");
            int hwnd4 = FindWindowEx(hwnd3, 0, "SysListView32", "Rates");
            SendMessage(hwnd4, 0x201, 0x00000001, MakeLParam((x - 2), (y - 127)));
            SendMessage(hwnd4, 0x202, 0x00000001, MakeLParam((x - 2), (y - 127)));
        }

        private static IntPtr MakeLParam(int LoWord, int HiWord)
        {
            return (IntPtr)((HiWord << 16) | (LoWord & 0xffff));
        }

pzdr Andrzej

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