Entwickler-Ecke
Windows API - mausklick simulieren
BigBen4ever - Di 01.03.05 12:46
Titel: mausklick simulieren
Hi
wenn man ein bisschen bei google sucht , stößt man immer wieder auf:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| SetCursorPos(x, y);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0); mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0); |
...dieser code funktioniert aber bei dieser speziellen anwendung bei mir nicht (ich habe ihn auch schon erfolgreich, bei anderen programm verwendet, aber dieses mal funzt er nicht)
kennt jemand eine andere möglichkeit einen mausklick an gewünschter position zu simulieren?
Moderiert von
raziel: Delphi-Tags hinzugefügt.Moderiert von
Tino: Topic aus Sonstiges verschoben am Mi 02.03.2005 um 17:39
retnyg - Di 01.03.05 13:03
falls du einen button klicken willst kannst du per findwindow das handle deines fensters suchen und dann an das handle des button ein sendmessage(handle, BM_CLICK, 0,0) schicken
BigBen4ever - Di 01.03.05 13:07
nein ich brauch nen mausklick
das handle auf das fenster hab ich mit so einer sendkey unit gelöst das beinhaltet das auch
retnyg - Di 01.03.05 13:17
gibt dafür mehrere möglichkeiten
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87:
| Procedure PostKeyEx32(key: Word; Const shift: TShiftState; specialkey: Boolean);
Type TShiftKeyInfo = Record shift: Byte; vkey : Byte; End; byteset = Set of 0..7; Const shiftkeys: Array [1..3] of TShiftKeyInfo = ((shift: Ord(ssCtrl); vkey: VK_CONTROL), (shift: Ord(ssShift); vkey: VK_SHIFT) , (shift: Ord(ssAlt); vkey: VK_MENU)); Var flag: DWORD; bShift: ByteSet absolute shift; i: Integer; Begin For i := 1 To 3 Do Begin If shiftkeys[i].shift In bShift Then keybd_event( shiftkeys[i].vkey, MapVirtualKey(shiftkeys[i].vkey, 0), 0, 0); End; if specialkey Then flag := KEYEVENTF_EXTENDEDKEY Else flag := 0;
keybd_event( key, MapvirtualKey( key, 0 ), flag, 0 );
flag := flag or KEYEVENTF_KEYUP; keybd_event( key, MapvirtualKey( key, 0 ), flag, 0 );
For i := 3 DownTo 1 Do Begin If shiftkeys[i].shift In bShift Then keybd_event( shiftkeys[i].vkey, MapVirtualKey(shiftkeys[i].vkey, 0), KEYEVENTF_KEYUP, 0); End; End;
function ClickButton(ParentWindow : Hwnd; ButtonCaption : string) : boolean; var SL:TStringList; H:hWnd; begin SL:=TStringList.Create; try SL.AddObject(ButtonCaption, nil); EnumChildWindows(ParentWindow, @EnumChildProc, LongInt(SL)); H:=0; case SL.Count of 1: ShowMessage('Window text not found.'); 2: H := hWnd(SL.Objects[1]); else ShowMessage('Ambiguous text detected.'); end; finally SL.Free; end; Result := H <> 0; if Result then PostMessage(H, BM_CLICK, 0, 0); end;
PostMessage(GetDlgItem(wnd,ID_OK),BM_CLICK,0,0); ClickButton(wnd, '&OK'); PostKeyEx32(VK_SPACE,[],FALSE) |
code stammt aus soulseekwatch, gibts auf meiner hp
BigBen4ever - Di 01.03.05 13:32
bin nen anfänger
wie is jez einfach konkret der code um den klick zu simulieren?
oder haste dich wieder auf was anderes bezogen?
retnyg - Di 01.03.05 13:34
welchen button willst du denn anklicken ? (caption)
BigBen4ever - Di 01.03.05 15:00
nen button außerhalb meiner delphi form ..daher geht das so vermutlich nicht oder?
retnyg - Di 01.03.05 15:06
doch genau so geht das - wenn du mal die caption deines buttons verraten würdest könnte ich dir auch was genaueres posten
toms - Di 01.03.05 15:24
BigBen4ever hat folgendes geschrieben: |
nen button außerhalb meiner delphi form ..daher geht das so vermutlich nicht oder? |
Wenn der Button ein Handle besitzt, geht's auch einfacher.
BigBen4ever - Di 01.03.05 17:28
hm mit caption meinst du doch den namen des "buttons" (es ist eher eine "schaltfläche" ) oder?
sie heißt Online
retnyg - Di 01.03.05 19:20
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44:
| function EnumChildProc(Wnd : hWnd; SL : TStrings) : Boolean; StdCall; var szFull : Array[0..MAX_PATH] of char; begin Result:=Wnd<>0; if Result then begin GetWindowText(Wnd, szFull, SizeOf(szFull)); if (pos(SL[0],StrPas(szFull))>0) and (SL.IndexOfObject(TOBject(Wnd))< 0) then SL.AddObject(StrPas(szFull),TObject(Wnd)); EnumChildWindows(Wnd,@EnumChildProc, LongInt(SL)); end; end;
function ClickButton(ParentWindow : Hwnd; ButtonCaption : string) : boolean; var SL:TStringList; H:hWnd; begin SL:=TStringList.Create; try SL.AddObject(ButtonCaption, nil); EnumChildWindows(ParentWindow, @EnumChildProc, LongInt(SL)); H:=0; case SL.Count of 1: ShowMessage('Window text not found.'); 2: H := hWnd(SL.Objects[1]); else ShowMessage('Ambiguous text detected.'); end; finally SL.Free; end; Result := H <> 0; if Result then PostMessage(H, BM_CLICK, 0, 0); end;
procedure TForm1.Button2Click(Sender: TObject); var hnd: hwnd; begin hnd := findwindow(nil,'Mozilla Firefox'); clickbutton(hnd,'Online'); end; |
statt mozilla firefox schreibst noch den titel deiner anwendung rein
dann müsste es eigentlich gehen
ansonsten statt 'Online' vielleicht '&Online' probieren
BigBen4ever - Di 01.03.05 21:11
windows text not found
sagt er
hab alles durchprobiert handle sogar nochmal extra vorher auf das fenster gegeben , geht trotzdem nicht ..sogar die cursor position an die stelle gesetzt
und nun?
retnyg - Di 01.03.05 21:47
breakpoint setzen auf zeile 8
immer schauen was bei szfull drinsteht solange bis irgendwas ähnliches wie Online drinsteht. (also immer wieder F9 drücken bis das passt)
wenn du den richtigen string hast bei dem clickbutton aufruf anpassen
schau auch mal bei findwindow: da muss der titel des fensters mit dem button drinstehen und nicht der titel der anwendung!
toms - Di 01.03.05 21:55
Um welche Anwendung handelt es sich denn?
BigBen4ever - Di 01.03.05 23:28
Zitat: |
breakpoint setzen auf zeile 8
immer schauen was bei szfull drinsteht solange bis irgendwas ähnliches wie Online drinsteht. (also immer wieder F9 drücken bis das passt)
wenn du den richtigen string hast bei dem clickbutton aufruf anpassen |
Sorry aber nochmal für anfänger ..
ist ein breakpoint ein "neuer haltepunkt" ? (roter punkt vor der zeile?)
das hab ich gemacht, aber ich weiß jez nicht wie ich gucke was bei szfull drinsteht
mit der maus rübergehen da wird nix angezeigt, am besten poste ich mal meinen quelltext...also ich hab das mitm button clicken in ne zeitroutine eingebaut nicht wundern..
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107:
| var Form1: TForm1; timer:integer;
implementation
uses SendKeys;
{$R *.DFM}
function EnumChildProc(Wnd : hWnd; SL : TStrings) : Boolean; StdCall; var szFull : Array[0..MAX_PATH] of char; begin Result:=Wnd<>0; if Result then begin GetWindowText(Wnd, szFull, SizeOf(szFull)); if (pos(SL[0],StrPas(szFull))>0) and (SL.IndexOfObject(TOBject(Wnd))< 0) then SL.AddObject(StrPas(szFull),TObject(Wnd)); EnumChildWindows(Wnd,@EnumChildProc, LongInt(SL)); end; end;
function ClickButton(ParentWindow : Hwnd; ButtonCaption : string) : boolean; var SL:TStringList; H:hWnd; begin SL:=TStringList.Create; try SL.AddObject(ButtonCaption, nil); EnumChildWindows(ParentWindow, @EnumChildProc, LongInt(SL)); H:=0; case SL.Count of 1: ShowMessage('Window text not found.'); 2: H := hWnd(SL.Objects[1]); else ShowMessage('Ambiguous text detected.'); end; finally SL.Free; end; Result := H <> 0; if Result then PostMessage(H, BM_CLICK, 0, 0); end;
procedure TForm1.Button1Click(Sender: TObject); begin timer1.enabled:=true; end;
procedure TForm1.Button2Click(Sender: TObject); begin timer1.enabled:=false; end;
procedure TForm1.FormCreate(Sender: TObject); begin timer:=60; Form1.Brush.Style:=bsClear; Form1.BorderStyle:=bsNone; end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var CursorPos: TPoint; begin GetCursorPos(CursorPos); edit3.text := Format('The cursor is at (%d, %d)', [CursorPos.X, CursorPos.Y]); end;
procedure TForm1.Button3Click(Sender: TObject); begin close; end;
procedure TForm1.Timer1Timer(Sender: TObject); var hnd: hwnd; begin label2.caption:=Inttostr(timer); dec(timer); if timer = 58 then begin sendkeystotitle('Yu-Gi-Oh! ONLINE Ver.050128.01-19-p05022401','j'); sendkeystotitle('Yu-Gi-Oh! ONLINE Ver.050128.01-19-p05022401','s'); end; if timer = 56 then begin SetCursorPos(481, 555); end; if timer = 54 then begin hnd := findwindow(nil,'Yu-Gi-Oh! ONLINE Ver.050128.01-19-p05022401'); clickbutton(hnd,'&ONLINE');
end; end;
end. |
also bei findwindow hab ich das eingetragen, was da steht, wenn man den taskmanager öffnet, das müsste eigentlich der richtige titel sein..
also bitte nochmal um etwas (erklärte) hilfe, vielen dank
retnyg - Di 01.03.05 23:31
ja ein breakpoint ist ein haltepunkt
was in szfull drinsteht siehst du wenn du mit der maus drauffährst
kannst du mal einen screenshot des fensters posten wo der online button drauf ist ?
BigBen4ever - Mi 02.03.05 18:39
naja wenn ich mit der maus drüber fahre, steht da aber nichts drin, woran liegt das, (weil ich mein ereignis in einen timer gebunden hab?)
screenshot
http://home.arcor.de/qbblatt3/yugi_oh.jpg
F34r0fTh3D4rk - Mi 02.03.05 18:46
das ist ja auch keine caption sondern ein image oder d3d oder dx oder gl, kA such dir einfach die koordinaten oder guck im speicher nach
BigBen4ever - Mi 02.03.05 22:21
ich hab die koordinaten und versuche einen klick mit oben genanntem code zu simulieren aber es geht nicht
wieso????
BigBen4ever - Mi 02.03.05 22:33
Ey das ist echt mal ne sehr merkwürdige Sache
Ich habe Folgendes ausprobiert:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33:
| var Form1: TForm1; timer:integer;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject); begin timer1.enabled:=true; end;
procedure TForm1.FormCreate(Sender: TObject); begin timer:=60; end;
procedure TForm1.Timer1Timer(Sender: TObject); begin label1.caption:=inttostr(timer); dec(timer); if timer = 58 then begin mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0); mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0); mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0); mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0); timer:=60; end; end;
end. |
Wirklich ein interessanter Test ...ich starte das Programm ...und führe die Maus auf verschiedene Positionen ...Auf Ordner auf dem Desktop, welche dann bei timer=58 geöffnet werden durch den simulierten Doppelklick, ...es werden auch Anwendungen geöffnet wenn ich die Maus auf dem Programm habe ...Ich halte den Cursor auf das Spiel , das Spiel wird geöffnet ...Sobald das Spiel offen ist und sich der Cursor allerdings auf der Fläche des Spiels befindet , wird KEIN KLICK mehr simuliert ...ich halte den cursor auf den oberen Rand mit _ [] X ...diese Funktionen werden dann wieder ausgeführt, aber solange der Cursor sich auf der Schaltfläche des Spiels befindet, funktioniert kein Klick ...
HMM??
Woran kann das liegen?
Welche anderen Möglichkeiten hab ich?
Wie kann man das evtl. umgehen?
uall@ogc - Mi 02.03.05 22:38
welches spiel? benutzt es directinput (directx)
retnyg - Do 03.03.05 00:00
tjo wie fear of the dark bereits sagte liegt es daran dass es sich um ein directx window handelt.
da wirst du dir schon schwerer tun.
mach am besten einen neuen thread auf mit dem titel: mausklick in directx anwendung simulieren.
und poste da den link auf den screenshot !
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!