Freigeben über


Geschachtelte Grafikcontainer

Windows GDI+ stellt Container bereit, die Sie verwenden können, um einen Teil des Zustands in einem Grafikobjekt vorübergehend zu ersetzen oder zu erweitern. Sie erstellen einen Container, indem Sie die Graphics::BeginContainer-Methode eines Graphics-Objekts aufrufen. Sie können Graphics::BeginContainer wiederholt aufrufen, um geschachtelte Container zu bilden.

Transformationen in geschachtelten Containern

Im folgenden Beispiel werden ein Graphics-Objekt und ein Container innerhalb dieses Graphics-Objekts erstellt. Die Welttransformation des Graphics-Objekts ist eine Übersetzung von 100 Einheiten in x-Richtung und 80 Einheiten in y-Richtung. Die globale Transformation des Containers ist eine Drehung um 30 Grad. Der Code führt den Aufruf aus.

DrawRectangle(&pen, -60, -30, 120, 60)

Zweimal. Der erste Aufruf von Graphics::D rawRectangle befindet sichim Container. Das heißt, der Aufruf befindet sich zwischen den Aufrufen von Graphics::BeginContainer und Graphics::EndContainer. Der zweite Aufruf von Graphics::D rawRectangle erfolgt nach dem Aufruf von Graphics::EndContainer.

Graphics           graphics(hdc);
Pen                pen(Color(255, 255, 0, 0));
GraphicsContainer  graphicsContainer;

graphics.TranslateTransform(100.0f, 80.0f);

graphicsContainer = graphics.BeginContainer();
   graphics.RotateTransform(30.0f);
   graphics.DrawRectangle(&pen, -60, -30, 120, 60);
graphics.EndContainer(graphicsContainer);

graphics.DrawRectangle(&pen, -60, -30, 120, 60);

Im vorherigen Code wird das rechteck, das aus dem Container gezeichnet wurde, zuerst durch die Welttransformation des Containers (Drehung) und dann durch die Welttransformation des Graphics-Objekts (Übersetzung) transformiert. Das rechteck, das von außerhalb des Containers gezeichnet wird, wird nur durch die Welttransformation des Graphics-Objekts (Übersetzung) transformiert. Die folgende Abbildung zeigt die beiden Rechtecke.

Screenshot eines Fensters mit zwei roten Rechtecken, die denselben Punkt zentriert, aber mit unterschiedlichen Drehungen

 

Clipping in geschachtelten Containern

Im folgenden Beispiel wird veranschaulicht, wie geschachtelte Container Clippingbereiche behandeln. Der Code erstellt ein Graphics-Objekt und einen Container innerhalb dieses Graphics-Objekts . Der Clippingbereich des Graphics-Objekts ist ein Rechteck, und der Beschneidungsbereich des Containers ist eine Ellipse. Der Code führt zwei Aufrufe an die Graphics::D rawLine-Methode aus. Der erste Aufruf von Graphics::D rawLine befindet sich innerhalb des Containers, und der zweite Aufruf von Graphics::D rawLine befindet sich außerhalb des Containers (nach dem Aufruf von Graphics::EndContainer). Die erste Linie wird am Schnittpunkt der beiden Clippingbereiche beschnitten. Die zweite Zeile wird nur durch den rechteckigen Beschneidungsbereich des Graphics-Objekts beschnitten .

Graphics           graphics(hdc);
GraphicsContainer  graphicsContainer;
Pen                redPen(Color(255, 255, 0, 0), 2);
Pen                bluePen(Color(255, 0, 0, 255), 2);
SolidBrush         aquaBrush(Color(255, 180, 255, 255));
SolidBrush         greenBrush(Color(255, 150, 250, 130));

graphics.SetClip(Rect(50, 65, 150, 120));
graphics.FillRectangle(&aquaBrush, 50, 65, 150, 120);

graphicsContainer = graphics.BeginContainer();
   // Create a path that consists of a single ellipse.
   GraphicsPath path;
   path.AddEllipse(75, 50, 100, 150);

  // Construct a region based on the path.
   Region region(&path);
   graphics.FillRegion(&greenBrush, &region);

   graphics.SetClip(&region);
   graphics.DrawLine(&redPen, 50, 0, 350, 300);
graphics.EndContainer(graphicsContainer);

graphics.DrawLine(&bluePen, 70, 0, 370, 300);

Die folgende Abbildung zeigt die beiden abgeschnittenen Linien.

Abbildung einer Ellipse in einem Rechteck, wobei eine Linie durch die Ellipse und die andere durch das Rechteck beschnitten wird

