CRect / GetClientRect()

TheShihan

Mitglied
Hallo,

Ich schreibe eine MFC Anwendung, welche unter anderem je nach Auswahl einer bestimmten Position einer ListControl auf der rechten Seite des Programmes ein anderes Bild zeigt (anzeige via GDI+, da TIFF Bilder).

Im Hauptfenster/Dialog habe ich also auf der rechten Seite eine Picture Control hingepflanzt. Diese dient eigenltich nur dazu ein schönes Rämchen um das Bild zu zeichnen.

Im Moment besteht das Problem, dass das zeichnen der Bilder, den Rahmen überklatscht, der Rahmen müsste dann immer mit m_pictureControl.invalidate() neu gezeichnet werden.

Zum besseren Verständnis hier mal die DrawPicture Methode:

Code:
void XY::DrawPicture()
{
	///////////////////////////////////////////////
	// show image in picture control IDC_PICTURE
	CClientDC dc(&m_pictureControl);
	Graphics graphics(dc);

	CRect rc;
	rc = m_pictureControl.GetClientRect();
	
	// Coordinates of the top left corner (in drawing area)
	int x = 0,
		y = 0;

	int size_x = rc.Width();
	int size_y = rc.Height();
		
	// Display it
	graphics.DrawImage(m_image, x, y, size_x, size_y);

	// we need to enable the image manipulation controls
	enableImageManipulation(true);

}

Da ich diesen Teil (rc = m_pictureControl.GetClientRect();) im Programm an verschiedenen Orten brauche, bin ich eine neue Methode am schreiben der dies auslagert:

Code:
CRect XY::GetImageArea(CWnd * windowElement)
{
	CRect rc;
	windowElement->GetClientRect(&rc);

	CClientDC dc(&m_pictureControl);

	CPoint dcPoint = dc.re;

	// fix the rectangle
	CPoint topLeft = rc.TopLeft();
	CPoint bottomRight = rc.BottomRight();

	CPoint newTopLeft, newBottomRight;

	newTopLeft.x = topLeft.x + 2;
	newTopLeft.y = topLeft.y + 2;
	newBottomRight.x = bottomRight.x - 2;
 	newBottomRight.y = bottomRight.y - 2;

	CRect fixedRect(newTopLeft.x, newTopLeft.y, newBottomRight.x, newBottomRight.y);

	return fixedRect;
}

Ziel der Methode ist es, dass sie mir eine Rectangle zurückgibt, in dem schlussendlich der Zeichenbereich für das Bild liegt/liegen kann. Merkwürdigerweise gibt es mir folgende Koordinaten zurück, wenn ich als Parameter die Picture Control (m_pictureControl) übermittle:
TOP: 2 Left: 2 Bottom: 540 ...

Beim überprüfen mit dem Debugen sehe ich auch in der m_pictureControl selber, dass sie eben die Koordinaten TOP: 0 Left: 0 etc hat (halt noch ohne die Verschiebungen). Wie kann das sein? Wo sie doch nicht am oberen Linken Rand platziert ist?

Versteht mich nicht falsch, das Bild wird schon richtig gezeichnet, da das GDI+ über den dc die Bild-Platzierung holt. Jedoch möchte ich z.B. eine Panning-Funktion einbauen, die so nicht funktioniert, da das Rectangle der Picture Controle nicht über dem gezeichneten Bild liegt (sondern eben ganz links, ganz oben).

Jemand ne Idee warum das so ist, und wie ich an die korrekten Koordinaten rankomme?

Danke und Gruss, Shihan
 
Hallo,

"GetClientRect()" gibt immer nur die Koordinaten, bezogen auf das Control selbst, zurück. Der top- und left-Wert ist daher in jedem Fall immer gleich Null.
Du musst stattdessen "GetWindowRect()" aufrufen und mit der Methode "ScreenToClient()" des Containers (dein Hauptdialog) die Werte umrechnen.

Gruß
MCoder
 
hehe danke,

ca. 5 Minuten nachdem ich das oben geschrieben habe, bin ich auch auf die Methode "GetWindowRect" gestossen. Wohlgemerkt: habe vorher ca. 2 Stunden schon gesucht und rumgebastelt :)

Das mit dem ScreenToClient muss ich jetzt noch ausprobieren, Dankeschön!
 
Ok, das funktioniert nun. Danke nochmals. Noch ne weitere Frage die in etwa die gleiche Richtung geht.

Ich hole mir ja mit folgendem Code, den Bereich in dem ich später das Bild zeichne:
Code:
	CClientDC dc(&m_pictureControl);
	Graphics graphics(dc);

Nun ist dies aber wieder der ganze Bereich, also auch mit dem Rahmen der "Picture Control". Folglich klatscht es mir das Bild auch über den Rahmen. Wenn das Bild normal angezeigt wird, ist es kein Problem, ich kann mit der DrawImage Methode ja die X,Y start Koordinaten verschieben und das Bild auch etwas verkleinern, damit es reinpasst.

Jedoch habe ich eine Zoom Position, bei der der Bildanfang sowieso hinter dem sichtbaren Bereich ist. Kennt ihr eine Möglich das GDI+ Object graphics (das ja ein Object der Graphics Klasse ist) zu verkleinern, quasi sowas wie shrinken um je 2 Pixel pro Seite. Dann würde das Bild ja wieder reinpassen. Das mit dem ScaleTransform ist es ja nicht, oder irre ich mich da?

Gruss, Shi
 
Jedoch habe ich eine Zoom Position, bei der der Bildanfang sowieso hinter dem sichtbaren Bereich ist. Kennt ihr eine Möglich das GDI+ Object graphics (das ja ein Object der Graphics Klasse ist) zu verkleinern, quasi sowas wie shrinken um je 2 Pixel pro Seite. Dann würde das Bild ja wieder reinpassen. Das mit dem ScaleTransform ist es ja nicht, oder irre ich mich da?
So richtig kapiert habe ich nicht, was du meinst. Warum nutzt du hier nicht auch die DrawImage-Methode, um das Bild entsprechend zu verkleinern? Mit ScaleTransform kannst du natürlich auch positionieren bzw. skalieren.

Gruß
MCoder
 
Es geht mir nicht darum das Bild zu verkleinern, sondern die Fläche in der das Bild gezeichnet wird. Sonst überklatscht es mir eben den Rand des Controls.

Habe mal mit Graphics.getclip probiert. Quasi ein etwas kleiners Rect gemacht, dass ich dann via SetClip von dem Graphics Object entferne, hat mir aber immer was komisches rausgeworfen... naja im Moment ist das Problem eh auf eis. Wende mich anderen Problemen zu :)
 
Zurück