PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Mausclick simulieren


snobordo
19.02.2002, 13:05
Weiß jemand wie man einen Mausclick simulieren kann? Ich brauch das für ein Programm, dass den Computer selber steuert.

Danke snobordo


Mimo
19.02.2002, 14:52
Ich hab´s mal hierin verschoben, weil´s mehr zu Windows-Programmierung passt. Hier sind die Funktionen, mit denen man einen User simulieren kann!

Es gibt folgende Windows-API hierfür:

mouse_event hier übergibt man Mauskoordinaten und den Status der Mausbuttons.

keybd_event funktioniert ähnlich wie Sendkeys in VB.

Diese beiden Funktionen sind einfach zu bedienen, weil keine Strukturen umständlich gefüllt werden müssen. Jedoch sind diese durch eine neuere Funktion ersetzt:

SendInput kann diverse Sachen ins System einspeisen. Es muss die Struktur INPUT entsprechende gefüllt werden.

Es wird zwar empfohlen, diese Funktion zu verwenden, jedoch die oberen beiden funktioneren genauso gut!

Falls Du keine MSDN-Library hast, um nach der genauen Beschreibung der Funktionen zu schauen, hier (http://msdn.microsoft.com/library/default.asp) findest Du die MSDN-Library auch online!

Gruss,
Mimo

xOOn
19.02.2002, 15:38
Wenn du exakte aktionen ausfuehren moechtest dann ist es oft besser direkt diese massage zu schicken, als diese erst ueber MouseKlick auszuloesen.

Windows arbeitet mit sogenannten Botschaften, und diese Botschaft kann nun auch ein anderes Programm schicken. zB kannst du einen Fenster WM_CLOSE schicken, das ist das selbe als wenn du auf Schliessen klickst.

Die Botschaften werden ueber SendMessage versendet.


Weitere Infos ueber SendMessage findest du unter
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/CommCtls/winui/messques_8ht1.asp

Eine liste mit Botschaften habe ich leider nicht gefunden

Bluppa
19.02.2002, 15:59
WM_LBUTTONUP LinkeMaustaste

WM_LBUTTONDOWN Rechte Maustaste

machst einfach mit ner case anweisung

xOOn
19.02.2002, 16:11
@Bluppa

da hast du dich mit den messages etwas verhaut

WM_LBUTTONUP LinkeMaustaste loslassen

WM_LBUTTONDOWN LinkeMaustaste druecken


wobei L fuer linke und R fuer rechte steht

WM_RBUTTONUP Rechte Maustaste loslassen

Diogenes
19.02.2002, 18:12
Die Mausbotschaften direkt verschicken ist gar keine schlechte Idee.

Grundsätzlich gilt dabei. daß lParam Position der Maus enthält: im Lo-Word die X- und im Hi-Word die Y-Position.

NB: SendMessage übernimmt:

1) das Zielfenster-Handle (Word)
2) die Botschafts-ID
3) den 16-Bit-Parameter
4) den 32-Bit-Parameter

Rückgabe:

ein 32-bit-Wert, den je nach Botschaft was bedeuted oder auch nicht.

Bluppa
19.02.2002, 20:34
da hast du dich mit den messages etwas verhaut

STIIMTT :rolleyes:

zwischen up und down besteht ein kleiner
aba entscheidener unterschied.....

snobordo
27.02.2002, 13:22
Kann mir mal jemand sagen wie ich das genau in VB anwenden kann (code)?

Patrik Graf
27.02.2002, 14:24
Also... in VB...?(

Ich glaube das könnte so gehen:

Bewegen:

mouse_event MOUSEEVENTF_MOVE,xCoord,yCoord,MOUSEEVENTF_WHEEL,GetMessageExtraInfo

Klicken geht dann natürlich so:

GetCursorPos Punkt
mouse_event MOUSEEVENTF_LEFTDOWN,Punkt.x,Punkt.y,MOUSEEVENTF_WHEEL,GetMessageExtraInfo
mouse_event MOUSEEVENTF_LEFTUP,Punkt.x,Punkt.y,MOUSEEVENTF_WHEEL,GetMessageExtraInfo

Du musst die Funktion beim klicken 2 mal aufrufen, da der Klick nur dann als Klick gezählt wird, wenn über einem Element das LEFTDOWN und das LEFTUP Ereignis ausgeführt wird. Du kannst aber auch beide Parameter kombinieren, nur weiß ich nicht mit welchem Operator. :D

Ich denke das mit der Punkt-Struktur der Variablen Punkt ist klar wie das funktionieren soll, oda? :D

Mimo
27.02.2002, 17:28
Hi!

wenn ich mal etwas korrigieren darf... ;) :D

