Markierungen in Bitmap zeichnen
-
ClientToScreen() und ScreenToClient() sind doch aber für die Umrechnung von Window-Koordinaten in Desktop-Koordinaten, oder? Habs natürlich trotzdem mal getestet, klappt damit nicht. Oder habe ich da was vergessen?
Gruß
-
Eigentlich so:
this->m_statFRM.GetClientRect(&lRect); this->m_statFRM.ClientToScreen( &lRect ); this->ScreenToClient( &lRect );
-
Danke, habe es jetzt so hinbekommen:
void CFotovermessungDlg::OnLButtonDown(UINT nFlags, CPoint point) { CRect lFRect, lDRect; this->m_statFRM.GetClientRect(&lFRect); this->m_statFRM.GetWindowRect(&lDRect); ClientToScreen(&point); if(point.x >= lDRect.left && point.x <= lDRect.right && point.y >= lDRect.top && point.y <= lDRect.bottom) { point.x = point.x - lDRect.left; point.y = point.y - lDRect.top; } if(this->m_bmpWork == NULL) this->m_bmpWork = new Gdiplus::Bitmap(lFRect.right, lFRect.bottom); Gdiplus::Graphics graphics(this->m_bmpWork); Gdiplus::Pen lpen(Gdiplus::Color::Red, 1.0f); graphics.DrawLine(&lpen, point.x-5, point.y, point.x+5, point.y); graphics.DrawLine(&lpen, point.x, point.y-5, point.x, point.y+5); this->ImgShow(); CDialog::OnLButtonDown(nFlags, point); }In ImgShow() wird dann zuerst das richtige Bild gezeichnet und dann das Bild mit den Linien drübergelegt. Dabei gibt es aber noch das Problem, dass er die Linien jetzt zwar in der Nähe des Mausklicks zeichnet, aber eben leider nicht genau dort, wo ich geklickt habe, aber das kriege ich bestimmt noch hin.

-
Könnte es sein, daß es daran liegt das Du in der DrawLine Funktion an der falschen Stelle 5 dazu addierst?
Außerdem halte ich es für riskant die Basisversion der Funktion mit veränderten Werten aufzurufen.
-
Mittlerweile hat sich der Code noch ganz schön geändert:
void CFotovermessungDlg::OnLButtonDown(UINT nFlags, CPoint point) { CRect lDRect; CPoint lpt = point; this->m_statFRM.GetWindowRect(&lDRect); ClientToScreen(&lpt); if(lpt.x >= lDRect.left && lpt.x <= lDRect.right && lpt.y >= lDRect.top && lpt.y <= lDRect.bottom) { lpt.x = (long) ((lpt.x - lDRect.left - 2 - this->m_ptOrigin.x + 0.5f) / this->m_fScaleFactor); lpt.y = (long) ((lpt.y - lDRect.top - 2 - this->m_ptOrigin.y + 0.5f) / this->m_fScaleFactor); } if(this->m_bmpWork == NULL) this->m_bmpWork = new Gdiplus::Bitmap(this->GetImgWidth(this->m_bmpOrig), this->GetImgHeight(this->m_bmpOrig)); Gdiplus::Graphics graphics(this->m_bmpWork); Gdiplus::Pen lpen(Gdiplus::Color::Red, 1.0f); graphics.DrawLine(&lpen, lpt.x-5, lpt.y, lpt.x+5, lpt.y); graphics.DrawLine(&lpen, lpt.x, lpt.y-5, lpt.x, lpt.y+5); this->ImgShow(); CDialog::OnLButtonDown(nFlags, point); }Ich bin jetzt erstmal davon abgekommen Linien zu zeichnen und zeichne erstmal kleine Kreuze, das lässt sich besser überprüfen. Die werden mit obigem Code sogar dort platziert, wo ich geklickt habe
Aber nur, wenn ich in der ersten IF-Klausel bei lpt.x und lpt.y je 2 Pixel abziehe, warum ich die abziehen muss, erschließt sich mir allerdings nicht so recht...BOOL CFotovermessungDlg::ImgShow() { CRect lrect; this->m_statFRM.GetClientRect(&lrect); CMemDC dc (this->m_statFRM.GetDC(), &lrect); Gdiplus::Graphics graphics(dc.m_hDC); graphics.Clear(Gdiplus::Color::Black); graphics.DrawImage(this->m_bmpOrig, this->m_ptOrigin.x, this->m_ptOrigin.y, this->GetImgWidth(this->m_bmpOrig), this->GetImgHeight(this->m_bmpOrig)); if(this->m_bmpWork != NULL) graphics.DrawImage(this->m_bmpWork, this->m_ptOrigin.x, this->m_ptOrigin.y, this->GetImgWidth(this->m_bmpWork), this->GetImgHeight(this->m_bmpWork)); return 0; }Habe mal 2 Screenshots gemacht, einmal ohne die 2 Pixel abzuziehen und einmal mit: http://img170.imageshack.us/gal.php?g=zwischenablage3.png
geklickt habe ich in beiden Fällen auf die Mitte des großen schwarzen Kreuzes, das sich in der Bitmap befindet und nicht durch das Programm gezeichnet wurde.Gruß
-
ClientRect und WindowRect haben i.d.R. verschiedene Größen. Sieht so aus als hätte m_statFRM einen Rahmen

