Maus als Zeichenstift nutzen?

Ravebaby

Erfahrenes Mitglied
Ich möchte, das meine Maus als Zeichenstift agiert. Sobald die linke Maustaste gedrückt ist soll an der Stelle ein Strich gezeichnet werden...
Nun habe ich mich schon durch zig "Meldungen" und viele "CDC Members" gekämpft, aber das Ergebnis was immer niederschmetternd...
Ich habe der Funktion "OnLButtonDown" beispielsweise "TextOut" zugeordnet. Diese soll einen Punkt als String ausgeben. Aber der Punkt wird nur genau an der Stelle gezeichnet, wo die Maus zum ersten Mal gedrückt wird, nicht überall, solange die Maus gedrückt ist.
Dann hab ich versucht, das mit dem Klick wegzulassen und wollte einfach immer einen Stift haben, wann immer ich die Maus bewege. Also hab ich der "OnMouseMove" eine "TextOut" mit nem Punkt zugeorndet. Aber die Ausgabe des Punktes erfolgt zu selten, so dass ich nur einige vertreute Punkte als Ergebnis auf den Schirm bekomme.
Auch hab ich mich mit "OnLButtonDown" und "LineTo" rumgeärgert. Aber bei "LineTo" kann man ja immer nur die Zielposition des Striches angeben. Ich würde ja aber in dem Fall die letzte Mausposition als Startposition und die jetztige Mausposition als Ziel benötigen.
Das man mit "point.x, point.y" seine eigene Mausposition als Ziel angeben kann, hab ich schon herausgefunden und verwendet. Aber wie setze ich nun die andere Position.

Oder ist das ganze hier beschriebene die falsche Herangehensweise um eine Maus als Zeichenstift zu nutzen?!
 
Ich denke, so dürfte es gehen:
- In 'OnLButtonDown' machst Du ein 'pDC->MoveTo(...)' auf den übergebenen 'point'. Damit wird der 'Zeichencursor' auf diesen Punkt gesetzt.
- In 'OnMouseMove' prüfst Du, ob der linke Mousebutton gedrückt ist:
Code:
if((nFlags & MK_LBUTTON) != 0){...}
- Wenn ja, dann machst Du ein 'pDC->LineTo(...)' auf den übergebenen 'point'. Damit wird eine gerade Linie vom 'Zeichencursor' zum angegebenen Punkt gezeichnet und der 'Zeichencursor' auf den Endpunkt der Linie gesetzt

Grüße,
jokey2
 
Habe es nun so gemacht, wie ich dich verstanden habe:

void CChildView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Fügen Sie hier Ihren Meldungsbehandlungscode ein, und/oder benutzen Sie den Standard.
CClientDC dc (this);
dc.MoveTo(point);

CWnd::OnLButtonDown(nFlags, point);
}

void CChildView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Fügen Sie hier Ihren Meldungsbehandlungscode ein, und/oder benutzen Sie den Standard.
CClientDC dc (this);
if((nFlags & MK_LBUTTON) != 0){
dc.LineTo(point);
}

CWnd::OnMouseMove(nFlags, point);
}

allerdings zeichnet er nun immer Linien von der Position x=0 und y=0, also oberes linkes Eck zu der aktuellen Mausposition. Also nicht wie gewünscht, von der letzten zu der aktuellen Mausposition.
:confused:
 
Es csheint so,m als ob Du immer einen neu erzeugten DC bekommst oder der DC wird zwischendurch zurückgesetzt. Wieso allerdings kann ich Dir jetzt aus dem Stegreif nicht sagen. Ich wede später mal nachschauen, ob ich da was finde, im Mom. habe ich keine Zeit. Vielleicht findest Du es ja inzwischen selber, dann sag' bitte Bescheid.
Als Workaround kannst Du dir natürlich den Punkt in OnLbuttonDown merken und dann in OnMouseMove:
Code:
pDC->MoveTo(m_gemerkterPunkt);
 pDC->LineTo(point);
 m_gemerkterPunkt = point;
Grüße,
jokey2
 
Aber ich erzeuge doch auch in jeder Funktion ein neues dc Objekt, oder?!
Nun sieht mein Code mit der Hilfsvariablen so aus:

Code:
void CChildView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: Fügen Sie hier Ihren Meldungsbehandlungscode ein, und/oder benutzen Sie den Standard.
	CClientDC dc (this);
	m_gemerkterPunkt = point;

	CWnd::OnLButtonDown(nFlags, point);
}

void CChildView::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: Fügen Sie hier Ihren Meldungsbehandlungscode ein, und/oder benutzen Sie den Standard.
	CClientDC dc (this);
	if((nFlags & MK_LBUTTON) != 0){
		dc.MoveTo(m_gemerkterPunkt);
		dc.LineTo(point);
	}

	CWnd::OnMouseMove(nFlags, point);
}


Nun nimmt er immer den Punkt, bei dem ich die Maustaste drücke als Startwert und wenn ich die Maus gedrückt halte, zeichnet er Striche um den Punkt....
 
Setze nach dem LineTo m_gemerkterPunkt auf point, dann geht die nächste Linie von dem Punkt aus weiter.

zusätzliche Erklärung:
Das CDC-Objekt erzeugst du immer neu, ja, aber das kapselt auch nur einen HDC. Und HDCs gibt es nicht allzuviele, und Windows benutzt den auch für die Standard-Darstellungen wie den Fensterrahmen zum Beispiel. Deshalb kannst du dich da eigentlich NIE drauf verlassen, dass ein HDC irgendwo noch die Einstellungen hat, die du an einer anderen Stelle mal reingepackt hast.
 
Alles klar, vielen Dank, nun tut es :)
Allerdings kommt nun folgender Fehler beim Debuggen, keine Ahnung warum: "Unbehandelte Ausnahme bei 0x77f6f570 in Linie_zeichnen.exe: Benutzerhaltepunkt."
Woran kann das liegen?!

Mein Code:
Code:
void CChildView::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: Fügen Sie hier Ihren Meldungsbehandlungscode ein, und/oder benutzen Sie den Standard.
	CClientDC dc (this);
	if((nFlags & MK_LBUTTON) != 0){
		dc.MoveTo(m_ptPrev);
		dc.LineTo(point);
		m_ptPrev = point;
	}
	CWnd::OnMouseMove(nFlags, point);
}

Was bedeutet denn dieses "nFlags"?
 
Was Deine Ausnahme betrifft, kann ich Dir leider nicht helfen. Wenn Du auf Abbrechen klickst, sollte der Debugger in die Zeile im Code springen, wo der Fehler wirksam wurde. Unter Ansicht->Debug-Fenster->Aufrufliste findest Du ein Fensterchen, in dem Du zurückverfolgen kannst, woher die vom Debugger angezeigte Funktion aufgerufen wird. So kannst Du Dich an die fehlerhafte Stelle heranarbeiten.
Das nFlags in OnMouseMove(...) zeigt an, welche Maustaste gedrückt ist. Das steht alles genauer erklärt im MSDN.

jokey2
 
Zurück