Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Mausklick simulieren klappt einfach nicht :-( (https://www.delphipraxis.net/169847-mausklick-simulieren-klappt-einfach-nicht.html)

SearchBot 15. Aug 2012 22:03

Mausklick simulieren klappt einfach nicht :-(
 
Hallo,

ich weiß, daß das ganze Forum mit dem Thema voll ist und ich hab auch schon viele Threads gelesen und ausprobiert, angefangen mit sendmessage über mouse_event bis jetzt zuletzt bei SendInput. Ich habe die OH gelesen und auch gegoogelt. Ich weiß von der Cursor- und Mauspositions-Differenz und deren Umrechnung.

Das Zeiger-Positionieren klappt auch. Aber das Klicken ums Verrecken nicht :wall:

Es geht eigentlich nur darum, ein FoxPro-Formular ganz fix mit immer ähnlichen Informationen zu füllen.

Also dachte ich mir, lässte das anklicken, füllst die Buchstaben rein und gut ist.
Keybd_event funktioniert prima und die Felder werden schön gefüllt.

Aber das Anklicken von Buttons funktioniert so absolut überhaupt nicht :(
Wenn die wenigstens ein Handle hätten, dann wär ich schon fertig, aber die Eingabefelder des Foxpro-Forumlars haben keine Handles, und die Buttons auch nicht.

Also positioniere ich den Mauszeiger (setCursorPos) und versuche einen Klick darauf. Aber es geht nicht.

Ich habe eine Testapp mit Delphi gemacht, die ich ansteuere. Tastatur funktioniert, Mausklicks nicht - liegt also nicht am FoxPro-Formular, sondern an meiner Programmierung.

Ich habe auch die Beispiele hier aus dem Forum kopiert - klappen auch nicht! Daher bin ich völlig ratlos.

Dies ist mein Stand der Dinge, es funzt nix (bei mir und meiner Windows Vista-Umgebung):
Code:
procedure MClick1(xpos,ypos:integer);
var Inp:TInput;
begin
  Inp.Itype := INPUT_MOUSE;
   Inp.mi.dwFlags := MOUSEEVENTF_LEFTDOWN or MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE;
   Inp.mi.dx := round(xPos * (65535 / Screen.Width));
   Inp.mi.dy := round(yPos * (65535 / Screen.Height));
   Inp.mi.time := 0;
   Inp.mi.dwExtraInfo := 0;
   SendInput(1, Inp, SizeOf(Inp));

   Inp.Itype := INPUT_MOUSE;
   Inp.mi.dwFlags := MOUSEEVENTF_LEFTUP or MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE;
   Inp.mi.dx := round(xPos * (65535 / Screen.Width));
   Inp.mi.dy := round(yPos * (65535 / Screen.Height));
   Inp.mi.time := 0;
   Inp.mi.dwExtraInfo := 0;
   SendInput(1, Inp, SizeOf(Inp));
end;
Ich mache auch das Zielfenster aktiv.
Code:
 if MessageDlg('Zeige auf das erste Eingabefenster und drücke OK'#13+
    'Aber natürlich nicht mit der Maus!!',
    mtinformation,[mbOK,mbCancel],0)=idOK then
 begin

 GetCursorPos(CursorPos);
 W := WindowFromPoint(CursorPos);

   postmessage(w,wm_setfocus,0,0);
   SetForegroundWindow(w);
   SendMessage(w, WM_CHILDACTIVATE, 0, 0);

...
//x und y werden korrekt aus einem Script ermittelt und übergeben
MKlick1(x,y);
..und da schaltet das andere Fenster auf Aktiv um. Aber die Klicks werden trotzdem nicht ausgelöst.

Ein anderer Versuch, der aber schon etwas verkorkst aussieht durch meine Fehlversuche:
Code:
procedure MClick(c:char; x,y:integer);
var i:byte; m:integer; p:TPoint; w:hwnd;

begin
 GetCursorPos(p);
 if (x<0) then x:=p.X;
 if (y<0) then y:=p.Y;

 m:=0;
{ if cbm.Checked then m:=m or MOUSEEVENTF_MOVE;
 if cb1.Checked then m:=m or MOUSEEVENTF_ABSOLUTE;

 // noch umrechnen
 if not cb2.Checked then begin
  x := 65535 Div Screen.DesktopWidth*x;
  y := 65535 Div Screen.DesktopHeight*y;
 end else begin
  if not cb2b.Checked then SetCursorPos(x,y)
  else begin
   x:=0; y:=0;
  end;
 end;
}
  GetCursorPos(p);
  W := WindowFromPoint(p);
   postmessage(w,wm_setfocus,0,0);
   SetForegroundWindow(w);
   SendMessage(w, WM_CHILDACTIVATE, 0, 0);

  setcursorPos(x,y);
  //x:=0;
  //y:=0;
  x := 65535 Div Screen.DesktopWidth*x;
  y := 65535 Div Screen.DesktopHeight*y;

// von x,y habe ich im Forum gesehen, daß ein paar diese Werte übergeben, andere diese auf Null lassen
// beides hat nichts am Klickverhalten verändert.

  case c of
   'L': mouse_event(MouseEventF_LeftDown or m,x,y,0,0);
   'R': mouse_event(MouseEventF_RightDown or m,x,y,0,0);
   'M': mouse_event(MouseEventF_MiddleDown or m,x,y,0,0);
  end;
   //application.processmessages;
   sleep(500);
  case c of
   'L': mouse_event(MouseEventF_LeftUp or m,x,y,0,0);
   'R': mouse_event(MouseEventF_RightUp or m,x,y,0,0);
   'M': mouse_event(MouseEventF_MiddleUp or m,x,y,0,0);
  end;
 end;
end;
JE mehr es nicht funktioniert und dran rumbastelt, schleichen sich natürlich auch blöde Fehler ein.
Ich finde keine.

Kann mir jemand bitte helfen, Mausklicks auf dem anderen Programm auszulösen?
:pale:

hathor 16. Aug 2012 00:19

AW: Mausklick simulieren klappt einfach nicht :-(
 
Ich habe mal ein kleines Testprogramm gemacht,
das funktioniert so:
Man klickt Button2 an, 3 Sek. später wird Button1 ausgelöst.
(Button1 hat die Dimension 100 x 100)

Delphi-Quellcode:
procedure MoveMouseIntoControl(AWinControl: TControl);
var rtControl: TRect;
begin
  rtControl := AWinControl.BoundsRect;
  MapWindowPoints(AWinControl.Parent.Handle, 0, rtControl, 2);
  SetCursorPos(rtControl.Left + (rtControl.Right - rtControl.Left) div 2,
    rtControl.Top + (rtControl.Bottom - rtControl.Top) div 2);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Close;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Sleep(3000);
MoveMouseIntoControl(Button1);
mouse_event(MOUSEEVENTF_LEFTDOWN, 50, 50, 0, 0);
Sleep(50);
mouse_event(MOUSEEVENTF_LEFTUP, 50, 50, 0, 0);
Application.ProcessMessages;
end;

Luckie 16. Aug 2012 00:51

AW: Mausklick simulieren klappt einfach nicht :-(
 
Also ich würde das nicht mit der Maus machen. Was wenn der Benutzer gerade was damit machen will? Fülle die Felder mit WM_SETTEXT aus und klicke die Schaltfläche mittels BM_CLICK an.

Kleines Beispiel:

Delphi-Quellcode:
procedure TForm1.btn1Click(Sender: TObject);
begin
  ShowMessage(edt1.Text);
end;

procedure TForm1.btn2Click(Sender: TObject);
var
  s: AnsiString;
begin
  s := 'hello world';
  SendMessage(edt1.Handle, WM_SETTEXT, 0, Integer(@s[1]));
  SendMessage(btn1.Handle, BM_CLICK, 0 , 0);
end;

Medium 16. Aug 2012 08:09

AW: Mausklick simulieren klappt einfach nicht :-(
 
Nicht alle Programme nutzen WinControls Luckie ;)

Ich bin mit nicht sicher, ob man Bewegung und Click bei SendInput() in einen Aufruf packen kann. Als ich damit mal rumgespielt habe, hatte ich das getrennt, und das sah ganz gut aus. Wäre nen Versuch wert.

Luckie 16. Aug 2012 09:06

AW: Mausklick simulieren klappt einfach nicht :-(
 
OK, berechtigter Einwand. Wäre das denn bei Foxpro der Fall?

SearchBot 16. Aug 2012 15:56

AW: Mausklick simulieren klappt einfach nicht :-(
 
Hallo,

danke für Eure Aufmerksamkeit.

FoxPro hat scheinbar keine WinControls, weil ich bekomme von dort keine Handles angezeigt.
Daher kann ich die Vorschläge von hathor und Luckie leider nicht anwenden. Hätte ich Handle, wäre ich schon lange fertig.
In meiner Delphi-Testapp habe ich natürlich handles, aber ich muss es ohne machen, weil ich in Foxpro ja keine habe.

Aber ihr habt mir trotzdem ein paar neue Denkansätze gegeben (BM_CLICK, Bewegung und Klick trennen)...

Vielleicht weiß noch jemand was?

Bernhard Geyer 16. Aug 2012 16:03

AW: Mausklick simulieren klappt einfach nicht :-(
 
Zitat:

Zitat von SearchBot (Beitrag 1178406)
Es geht eigentlich nur darum, ein FoxPro-Formular ganz fix mit immer ähnlichen Informationen zu füllen.

Muss es denn eine eigen Delphi-App sein? Würde denn evtl. auch Fertige Lösung mit AutoIt auch gehen?

madtom 16. Aug 2012 16:20

AW: Mausklick simulieren klappt einfach nicht :-(
 
Zitat:

Zitat von SearchBot (Beitrag 1178500)
Daher kann ich die Vorschläge von hathor und Luckie leider nicht anwenden. Hätte ich Handle, wäre ich schon lange fertig.

Hallo, für die letzte Prozedur aus Hathors Vorschlag brauchst Du kein Handle, allerdings die Position des Controls, auf das Du klicken willst. Also wenn Du die Position bestimmen würdest, zur Not über das Handle des Formulars die Form-Position bestimmen und dann +X und +Y Koordinaten ...

siehe auch:
http://delphi.about.com/od/vclusing/a/mouseadvanced.htm

SearchBot 16. Aug 2012 21:49

AW: Mausklick simulieren klappt einfach nicht :-(
 
Oooooooooooooooooooooooooh, ich bin ein Vollpfosten!!!

In einer App mit 'nur Klicken' geht es :hello: - in meiner geht es nicht (jetzt aber endlich schon).

Hier ist der Grund - siehst du ihn auch? :oops:

Auszug, wie ich den Script für die Mausposition zerlege... s='@ML400,200;';
Code:
        case upcase(s[i+1]) of
         'M','V':begin
              t:=copy(s,i+3,pos(';',s)-(i+3)); inc(i,length(t)+4);
              u:=copy(t,1,pos(',',t)-1); delete(t,1,pos(',',t));
              x:=strtoint(u); y:=strtoint(t);
              if upcase(s[i+1])='M' then MClick2(upcase(s[i+2]),x,y)
              else SetCursorPos(x,y);
             end;
Dieser kleine Teufelsbug hat mich jetzt 10 Stunden rumgebastele gekostet :wall:
..und ich hoffe, daß es dann auch in FoxPro so funzt...

himitsu 16. Aug 2012 23:34

AW: Mausklick simulieren klappt einfach nicht :-(
 
Zitat:

Zitat von SearchBot (Beitrag 1178544)
siehst du ihn auch?

nee


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:11 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz