ClipCursor bei Mausbewegung



  • Hi an alle,

    ich zermatere mir schon den ganzen tag das Hirn wie ich es mit ClipCursor in OnMouseMove und allem hinbekomme, das ich bei geklickter linker Maustaste und Mausbewegung den Effekt hinbekomme wie z.B. im Windows Explorer, wenn ich zwischen der Baumansicht(links) und der Liste(rechts) die Größe modifiziere.

    Mein Problem ist, dass der Cursor sich halt an einer Position festfrisst und dann nicht mehr mitbekommt wenn ich wieder in die andere Richtung gehe.

    Hier mal etwas von meinem Code

    if(m_bIsPressed)
    {
    	//Bewegung nach rechts
    	if(point.x > m_noldCursorPos)
    	{
    		if(crSubject.Width() > (m_nDefWidthSubjectView / 2))
    		{
    			nDiff = point.x - crContact.right;
    			crSubject.SetRect(crSubject.left + nDiff, crSubject.top, crSubject.right, crSubject.bottom);
    			m_wndSubjectView.MoveWindow(&crSubject);	
    			crContact.SetRect(crContact.left, crContact.top, crContact.right + nDiff, crContact.bottom);
    			m_wndContactView.MoveWindow(&crContact);
    			ClientToScreen(&crContact);
    			ClientToScreen(&crSubject);
    			crClickArea.left = crContact.right;
    			crClickArea.right = crSubject.left;
    			crClickArea.top = crContact.top;
    			crClickArea.bottom = crContact.bottom;
    			ClientToScreen(&point);
    			ScreenToClient(&point);
    			if(!ClipCursor(&crClickArea))
    			   dwErr = GetLastError();
    			ScreenToClient(&crContact);
    			ScreenToClient(&crSubject);
    		}
    	}
    	//Bewegung nach Links
    	else if(point.x < m_noldCursorPos - 1)
    	{
    		if(crContact.Width() > (m_nDefWidthContactView / 2))
    		{
    			nDiff = point.x - crSubject.left;
    			crSubject.SetRect(crSubject.left + nDiff, crSubject.top, crSubject.right, crSubject.bottom);
    			m_wndSubjectView.MoveWindow(&crSubject);
    			crContact.SetRect(crContact.left, crContact.top, crContact.right + nDiff, crContact.bottom);
    			m_wndContactView.MoveWindow(&crContact);
    			ClientToScreen(&crContact);
    			ClientToScreen(&crSubject);
    			crClickArea.left = crContact.right;
    			crClickArea.right = crSubject.left;
    			crClickArea.top = crContact.top;
    			crClickArea.bottom = crContact.bottom;
    			if(!ClipCursor(&crClickArea))
    			   dwErr = GetLastError();
    			ScreenToClient(&crContact);
    			ScreenToClient(&crSubject);
    		}
    	}
    }
    

    Ich weiß so wie ich es dort mache ist es sicherlich falsch.

    In google kann ich leider nichts genaues finden.

    Gruß


  • Mod

    mr. main schrieb:

    ich zermatere mir schon den ganzen tag das Hirn wie ich es mit ClipCursor in OnMouseMove und allem hinbekomme, das ich bei geklickter linker Maustaste und Mausbewegung den Effekt hinbekomme wie z.B. im Windows Explorer, wenn ich zwischen der Baumansicht(links) und der Liste(rechts) die Größe modifiziere.

    Und was ist da Dein Problem. Der Explorer clipped den Cursor nicht!
    Wenn mit der Maus auf den Splitter geklickt wird, wird en Maus Capture gesetz (SetCapture), ab dann (so lange die Maustaste unten ist) werden alle Mausnachrichten an das Fenster (Splitter) gesendet. ClipCursor wird nicht verwendet.



  • Also zuerst ich benutze kein CSplitterWnd.
    Ich nutze beim Mausklick schon SetCapture,
    wenn ich dann aber ohne ClipCursor arbeite
    wandert der Cursor zu weit und verliert den
    Bereich innerhalb dessen er angeklickt wird.

    Der Aufbau ist so, dass eine von CWnd abgeleitete
    Klasse den Bereich bildet in welchen die Steuerelement
    eingebracht sind.

    Beim Klicken mit der Maus prüfe ich halt, ob die
    Position zwischen meinen 2 Steuerelementen liegt.
    Sollte dem so sein, dann prüfe ich die Richtung in
    welche die Maus bewegt wird und verändere dementsprechend
    die Größe beider Steuerelemente.



  • Es geht viel einfacher, wenn Du nur die Größe (oder die Lage) der Steuerelemente begrenzt.
    Lasse den Mauscursor einfach dahin bewegen wie der User ihn mit der Maus bewegt.

    Zum Vergleich: Alle Scrollbalken des Fensters (auch die im Windows Explorer!) verhalten sich so, nämlich die Lage der Scrollbalken wird begrenzt, aber der Mauscursor selbst befindet sich bereits über die Fenstergrenzen hinweg weit außerhalb...

    Weitere Beispiele:
    Word 2003 und Excel 2003: Beim Verschieben der Tabulatoren (jeweils oberhalb des Arbeitsblatts) wird der Mauscursor nicht geclippt.
    Total Commander, auch dort wird beim Splitter der Mauscursor nicht geclippt.

    Ich meine nur, damit kann man auch gut leben (ich betrachte das Clippen beim Explorer-Splitter als Ausnahme, ehrlich gesagt das war mir in meinen ganzen Jahren Windows-Nutzung überhaupt nicht aufgefallen)

    Martin



  • Qualm 😃
    Nu bin ich etwas überfragt.
    Wie meinst du das mit dem begrenzen der LAge(Größe) der Steuerelemente?
    Das ganze soll ja dynamisch bleiben wenn ich z.B. die Größe des Hauptfensters
    ändere sollen die Steuerelemente dementspechend auch größer bzw. kleiner werden.
    Stört ein Begrenzung dabei nicht eher?

    Und wie schaffe ich wie schaffe ich es dass der Mauscursor praktisch nicht vergisst das er im Moment der Bewegung bei geklickter Maustaste nicht vergisst, das er noch mit dem Bereich verbunden ist der praktisch die Splitting Area darstellt? Derzeit habe ich ja noch das Problem dass dies trotz SetCapture passiert. Wenn er zu weit von dem Splitting Bereich weggezogen wurde dann verliert er irgendwie diese Information.



  • Du meinst doch in etwa so wie resizeable Dialogboxen? z.B.:
    "CResizableDialog" http://www.codeproject.com/KB/dialog/resizabledialog.aspx
    Dort ist auch eine lauffähige Demoversion.
    [EDIT]: Es spielt hier keine Rolle, was für ein Steuerelement (Splitter, Button, Fenster, Dialog, ... ) in der Größe oder in der Lage verändert wird. Es geht ja nur um das Clippen oder nicht Clippen des Mauscursors.

    mr. main schrieb:

    Wenn er zu weit von dem Splitting Bereich weggezogen wurde dann verliert er irgendwie diese Information.

    Das kann nicht sein, da machst Du was falsch.
    Solange Du den Mauscursor mit SetCapture() übernommen hast, gehen keine Informationen verloren.

    Folgende Tipps könnten Dir dabei weiterhelfen:
    -SetCapture() captures mouse input either when the mouse is over the capturing window, or when the mouse button was pressed while the mouse was over the capturing window and the button is still down. Only the foreground window and only one window at a time can capture the mouse.
    -Cursor-Koordinaten können auch negative Werte annehmen!
    -Unbedingt WM_CAPTURECHANGED auswerten. Wenn Du z.B. während aktivem SetCapture() den Alt+Tab (Task-Switch) betätigst, hat Dein Fenster den mouse capture verloren! Oder ganz allgemein, ein anderes Fenster wird in den Vordergrund gebracht... usw.

    Martin



  • Das mit dem Resizen klappt ja gut bei mir. Da hab ich keinen Stress mit.
    Nein ich möchte sowas wie einen Splitter. Also ich habe auf einem ParentCtrl 2 Steuerelemente und der Bereich zw. den Elementen soll nun vertikal verschoben werden können halt wie oben beschrieben beim Windows Explorer zwischen den Ansichten der Ordner und der Ansicht der Inhalte des Ordners.


  • Mod

    Aber auch beim Windows Explorer kannst Du den Cursor über den Ranbd weiter ziehen. Da wird kein Clipping gemacht.

    Was ist denn nun Dein Problem? Wenn Du SetCapture korrekt verwendest verlierst Du keine Mausnachrichten... und Clipping ist unnötig und eher irritierend.



  • Oh man oh man oh man....

    Ich könnte mich treten. Das Probelm mit SetCapture lag einzig daran, das ich das Abfragen der Bewegung des Mauszeigers und damit auch das Anpassen der Steuerelemente innerhalb der Abfrage ob die Mausposition sich im Splitting Bereich befindet. Mach ich beides für sich alleine funzt das auch mit SetCapture und ohne ClipCursor.

    Jetzt ist es nur noch das wenn ich die Maus anhalte der Mauscursor auf die Anfangspositon zurück springen soll zumindest im x - Bereich. Kann ich da einfach SetCursorPos einsetzen?


Anmelden zum Antworten