Wie in den beiden vorherigen Beispielen zu sehen, sind Transformationen und Clippingbereiche in geschachtelten Containern kumulativ. Wenn Sie die Welttransformationen des Containers und des Graphics-Objekts festlegen, gelten beide Transformationen für Elemente, die aus dem Container gezeichnet werden. Die Transformation des Containers wird zuerst angewendet, und die Transformation des Graphics-Objekts wird als zweites angewendet. Wenn Sie die Beschneidungsbereiche des Containers und des Grafikobjekts festlegen, werden elemente, die aus dem Container gezeichnet wurden, durch die Schnittmenge der beiden Beschneidungsbereiche beschnitten.

Qualitätseinstellungen in geschachtelten Containern

Qualitätseinstellungen ( SmoothingMode, TextRenderingHint usw.) in geschachtelten Containern sind nicht kumulativ; Stattdessen ersetzen die Qualitätseinstellungen des Containers vorübergehend die Qualitätseinstellungen eines Grafikobjekts . Wenn Sie einen neuen Container erstellen, sind die Qualitätseinstellungen für diesen Container auf Standardwerte festgelegt. Angenommen, Sie verfügen über ein Graphics-Objekt mit dem Glättungsmodus SmoothingModeAntiAlias. Wenn Sie einen Container erstellen, ist der Glättungsmodus innerhalb des Containers der Standardglättungsmodus. Sie können den Glättungsmodus des Containers festlegen, sodass für alle Elemente, die im Rahmen des Containers gezeichnet werden, der von Ihnen festgelegten Modus verwendet wird. Elemente, die nach dem Aufruf von Graphics::EndContainer gezeichnet wurden, werden entsprechend dem Glättungsmodus (SmoothingModeAntiAlias) gezeichnet, der vor dem Aufruf von Graphics::BeginContainer vorhanden war.

Mehrere Ebenen geschachtelter Container

Sie sind nicht auf einen Container in einem Graphics-Objekt beschränkt. Sie können eine Reihe von Containern erstellen, die im jeweils vorherigen Container geschachtelt sind, und die globale Transformation, den Clippingbereich und die Qualitätseinstellungen jedes dieser geschachtelten Container angeben. Wenn Sie eine Zeichenmethode aus dem innersten Container aufrufen, werden die Transformationen der Reihe nach angewendet – vom innersten bis zum äußersten Container. Elemente, die im Rahmen des innersten Containers gezeichnet werden, werden am Schnittpunkt aller Clippingbereiche beschnitten.

Im folgenden Beispiel wird ein Graphics-Objekt erstellt und dessen Textrenderinghinweis auf TextRenderingHintAntiAlias festgelegt. Durch den Code werden zwei ineinander geschachtelte Container erstellt. Der Textrenderinghinweis des äußeren Containers ist auf TextRenderingHintSingleBitPerPixel festgelegt, und der Textrenderinghinweis des inneren Containers ist auf TextRenderingHintAntiAlias festgelegt. Der Code zeichnet drei Zeichenfolgen: eine aus dem inneren Container, eine aus dem äußeren Container und eine aus dem Graphics-Objekt selbst.

Graphics graphics(hdc);
GraphicsContainer innerContainer;
GraphicsContainer outerContainer;
SolidBrush brush(Color(255, 0, 0, 255));
FontFamily fontFamily(L"Times New Roman");
Font font(&fontFamily, 36, FontStyleRegular, UnitPixel);

graphics.SetTextRenderingHint(TextRenderingHintAntiAlias);

outerContainer = graphics.BeginContainer();

   graphics.SetTextRenderingHint(TextRenderingHintSingleBitPerPixel);

   innerContainer = graphics.BeginContainer();
      graphics.SetTextRenderingHint(TextRenderingHintAntiAlias);
      graphics.DrawString(L"Inner Container", 15, &font,
         PointF(20, 10), &brush);
   graphics.EndContainer(innerContainer);

   graphics.DrawString(L"Outer Container", 15, &font, PointF(20, 50), &brush);

graphics.EndContainer(outerContainer);

graphics.DrawString(L"Graphics Object", 15, &font, PointF(20, 90), &brush);

Die folgende Abbildung zeigt die drei Zeichenfolgen. Die aus dem inneren Container und dem Graphics-Objekt gezeichneten Zeichenfolgen werden durch Antialiasing geglättet. Die aus dem äußeren Container gezeichnete Zeichenfolge wird aufgrund der Einstellung TextRenderingHintSingleBitPerPixel nicht durch Antialiasing geglättet.

Abbildung eines Rechtecks, das die gleiche Zeichenfolge enthält; nur die Zeichen in der ersten und letzten Zeile sind glatt