Also, wenn Du per VB auf Windows-API zugreifst, solltest Du erstmal über "Add-Ins/Add-In Manager" den API-Viewer aktivieren.

Weil Du mußt nämlich noch die Funktionen deklarieren, damit VB weiss, wie die Paramter sind und in welcher DLL sich die Funktion befindet. In diesem Fall:

Public Declare Sub mouse_event Lib "user32" Alias "mouse_event" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)

(In einer Form muss das übrigens als "Private" deklariert werden)

und dann noch die dazugehörigen Konstanten:

Public Const MOUSEEVENTF_ABSOLUTE = &H8000 ´ absolute move
Public Const MOUSEEVENTF_LEFTDOWN = &H2 ´ left button down
Public Const MOUSEEVENTF_LEFTUP = &H4 ´ left button up
Public Const MOUSEEVENTF_MIDDLEDOWN = &H20 ´ middle button down
Public Const MOUSEEVENTF_MIDDLEUP = &H40 ´ middle button up
Public Const MOUSEEVENTF_MOVE = &H1 ´ mouse move
Public Const MOUSEEVENTF_RIGHTDOWN = &H8 ´ right button down
Public Const MOUSEEVENTF_RIGHTUP = &H10 ´ right button up)

(Es gibt auch noch MOUSEEVENTF_WHEEL um Bewegen des Rädchens auf der Maus zu simulieren, hab nur den Wert nicht parat)


Hiermit bewegst Du die Maus um 10 Pixel nach unten und 20 Pixel nach rechts:
mouse_event MOUSEEVENTF_MOVE, 10, 20, 0, 0

(Sollen die dx und dy-Werte absolut sein, dann muss MOUSEEVENTF_MOVE+MOUSEEVENTF_ABSOLUTE statt MOUSEEVENTF_MOVE angegeben werden)


Hiermit simulierst Du ein Klicken mit der linken Taste (dort, wo sich die Maus gerade befindet):
mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0
mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0


Gruss,
Mimo

Patrik Graf
27.02.2002, 18:00
Tja, in VB bin ich halt nich so der Profi... :D

Aber so falsch bin ich ja nich gelegen, hab nur vergessen die Deklarationen zu machen...

Naja, mit Delphi oder C++ Builder geht´s halt immernoch am besten mit den API´s :D :D

Diogenes
27.02.2002, 18:32
@Grafitty:

