Entwickler-Ecke

Multimedia / Grafik - Probleme mit Mausbewegung


Sneap - Di 20.07.10 21:43
Titel: Probleme mit Mausbewegung
Hallo Leute,
wie der Titel schon sagt hab ich ein paar Probleme den Mauszeiger zu bewegen und zwar bewegt sich dieser immer unterschiedlich schnell mal so schnell das man ihn kaum sieht und mal ziemlich langsam.
Hier mal der Code dazu:

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:
  while z < strtoint(edit_anzahl1.Text) do
  begin
    // Maus an Position x,y setzen:
    SetCursorPos(x_start, y_start);
    // Linke Maustaste drücken
    mouse_event(MOUSEEVENTF_LEFTDOWN, 0000);

    while(x_start < x_end)or(y_start < y_end) do
      begin
        if ((GetAsyncKeyState(VK_ESCAPE) and $8001) <> 0then
          begin
            x_start := x_end;
            y_start := y_end;
            z := strtoint(edit_anzahl1.Text);
          end;
        if x_start < x_end then x_start := x_start+1;
        if y_start < y_end then y_start := y_start+1;
        SetCursorPos(x_start, y_start);
        Application.ProcessMessages;
        //sleep(1);
      end;
    //Linke Maustaste loslassen
    mouse_event(MOUSEEVENTF_LEFTUP, 0000);
    z := z+1;
    x_start := x_start1;
    y_start := y_start1;
    Application.ProcessMessages;
    sleep(strtoint(edit_wait.Text));
  end;

Weiß jemand vll wo drann das liegt bzw wie ich es hinbekomme das die Maus immer flüssig bewegt wird?
Danke schon mal für eure Hilfe.

Mfg


Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Mi 21.07.2010 um 02:36


jaenicke - Di 20.07.10 21:46

Hallo und :welcome:

Ich sehe nirgends, dass du eine Zeitangabe nutzt, dementsprechend ist die Bewegung eben nicht von der Zeit sondern von der Ausführungsgeschwindigkeit deines Codes abhängig. :nixweiss:

Wenn du eine bestimmte Geschwindigkeit möchtest, musst du auch die Bewegung von der Zeit abhängig machen. Indem du zum Beispiel die aktuelle Position in Abhängigkeit von der vergangenen Zeit berechnest.


Sneap - Di 20.07.10 22:35

Moderiert von user profile iconNarses: Komplett-Zitat des letzten Beitrags entfernt.

Ich dachte sleep würde dafür reichen.
Wie mach ich das am besten, soll ich mir dann mit TDateTime die Uhrzeit hollen und damit rechnen oder gibts da vll ne einfachere Methode?


jaenicke - Di 20.07.10 22:43

Ich würde eher GetTickCount benutzen, das zählt in Millisekunden. ;-)

Sleep pausiert für eine Zeitspanne von einigen Millisekunden, aber du weißt eben nicht, ob es 15 oder 50 Millisekunden sind, je nach PC und Rechnerauslastung. Weniger als 15-25 Millisekunden ist gar nicht möglich.

Deshalb kannst du dich nicht darauf verlassen, dass eine Pause eine bestimmte Zeit dauert, sondern musst die aktuelle Position in Abhängigkeit von der Zeit berechnen. Dann ruckelt es nur, wenn durch hohe Rechnerauslastung es mal länger bis zum nächsten Positionswechsel dauert, aber die Geschwindigkeit bleibt gleich.

Für die Berechnung der vergangenen Zeit bietet sich wie gesagt GetTickCount an.


Sneap - Di 20.07.10 23:19