-
Du hast Recht, die beiden Funktionen liefern (auch nach ScreenToClient) unterschiedliche Werte. hast du vielleicht einen Vorschlag wie ich es besser machen kann, damit ich auf die "- 2" verzichen kann?
Gruß
-
Na mal angenommen du wölltest den point aus OnLButtonDown in ClientKoordinaten von m_statFRM umrechnen:
void CFotovermessungDlg::OnLButtonDown(UINT nFlags, CPoint point) { CPoint ptFRM( point ); ClientToScreen( ptFRM ); m_statFRM.ScreenToClient( ptFRM ); }D.h. einfach wo es geht Clientkoordinaten verwenden und die Screenkoordinaten nur als Bezugssystem nutzen.
-
Vielen Dank, für deine Hilfe! Es funktioniert jetzt ohne 2 abzuziehen

void CFotovermessungDlg::OnLButtonDown(UINT nFlags, CPoint point) { Gdiplus::Pen lpen(Gdiplus::Color::Red, 1.0f); CPoint lpt(point); ClientToScreen(&lpt); CRect lDRect; this->m_statFRM.GetWindowRect(&lDRect); if(lpt.x >= lDRect.left && lpt.x <= lDRect.right && lpt.y >= lDRect.top && lpt.y <= lDRect.bottom) { this->m_statFRM.ScreenToClient(&lpt); lpt.x = (long) ((lpt.x - this->m_ptOrigin.x + 0.5f) / this->m_fScaleFactor); lpt.y = (long) ((lpt.y - this->m_ptOrigin.y + 0.5f) / this->m_fScaleFactor); this->PointSave(&lpt); if(this->m_bmpWork == NULL) this->m_bmpWork = new Gdiplus::Bitmap(this->m_bmpOrig->GetWidth(), this->m_bmpOrig->GetHeight()); Gdiplus::Graphics graphics(this->m_bmpWork); this->PointDrawCross(&graphics, &lpen, &lpt); this->PointDrawLines(); this->ImgShow(); } CDialog::OnLButtonDown(nFlags, point); }
-
Ich würde noch auf GetWindowRect verzichten:
void CFotovermessungDlg::OnLButtonDown(UINT nFlags, CPoint point) { Gdiplus::Pen lpen( Gdiplus::Color::Red, 1.0f ); CPoint lpt( point ); ClientToScreen( lpt ); m_statFRM.ScreenToClient( lpt ) CRect lDRect; m_statFRM.GetClientRect(&lDRect); if( !( lpt.x < 0 || lpt.y < 0 || lpt.x >= lDRect.Width() || lpt.y >= lDRect.Height() ) ) { lpt.x /= m_fScaleFactor; lpt.y /= m_fScaleFactor; PointSave( &lpt ); if( m_bmpWork == NULL) m_bmpWork = new Gdiplus::Bitmap( m_bmpOrig->GetWidth(), m_bmpOrig->GetHeight()); Gdiplus::Graphics graphics( m_bmpWork ); PointDrawCross(&graphics, &lpen, &lpt); PointDrawLines(); ImgShow(); } CDialog::OnLButtonDown(nFlags, point); }