Vergiß nicht BPW/OWL! X( >> :D

snobordo
27.02.2002, 22:29
So, und jetzt hab ich leider noch ne Frage.
Iich will davor die Mausklicks abfangen, d.h. mein Programm soll ein Ereignis ausführen sobald auf einem beliebigen Ort in Windows geklickt wird. Ich will es nicht über ein extra Fenster machen.

Eigentlich brauch ich das ganze ja nur für ein Netzwerkprogramm, mit dem man die den anderen Computer über die Maus steuern kann.

Mimo
28.02.2002, 01:21
Dann würd ich mir das Leben einfach machen und eine fertige Soft verwenden (Carboncopy, PcAnywhere, Laplink usw.)

Was spricht dagegen?

Mimo

snobordo
28.02.2002, 13:35
Dagegen spricht, dass ich das Programm selber programmieren will und ich dadurch meinem Programm noch viele zusatzfunktionen hinzufügen kann, die bei fertigenn Programmen nicht vorhanden sind. Außerdem muss bei PC-Anywhere das Programm sichtbar auf dem zweiten rechner laufen, das kann ich jedoch z.B. bei einem selbst programmierten Programm verhindern!

Mimo
28.02.2002, 16:28
ok! man kann dann alles selber machen.

Nur wie willst Du es denn anstellen, dass DU den Bildschirm des Rechner siehst, den Du fernsteuern willst?

Aber ich weiche ab... kann Dir zu Deiner letzen Frage nichts genaues sagen. Ich würde unter dem Stichwort "hook" "hooking" oder so mal nachschauen in der MSDN-Lib.

gruss,
Mimo

Patrik Graf
28.02.2002, 21:33
Ok, snobordo.

Um einen Rechner mit der Maus fernsteuern zu können, benötigst du auf jeden Fall ein Fenster in dem du den Screenshot des anderen Rechners auf den Canvas (Canvas = Leinwand) zeichnen kannst. Da kannst du dann die vorgegebenen Fensterereignisse nutzen. Ist die einfachste Lösung und du hast den Vorteil das du sehen kannst was du da überhaupt auf dem anderen Rechner machst.

Das wars eigentlich :D

snobordo
28.02.2002, 22:07
das mit dem screenshot mach ich nicht, weil das winsock steuerelement viel zu kleine datenpakete senden kann. dadurch ist der download des screenshots sehr langsam. seidenn jamand weiß wie man ein bild konvertieren kann. denn der screenshot ist ca. 1,2 mb groß wenn ich ihn als 32 bit Bitmap speichere. ich müsste das bild also beispielsweise in eine JPG datei konvertieren. Weiß jemand wie das geht? Vielleicht mach ich ja deswegen noch ein neuen Eintrag auf.
Snobordo

Technote
01.03.2002, 07:20
hast du phozoshop oder andree bildbearbeitungsprogramme? dan oeffnest du es einfach und speicherst es als jpg ab...

Patrik Graf
01.03.2002, 08:10
Hmmm... mit Delphi geht das ziemlich einfach. Da muß man nur die Unit JPEG.PAS einbinden und dann geht die Geschichte schon so gut wie von alleine. Ich mach´s mir aber immer noch einfacher und nehm einfach ein Image, lade die Bitmap und speichere dann das Bild einfach als JPEG ab. Ich denke mit VB dürfte das nicht viel anders gehen :)

nj0y
01.03.2002, 08:45
Es ist eine weitverbreitete Sünde, Screenshots als JPG abzuspeichern! JPG ist ein Format für Fotos mit unscharfen Verläufen, nicht für scharfe Screenshots! Die Qualität nimmt deutlich ab, und andere Formate würden Screenshots häufig besser komprimieren. Ich empfehle PNG.

xOOn
01.03.2002, 09:18
naja nj0y PNG ist nich so einfach einzubinden, aber mit dem rest hast du recht!
also man kann ja das bmp komprimieren, verschicken und wieder dekompriemieren, zip-lzh oder andere

snobordo
01.03.2002, 18:24
also von dem format hab ich leider noch nicht viel gehört. Das mit dem zippen würde ich nicht machen, da das bild dann nur soehr wenig kleiner wird. Außerdem ist das sehr umständlich die datei zuerst zu zippen, und dann zu verschicken. Was ist mit anderen formaten, oder wenn man das bild einfach nur im 256 farbmodus speichert, statt es in ein anderes format zu bringen. dadurch müsste die datei ja schon erheblich kleiner werden. aber wie geht das. es gibt glaub ich so ein befehl mit dem man die farbpalette ändern kann oder so ähnlich. man müsste das bild wenn das geht einfach einlesen und mit dem Befehl PSet abmalen und wieder speichern geht das vielleicht? (ist aber weit hergeholt ;-) )

xOOn
02.03.2002, 14:32
warum soll man mit den zippen wenig rauskriegen?

bei jpg stimmt das aber wie jemand in einem vorigen post richtig darauf hingewiesen hat ist das bild dann nicht mehr pixel fuer pixel ident (jpg ist eine verlustbehaftete komprimierung)

ich meinte mit zippen das ganze als bmp speichern und danach zu komprimieren und dabei kann du sicher ein vielfaches rausschlagen

Felix Kaiser
03.03.2002, 14:05
Hach ihr Umstandkanonen. Zum eigentlichen Thread mal die schöne Bemerkung: Es geht auch einfacher ;)

Mausklick bei Buttons simulieren:

SendMessage(ButtonHandle,BM_CLICK,0,0);

Einfacher gehts nich, hab für nen tastaturlosen Win95 LAN Client nen kleines NETLOGON Tool geschrieben. Mittels Copy´n´Paste trägt das bei Benutzername / Passwort im Netzwerk-Logon Fenster von Win95 die Benutzerdaten ein und löst anschließend den OK Button aus.