Meinst du in ungefär so:

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:
while(x_start < x_end)or(y_start < y_end) do
      begin
        if ((GetAsyncKeyState(VK_ESCAPE) and $8001) <> 0then
          begin
            x_start := x_end;
            y_start := y_end;
            z := strtoint(edit_anzahl1.Text);
          end;
        if x_start < x_end then x_start := x_start+1;
        if y_start < y_end then y_start := y_start+1;
        SetCursorPos(x_start, y_start);
        time_start := GetTickCount;
        time_end := GetTickCount + strtoint(edit_speed.Text);
        while time_start < time_end do
        begin
          time_start := GetTickCount;
        end;
      end;
    //Linke Maustaste loslassen
    mouse_event(MOUSEEVENTF_LEFTUP, 0000);
    z := z+1;
    x_start := x_start1;
    y_start := y_start1;

    Application.ProcessMessages;
    time_start := GetTickCount;
    time_end := GetTickCount + strtoint(edit_wait.Text);
    while time_start < time_end do
    begin
      time_start := GetTickCount;
    end;
  end;
Das läuft so zwar besser aber die Maus ist dafür jetzt verdammt lahm egal wie klein ich den Wert auch mache...


Sneap - Mi 21.07.10 08:24

So Leute hab mir jetzt ne kleine funktion geschrieben die so aussieht:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure pause(zeit:longint);
var zeit1:longint;
begin
  zeit1 := GetTickCount;
  repeat
    application.ProcessMessages;
  until (GetTickCount-zeit1 > zeit);
end;

Das einzigste Problem is das die Maus selbst wenn ich pause(1) mache, immer noch recht lahm ist normal müste sie doch dann flitzen ohne ende aber Sie tuts nicht.Wäre super wenn mir da vll noch jemand sagen könnte wies am besten wäre...


Hobby-Programmierer - Mi 21.07.10 08:44

Moin ...,
mach mal das

Delphi-Quelltext
1:
Application.ProcessMessages                    
raus oder steuere das zumindest gezielt, zb. nur jeder 10. Mausschritt wird Rechenzeit freigegeben.
In der Procedure Pause hat das garnix zu suchen sonst könntest du da gleich mit Zufallszeiten arbeiten.

LG Mario


Nersgatt - Mi 21.07.10 08:56

Ich würde es andersrum angehen. Vergiss die Sache mit der Pause erst mal.
Berechne, um wie viele Pixel sich der Mauszeiger verschoben haben müsste (anhand gewünschter Geschwindigkeit und vergangener Zeit) und verschiebe den Mauszeiger dann um diese Strecke.
Dann kann die Pause so lang oder kurz sein, wie sie will. Der Mauszeiger ist immer gleich schnell. Wenn der PC mit andere Dingen beschäftigt ist, würde der Mauszeiger halt anfangen zu ruckeln/hüpfen, aber die Geschwindigkeit stimmt trotzdem.


Sneap - Mi 21.07.10 09:20

user profile iconHobby-Programmierer hat folgendes geschrieben Zum zitierten Posting springen:
Moin ...,
mach mal das

Delphi-Quelltext
1:
Application.ProcessMessages                    
raus oder steuere das zumindest gezielt, zb. nur jeder 10. Mausschritt wird Rechenzeit freigegeben.
In der Procedure Pause hat das garnix zu suchen sonst könntest du da gleich mit Zufallszeiten arbeiten.

LG Mario

Hab jetzt einfach mal vor dem Aufruf von pause() gestezt.

user profile iconNersgatt hat folgendes geschrieben Zum zitierten Posting springen:
Ich würde es andersrum angehen. Vergiss die Sache mit der Pause erst mal.
Berechne, um wie viele Pixel sich der Mauszeiger verschoben haben müsste (anhand gewünschter Geschwindigkeit und vergangener Zeit) und verschiebe den Mauszeiger dann um diese Strecke.
Dann kann die Pause so lang oder kurz sein, wie sie will. Der Mauszeiger ist immer gleich schnell. Wenn der PC mit andere Dingen beschäftigt ist, würde der Mauszeiger halt anfangen zu ruckeln/hüpfen, aber die Geschwindigkeit stimmt trotzdem.


Du meinst in etwa:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure mouse_move(move_time:longint);
var time:longint;
begin
  time := GetTickCount;
  
  while GetTickCount < (time + move_time) do
  begin 
    if x_start < x_end then x_start := x_start+1;
    if y_start < y_end then y_start := y_start+1
    SetCursorPos(x_start, y_start);
  end;
end;

//...
while(x_start < x_end)or(y_start < y_end) do
begin
  mouse_move(100);
end;

Ich hoffe du meinst das so, habs nicht geteste und hoffe ich hab keinen Denkfehler drin.


Hobby-Programmierer - Mi 21.07.10 09:26

Ich war der Meinung er wollte den Mauszeiger schrittweise bewegen und während des verschiebens zuschauen :lol:
Wie es user profile iconNersgatt beschrieben hat gehts natürlich auch.

Delphi-Quelltext
1:
2:
3:
4:
5:
// nicht getestet
var MyMouse: TPoint;
  MyMouse:= Mouse.CursorPos;
  MyMouse.y:= MyMouse.y + StrToInt(edit_anzahl1.Text);
  SetCursorPos(MyMouse.x, MyMouse.y);

Der TE braucht aber lediglich die Pixel von edit_anzahl1.Text zum aktuellen Mausbreich summieren und vielleicht noch prüfen ob sich der Bereich innerhalb des Bildschrims befindet.


Sneap - Mi 21.07.10 10:00

Habs jetzt so, aber dann verschwindet die Maus immer ins Bodenlose:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure mouse_move(speed:string;y_end:integer);
var MyMouse: TPoint;
begin
  MyMouse:= Mouse.CursorPos;
  MyMouse.y:= MyMouse.y + StrToInt(speed);
  if MyMouse.y < y_end then SetCursorPos(MyMouse.x, MyMouse.y);
end;

//...

while(x_start < x_end)or(y_start < y_end) do
begin
  mouse_move(edit_speed.Text,y_end);
end;

So wie es aussieht stimmt was nicht ganz mit dem Wo sie aufhören soll, nur iwi bin ich gerade n bisel durchen wind um den Fehler zu sehn.


Delete - Mi 21.07.10 20:12

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
...Sleep pausiert für eine Zeitspanne von einigen Millisekunden, aber du weißt eben nicht, ob es 15 oder 50 Millisekunden sind, je nach PC und Rechnerauslastung. Weniger als 15-25 Millisekunden ist gar nicht möglich...

Deshalb kannst du dich nicht darauf verlassen, dass eine Pause eine bestimmte Zeit dauert, sondern musst die aktuelle Position in Abhängigkeit von der Zeit berechnen. Dann ruckelt es nur, wenn durch hohe Rechnerauslastung es mal länger bis zum nächsten Positionswechsel dauert, aber die Geschwindigkeit bleibt gleich.

Für die Berechnung der vergangenen Zeit bietet sich wie gesagt GetTickCount an.


Seit WINDOWS 7 64Bit sollte so etwas niemand mehr schreiben!


Hobby-Programmierer - Mi 21.07.10 20:25

:roll:
Hast du selber begriffen was du da geschrieben hast?
Für was zum Geier gibt es die Konstante Speed und warum ist das ein String?
Du addierst die Y-Koordinate mit Speed und prüfst dann ob das kleiner als y_end ist. Wie berechnest du denn y_end?


Gausi - Do 22.07.10 06:51

user profile iconhathor hat folgendes geschrieben Zum zitierten Posting springen:
Seit WINDOWS 7 64Bit sollte so etwas niemand mehr schreiben!

Und warum nicht? was hat sich denn in Windows 7 in der Richtung getan? Und warum gilt das dann nicht für die 32-Bit-Version?


Sneap - Do 22.07.10 08:31

user profile iconHobby-Programmierer hat folgendes geschrieben Zum zitierten Posting springen:
:roll:
Hast du selber begriffen was du da geschrieben hast?
Für was zum Geier gibt es die Konstante Speed und warum ist das ein String?
Du addierst die Y-Koordinate mit Speed und prüfst dann ob das kleiner als y_end ist. Wie berechnest du denn y_end?


y_end holle ich mir vorher das ist kein Problem.
Speed steht in ner edit.
Aber hab das Problem jetzt anders gelöst, ich brauchte die Maus für das vorhaben nicht bewegen sondern es reicht wenn ich sie von Start xy nach End xy Springen lasse und dann eine Pause einlege.