Entwickler-Ecke
Sonstiges (Delphi) - gucken was die Maus macht
tommie-lie - Fr 01.11.02 17:13
Titel: gucken was die Maus macht
Hallo,
Kennt einer eine Möglichkeit, ruaszukriegen um ie viele Pixel die Maus bewegt wurde, unabhängig davon, ob sie sich bereits am Rand des Fensters befindet, oder nicht?
Wenn man es nämlich mit dem normalen X und Y macht, die es ja bei jedem Mouse-Event gibt, bekomme ich, wenn die Maus am linken Rand ist, immer 0. Ich will aber wissen, um wieviele Pixel die Maus "über den Rand hinweg" bewegt wurde.
Tschüß
Thomas
edit: im nachhinein wäre es sogar besser, rauszukriegen, um wieviele centimeter sich die MAus in welche Richtung bewegt hat, weil ich dann da die Sensitivität selbst einstellen kann.
Ach ja, und ohne DirectInput soll's sein ;-)
Anonymous - Fr 01.11.02 18:27
Versuchs mit GetCursorPos. Hier ein Beispiel
Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| procedure TForm1.Timer1Timer(Sender: TObject); var CursorPos: TPoint; begin Timer1.Interval := 100; GetCursorPos(CursorPos); Caption := IntToStr(CursorPos.X) + ' - ' + IntToStr(CursorPos.Y); end; |
Ab D5 (glaube ich) gibts noch TMouse.
tommie-lie - Fr 01.11.02 19:54
ich weiß, das es sowas gibt. Aber da ist man anstatt seines Fensters auf seinen desktop beschrönkt. Irgendwo gibt's da auch 'ne Null, wenn die Maus ganz Links ist. Ich will, daß man über den gesamten Bildschirm hinweg die Maus bewegen kann. Also nicht, daß sie dann auf der anderen Seite wieder auftaucht, sondern daß ich einfach weiß, an welcher Stelle die Maus wäre, wenn der Bildschirm eine unendliche Fläche wäre und nie aufhört.
Ex0rzist - Sa 02.11.02 02:31
| tommie-lie hat folgendes geschrieben: |
| ... wenn der Bildschirm eine unendliche Fläche wäre und nie aufhört. |
Dazu musst du ja erstmal ein Koordinatensystem festlegen (incl. Ursprung) :wink:
Ich habe bloss nicht ganz verstanden, was du an Popovs Code auszusetzen hast?
Eine Frage noch: Wozu? :?
DaFox - Sa 02.11.02 16:54
Na, dann setz' doch die Maus nach jeder Bewegung in die Mitte von Deiner Form... :lol:
Gruß,
Markus
tommie-lie - Sa 02.11.02 18:02
dann springt die Maus immer :-(
Aber ich könnte die letzte Position speichern (wenn man die Taste zum Zoomen drückt) und die Maus jedesmal wieder an diese Position setzen. Dann hat man die Maus immer da, wo sie vorher auch war.
Gut Idee! Danke!
DaFox - Sa 02.11.02 18:40
Um das Springen zu beseitigen, könntest Du mit einem lokalen Hook arbeiten....
Gruß,
Markus
tommie-lie - Sa 02.11.02 19:10
mit hooks kenne ich mich leider nicht so gut aus. Ich denke, daß die Lösung mit dem speichern der Position und dem nachfolgenden "zurückspringen" die einfachste Lösung ist...
Anonymous - Sa 02.11.02 20:52
Kombinier doch die Form Koordinaten mit den Desktop Koordinaten und schon kannst du alles berchnen was du willst.
tommie-lie - So 03.11.02 13:09
So, das versteh ich jetzt gar nicht merh.
Wie soll ich denn die Form- mit den Desktop-Koordinaten verbinden? Die Form ist doch ein Vollbild, was bringt mir dann eine Verknüpfung von beidem? Sind doch eh die gleichen Werte...
tommie-lie - So 03.11.02 13:54
Ich hab jetzt mal alle Möglichkeiten zum coden ausprobiert.
logisch wäre ja folgendes im MouseMove-Event der Maus:
Quelltext
1: 2: 3:
| if Shift <> [] then Mouse.CursorPos := MousePos; MousePos := Mouse.CursorPos; |
Also zuerst die letzte Position setzen, dann die aktuelle Position in die Variable und beim nächsten mal wieder die Position aus der Variable setzen usw, und zwar nur dann, wenn eine Taste gedrückt ist.
Das Problem ist nur, wenn man das mal ausprobiert, klappt's nicht.
Die Maus bewegt sich gar nicht, bzw die X und Y-Variablen der Funktion sind immer gleich. Weiß da jemand was anderes?
Anonymous - So 03.11.02 15:35
Ich muß erlich sagen, daß ich noch nich ganz verstanden habe was dein Problem ist. Du hast geschrieben, daß du wissen willst um wieviel die Maus über den Rand bewegt wurde. Also hab ich dich auf GetCursorPos hingewiesen. Wenn du GetCursorPos zusammen mit den Werten aus MouseMove oder den Formwerten kombinierst, dann kannst du jede Differenz berechnen die du Brauchst.
Und dann schreibst du
| Zitat: |
| Wie soll ich denn die Form- mit den Desktop-Koordinaten verbinden? Die Form ist doch ein Vollbild, was bringt mir dann eine Verknüpfung von beidem? Sind doch eh die gleichen Werte... |
Jetzt hast du plötzlich ein Vollbild und die Werte sind eh gleich. Wenn es eh Vollbild ist, was willst du dann messen?
Ich würde dir gerne helfen aber ich weiss die Frage nicht.
Damit zumindes du weisst was ich gemeint habe:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| procedure TForm1.Timer1Timer(Sender: TObject); var CursorPos: TPoint; begin Timer1.Interval := 100; GetCursorPos(CursorPos); Caption := 'x= ' + IntToStr(CursorPos.x - Left) + ' / y= ' + IntToStr(CursorPos.y - Top); end; |
Funktioniert nicht bei Vollbild.
Aber Vorsicht! Ist nur ein Teil der den linken und oberen Teil berechnet. Also wenns nicht das ist was du wolltest, dann weiss ich erstmal nicht wie die Frage war.
tommie-lie - So 03.11.02 16:15
ich dachte, das hätte ich weiter oben geschrieben :roll:
Wenn man die Maus über den Rand ddes Desktops hinaus bewegt, dann will ich wissen, um wieviel das wäre. Bzw wenn der Bildschirm eine unendliche Fläche ist, will ich wissen, wo die Maus wäre.
Normale Leute haben eine Auflösung von 1024*786 Pixeln. Man kann also die Maus auf dem Desktop nur um 1024 Pixel in der Horizontalen bewegen. Ich will die Maus aber weiter bewegen, bzw wissen, wo sie wäre. Praktisch wenn die Maus am rechten Rand ist, und noch ein stückchen weiter bewegt wird, will ich 1025, 1026, 1027 und so weiter haben. Nach unten genauso. Ist die Maus ganz unten und wird weiter nach unten bewegt, will ich 787, 788, 789 usw haben. Das gleiche natürlich nach oben und links auch, indem man dann negative Werte hat (-1, -2, -3).
Es gibt zwar Leute mit höheren Auflösungen, wo die Grenze dementsprechend höher ist, aber da will ich auch über diese physikalische Grenze des beschränkten Bildschirmes hinaus die Position der Maus messen. Das der Mauszeiger erstmal am Rand stehenbleibt, ist nebensache. Wichtig ist, daß ich weiß, wo er wäre, wenn....
Jetzt klar? Sonst mach ich auch 'ne Zeichnung...
Anonymous - So 03.11.02 17:21
Jetzt wird es endlich etwas klarer. Versuch mal dieses Beispiel:
Leeres Projekt mit ListBox1 drauf. Dann diese Prozedur:
Quelltext
1: 2: 3: 4: 5:
| procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin ListBox1.Items.Insert(0, IntToStr(X) + ' - ' + IntToStr(Y)); end; |
Du bekommst die x und y Koordinatenwerte der Maus. Wie du sehen wirst sind die Differenzen zu vorherigen Werten nicht 1 sonden auch größer. Deshalb wirst du NICHT die genauen Werte erhalten können. Jedes mal wenn du den Desktop verläß wird dich der Übergang einige Pixel kosten. Du wirst nie sicher sein ob der Wert bis du reagierst bereits -1 oder -5 oder -11 ist.
Noch genauer: Du bekommst vom System die x/y Werte NICHT wenn sie sich um ein Pixel verändert haben, sondern pro Zeit. Wenn du also irgendwann auf IF X = 0 reagierst um z.B. die Position wieder auf die Bildschirm mitte zu setzen, kann X schon längst kleiner als Null sein.
Mit Rechnen kommst du also nicht ans Ziehl. Zumindest wirst du kein genaues Ergebnis bekommen.
Ob man etwas machen kann wenn man an die Hardware geht oder mit den Messages arbeitet, daß weiss ich allerdings nicht.
Delete - So 03.11.02 18:35
Ich bin mal neugierig: Was willst du damit erreichen? Oder anderst: Wozu das ganze?
Was habe ich davon, wen ich weiß, dass mein Mauscursor rein theoretisch in Bagdad steht oder im Nebenzimmer in der Küche auf die Kaffeemaschine zeigt? :roll:
Anonymous - So 03.11.02 19:35
Ich glaube das soll ein über-den-Desktop-hinaus-zeichnen-können können.
Ich bekamm das Interesse es mal selbst zu lösen. Allerdings im Kleinformat. Für dein Problem mußt du es kräftig anpassen, aber das Prinzip steht. Setze in der mitte des Formulars ein Button mit Close Anweisung. Sonst kommst du nicht raus.
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:
| var Form1: TForm1; MX, MY: Integer; DX, DY: Integer;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject); begin MX := ClientWidth div 2; MY := ClientHeight div 2; DX := 0; DY := 0; SetCursorPos(MX + Left, MY + Top); end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var F: Word; begin //Screen.Cursor := crNone; F := 200; if X > (MX + F) then begin DX := DX + (X - MX); SetCursorPos(MX + Left, Y + Top); end; if X < (MX - F) then begin DX := DX - (MX - X); SetCursorPos(MX + Left, Y + Top); end; if Y > (MY + F) then begin DY := DY + (Y - MY); SetCursorPos(X + Left, MY + Top); end; if Y < (MY - F) then begin DY := DY - (MY - Y); SetCursorPos(X + Left, MY + Top); end; //Werte Anzeigen Caption := 'X = ' + IntToStr(DX + X) + ' - ' + 'Y = ' + IntToStr(DY + Y); //Gummiband Anzeigen Canvas.Brush.Color := clBtnFace; Canvas.FillRect(ClientRect); Canvas.MoveTo(MX, MY); Canvas.LineTo(DX + X, DY + Y); end;
procedure TForm1.Button1Click(Sender: TObject); begin Close; end; |
Wie das Gummiband beweist gibt es Verluste beider Methode. Funktioniert nur wenn du die Maus langsam bewegst.
Ganz wichtig: Optimieren mußt du es selbst. Ist eben etwas auf die schnelle geschrieben.
tommie-lie - Mo 04.11.02 19:04
nicht ganz.
es geht darum, etwas zu zoomen. Das Zoomen soll durch Tastendruck+[Maus bewegen] gehen.
Allerdings soll sich, während man die Taste drückt, der Mauszeiger nicht bewegen und trotzdem die richtige Position anzeigen. Wenn man also nach hinten zoomt (wegzoomt), soll die Maus an der gleichen Stelle bleiben, wie sie vorher war, und man soll unendlich weit zoomen können. Also am Rand soll nicht schluß sein, weil sich der Mauszeiger ja auch nciht bewegen soll.
Jetzt noch klarer? Oder hab ich wieder alle Ideen über den Haufen geschmissen?
Popovs Beispiel verfolgt daher das falsche Ziel, ist aber doch irgendwo richtig. Wie kriege ich es denn hin, daß der Mauszeiger nie bewegt wird? Auch nicht ein bisschen "flimmert", wenn man die Maus schnell bewegt? Dabei soll aber trotzdem noch die theoretische Position angezeigt werden, wie's bei Popovs Beispiel der Fall war.
Anonymous - Mo 04.11.02 21:54
| tommie-lie hat folgendes geschrieben: |
| Wie kriege ich es denn hin, daß der Mauszeiger nie bewegt wird? |
Du kommst immer mit neuen Infos.
Das ich nicht den fertigen Code schreibe war doch klar. Ich hab nur eine Idee geliefert. Wenn du dir das genau angesehen hast, dann hast du bemerkt, daß ich am Anfang eine Zeile auskommentiert habe die die Maus unsichtbar macht. Mit ein wenig Code kannst du die Maus verschwinden lassen wenn sie über den Desktop ist und wieder sichtbar machen wenn sie immerhalb des Desktops ist.
Da ich befürchte, daß nach dem nächsten Tipp die Maus dabei Kasatschok tanzen muß, lass ich alles weitere.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 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!