Für z.B. ComboBox Steuerelemente gäbe es auch wunderbare Steuercodes wie z.B. CBN_DROPDOWN um eine ComboBox auszufahren. Der ganze Mist ist im Win32 SDK beschrieben und zwar in den Steuerelement Referenzen. Jedes Standardsteuerelement hat dort seine eigene Referenz u.a. mit elementspezifischen Botschaften aufgeführt. :P

Mimo
03.03.2002, 14:20
sicher gibt´s die wunderbarsten steuercodes für die ganzen controls.

Aber, wenn Du eine Remotesoft für nen Client schreiben willst, dann hat man ja nie die ganzen Windowhandles der Fenster, die aufm Client sichtbar sind.

Gruss,
Mimo

Felix Kaiser
03.03.2002, 17:22
Daher geh ich in einem solchen Fall immer auf Handle-Suche ;)

Diogenes
03.03.2002, 17:35
Wie sucht man 1 Handle, speziell auf einem entfernten (remote) Rechner?

Felix Kaiser
03.03.2002, 18:16
Das Handle sucht das Programm was den Rechner direkt steuert, bei Remoterechnern das auf dem Remoterechner installierte Steuerungsprogramm.

Geeignet zum Suchen sind:
GetDesktopWindow
GetWindow
FindWindow

Schau dir mal die Beschreibung zu diesen Routinen näher an. Mit GetWindowText kannst du meistens das Hauptfenster, in dem die Elemente, die du ansprechen willst, sind, bestimmen, dem Handle nach.

Wenn man allerdings kein Ansatzhandle hat kann man einfach die Handles durchtesten mit IsWindow in einer Schleife, bei 0 beginnend. Anhand der Tatsache dass Windows95 z.B. nur max. 16384 Handles verwalten kann, kann man sehr gut ein Ende der Schleife bestimmen. Schau dir mal diese Routinen in der SDK etwas näher an.

Mimo
03.03.2002, 19:39
...wobei man dann auch nicht weiss, wenn man alle 16xxx Handles abgegrast hat, um was es sich dabei handelt. Also, nicht die Fensterklasse (auch eine Textbox ist für Windows ein Fenster) - man würde schon rauskriegen, ob´s sich um eine textbox, Combobox oder was weiss ich handeln würde, aber wo diese z.B. Textbox gerade verwendet wird... wie kriegt man das dann raus?

Mimo

Felix Kaiser
03.03.2002, 19:50
GetWindow, damit kann man zu Handles PARENT und CHILD Objekte bestimmen. Zu dem bin ich nie nach Klassen gegangen, sondern hab mit Unterstützung von GetWindowText immer das Hauptfenster, in dem die gebrauchten Elemente zu finden sind, gesucht und bin dann über die CHILD Suche mit GetWindow gegangen ...

Diogenes
06.03.2002, 18:07
Klingt nach einer guten Idee... :]

A propos zum Begriff "Hauptfenster": Das ist ein Fenster, das keinen Parent hat. Es kann daher über den ganzen Bildschirm veschoben werden. Lustigerweise sind auch anwendungsmodale Dialogboxen Hauptfenster in diesem Sinne (jedenfalls bei 3.11). Eine Anwendung kann durchaus mehrere Hauptfenster haben, die dann alle in der Taskleiste auftauchen, sofern sie nicht hidden sind... :rolleyes:

Felix Kaiser
06.03.2002, 19:45
Das oberste Fenster ist immernoch der Desktop, was wir jetzt als Hauptfenster behandeln dürften Childwindows des DeskTop HWND sein. Aber dann passts. Und die Sache mit den vielen Tasks bei Win3.x Anwendungen merke ich selber, wenn ich mal z.B. mit Delphi 1.0 arbeite (schon fast historisches Delphi :D)

Diogenes
07.03.2002, 23:15
Ja, stimmt!

Scheint das Desktop aber auch auf, wenn man nach Hauptfenstern sucht? Wenn ja, bestimmt man mittels des "eigenen" Hauptfensters das Desktop, indem man sich den Parent abruft und kann danach alle Childs des Desktops (folglich alle Hauptfenster) rauslisten.
Ist das Dein Verfahren, Guru?