Możesz podać więcej informacji, aby uzyskać przydatną odpowiedź.
Andy
36
Wskazówka: jeśli tytuł jest taki sam jak pytanie, oznacza to, że jest on o wiele za długi lub pytanie jest zbyt krótkie. W tym przypadku jest to drugie, musisz podać dużo więcej kontekstu, aby ktokolwiek miał rozsądną szansę na udzielenie użytecznej odpowiedzi.
Guffa
Odpowiedzi:
145
Połączyłem kilka źródeł, aby utworzyć poniższy kod, którego obecnie używam. Usunąłem również odwołania do Windows.Forms, dzięki czemu mogę go używać z aplikacji konsoli i WPF bez dodatkowych odniesień.
using System;
using System.Runtime.InteropServices;publicclassMouseOperations{[Flags]publicenumMouseEventFlags{LeftDown=0x00000002,LeftUp=0x00000004,MiddleDown=0x00000020,MiddleUp=0x00000040,Move=0x00000001,Absolute=0x00008000,RightDown=0x00000008,RightUp=0x00000010}[DllImport("user32.dll",EntryPoint="SetCursorPos")][return:MarshalAs(UnmanagedType.Bool)]privatestaticexternboolSetCursorPos(int x,int y);[DllImport("user32.dll")][return:MarshalAs(UnmanagedType.Bool)]privatestaticexternboolGetCursorPos(outMousePoint lpMousePoint);[DllImport("user32.dll")]privatestaticexternvoid mouse_event(int dwFlags,int dx,int dy,int dwData,int dwExtraInfo);publicstaticvoidSetCursorPosition(int x,int y){SetCursorPos(x, y);}publicstaticvoidSetCursorPosition(MousePoint point){SetCursorPos(point.X, point.Y);}publicstaticMousePointGetCursorPosition(){MousePoint currentMousePoint;var gotPoint =GetCursorPos(out currentMousePoint);if(!gotPoint){ currentMousePoint =newMousePoint(0,0);}return currentMousePoint;}publicstaticvoidMouseEvent(MouseEventFlagsvalue){MousePoint position =GetCursorPosition();
mouse_event
((int)value,
position.X,
position.Y,0,0);}[StructLayout(LayoutKind.Sequential)]publicstructMousePoint{publicint X;publicint Y;publicMousePoint(int x,int y){
X = x;
Y = y;}}}
Nie widzę żadnej przewagi tego długiego kodu źródłowego nad tym, co opublikował Marcos Placona 17 miesięcy temu.
Al Kepp
46
Biorąc pod uwagę niejasność pytania, pomyślałem, że ludzie mogą skorzystać na przykładzie, który pozwala im zrobić coś więcej niż tylko lewe kliknięcie zasysanie prawego lub środkowego kliknięcia lub zezwolenie na kliknięcie i przeciągnięcie.
Keith
2
Działa świetnie. Przyszedłem tutaj, szukając czegoś takiego
CSharpie
To jest to, czego szukam, ale jak kliknąć w dół, przesunąć mysz w inne miejsce, a następnie zwolnić?
ninjaxelite
1
@ninjaxelite Zgaduję, że wyślesz 1. SetCursorPos, 2. MouseEvent(LeftButtonDown), 3. SetCursorPos, 4. MouseEvent(LeftButtonUp). Potencjalnie owinąć to metodą pomocniczą
Michał Ciechan
137
Przykład, który znalazłem gdzieś tutaj w przeszłości. Może być pomocna:
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;publicclassForm1:Form{[DllImport("user32.dll",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]publicstaticexternvoid mouse_event(uint dwFlags,uint dx,uint dy,uint cButtons,uint dwExtraInfo);//Mouse actionsprivateconstint MOUSEEVENTF_LEFTDOWN =0x02;privateconstint MOUSEEVENTF_LEFTUP =0x04;privateconstint MOUSEEVENTF_RIGHTDOWN =0x08;privateconstint MOUSEEVENTF_RIGHTUP =0x10;publicForm1(){}publicvoidDoMouseClick(){//Call the imported function with the cursor's current positionuint X =(uint)Cursor.Position.X;uint Y =(uint)Cursor.Position.Y;
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, X, Y,0,0);}//...other code needed for the application}
Dobrze rozegrane. Dodano odniesienie do oryginalnej odpowiedzi
Marcos Placona
2
Otrzymuję błąd z tym kodem: Wywołanie funkcji PInvoke „MyForm! MyForm.Form1 :: mouse_event” spowodowało wyważenie stosu. Jest to prawdopodobne, ponieważ zarządzany podpis PInvoke nie pasuje do niezarządzanego podpisu docelowego. Sprawdź, czy konwencja wywoływania i parametry podpisu PInvoke są zgodne z docelowym niezarządzanym podpisem. Jakieś pomysły?
Abdulla
12
Musisz rzucić X i Y do uintów.
Dibesjr,
1
Działa idealnie, wymaga pewnych zmian pozycji kursora zgodnie z wymaganiami ...
Anurag Rabadia
14
Niektóre kontrolki, takie jak Button w System.Windows.Forms, mają do tego celu metodę „PerformClick”.
To trochę dziwne, że zostało to odizolowane w przestrzeni nazw testowych interfejsu użytkownika programu Visual Studio, ale przejmę to przez PInvoke każdego dnia, kiedy nie muszę filtrować zdarzeń według urządzenia.
kayleeFrye_onDeck
2
Wygląda na to, że wersja Visual Studio Community nie jest dostarczana z tą biblioteką DLL.
CM,
2
Właśnie spędziłem godzinę próbując to uruchomić, kopiując biblioteki DLL z projektu „zakodowanego testu interfejsu użytkownika” do innego i jeśli nie używasz typu projektu „kodowany test interfejsu użytkownika”, moja rada brzmi: nie przejmuj się. Nawet gdy skopiowałem wszystkie niezbędne biblioteki DLL, wyrzucił plik InvalidUITestExtensionPackageException, więc niestety wydaje się być bardzo wybredny, jeśli chodzi o uruchamianie w określonym typie projektu.
Jez
@Jez - Dobrze wiedzieć, dzięki. Sam jeszcze nie widziałem żadnych problemów, ale teraz przynajmniej wiem, że niektóre istnieją; 0)
Rusty Nail
5
Wypróbowałem kod, który opublikował Marcos i nie zadziałał. Cokolwiek podano współrzędnej Y, kursor nie poruszał się po osi Y. Poniższy kod zadziała, jeśli chcesz ustawić kursor względem lewego górnego rogu pulpitu, a nie względem aplikacji.
[DllImport("user32.dll",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]publicstaticexternvoid mouse_event(long dwFlags,long dx,long dy,long cButtons,long dwExtraInfo);privateconstint MOUSEEVENTF_LEFTDOWN =0x02;privateconstint MOUSEEVENTF_LEFTUP =0x04;privateconstint MOUSEEVENTF_MOVE =0x0001;publicvoidDoMouseClick(){
X =Cursor.Position.X;
Y =Cursor.Position.Y;//move to coordinates
pt =(Point)pc.ConvertFromString(X +","+ Y);Cursor.Position= pt;//perform click
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);}
Używam tylko funkcji mouse_event, aby faktycznie wykonać kliknięcie. Możesz podać X i Y jakie współrzędne chcesz, użyłem wartości z pola tekstowego:
X =Convert.ToInt32(tbX.Text);
Y =Convert.ToInt32(tbY.Text);
to jest dla mnie właściwe, w zasadzie Cursor.Positionwystarcza do umieszczenia kursora myszy w dowolnym miejscu, a następnie użyj WIN32API, aby wykonać faktyczne kliknięcie.
Ge Rong
0
są to potrzeby, których nie mogę spełnić, aby zrobić coś takiego jak Keith czy Marcos Placona, zamiast po prostu je realizować
using System;
using System.Windows.Forms;
namespace WFsimulateMouseClick{publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}privatevoidForm1_Load(object sender,EventArgs e){
button1_Click(button1,newMouseEventArgs(System.Windows.Forms.MouseButtons.Left,1,1,1,1));//by the way//button1.PerformClick();// and//button1_Click(button1, new EventArgs());// are the same}privatevoid button1_Click(object sender,EventArgs e){MessageBox.Show("clicked");}}}
Odpowiedzi:
Połączyłem kilka źródeł, aby utworzyć poniższy kod, którego obecnie używam. Usunąłem również odwołania do Windows.Forms, dzięki czemu mogę go używać z aplikacji konsoli i WPF bez dodatkowych odniesień.
źródło
1. SetCursorPos, 2. MouseEvent(LeftButtonDown), 3. SetCursorPos, 4. MouseEvent(LeftButtonUp)
. Potencjalnie owinąć to metodą pomocnicząPrzykład, który znalazłem
gdzieśtutaj w przeszłości. Może być pomocna:źródło
Niektóre kontrolki, takie jak Button w System.Windows.Forms, mają do tego celu metodę „PerformClick”.
źródło
Microsoft.VisualStudio.TestTools.UITesting
źródło
InvalidUITestExtensionPackageException
, więc niestety wydaje się być bardzo wybredny, jeśli chodzi o uruchamianie w określonym typie projektu.Wypróbowałem kod, który opublikował Marcos i nie zadziałał. Cokolwiek podano współrzędnej Y, kursor nie poruszał się po osi Y. Poniższy kod zadziała, jeśli chcesz ustawić kursor względem lewego górnego rogu pulpitu, a nie względem aplikacji.
Używam tylko funkcji mouse_event, aby faktycznie wykonać kliknięcie. Możesz podać X i Y jakie współrzędne chcesz, użyłem wartości z pola tekstowego:
źródło
Cursor.Position
wystarcza do umieszczenia kursora myszy w dowolnym miejscu, a następnie użyj WIN32API, aby wykonać faktyczne kliknięcie.są to potrzeby, których nie mogę spełnić, aby zrobić coś takiego jak Keith czy Marcos Placona, zamiast po prostu je realizować
źródło
null
w drugim parametrze, wyrzuci onNullReferenceException
, zamiast tego użyjEventArgs.Empty
NullReferenceException