Freigeben über


Grafikcontainer

Der Grafikzustand – Abschneidebereich, Transformationen und Qualitätseinstellungen – wird in einem Graphics-Objekt gespeichert. Mit Windows GDI+ können Sie einen Teil des Zustands in einem Graphics-Objekt mithilfe eines Containers vorübergehend ersetzen oder erweitern. Sie starten einen Container, indem Sie die Graphics::BeginContainer-Methode eines Graphics-Objekts aufrufen und einen Container beenden, indem Sie die Graphics::EndContainer-Methode aufrufen. Zwischen Graphics::BeginContainer und Graphics::EndContainer gehören alle Zustandsänderungen, die Sie am Graphics-Objekt vornehmen, zum Container und überschreiben nicht den vorhandenen Zustand des Graphics-Objekts .

Im folgenden Beispiel wird ein Container in einem Graphics-Objekt erstellt. Die Welttransformation des Grafikobjekts ist eine Übersetzung von 200 Einheiten nach rechts, und die Welttransformation des Containers ist eine Übersetzung von 100 Einheiten nach unten.

myGraphics.TranslateTransform(200.0f, 0.0f);

myGraphicsContainer = myGraphics.BeginContainer();
   myGraphics.TranslateTransform(0.0f, 100.0f);
   myGraphics.DrawRectangle(&myPen, 0, 0, 50, 50);
myGraphics.EndContainer(myGraphicsContainer);

myGraphics.DrawRectangle(&myPen, 0, 0, 50, 50);

Beachten Sie, dass im vorherigen Beispiel die Anweisung myGraphics.DrawRectangle(&myPen, 0, 0, 50, 50) zwischen den Aufrufen von Graphics::BeginContainer und Graphics::EndContainer ein anderes Rechteck als die gleiche Anweisung erzeugt, die nach dem Aufruf von Graphics::EndContainer erstellt wurde. Nur die horizontale Übersetzung gilt für den DrawRectangle-Aufruf außerhalb des Containers. Beide Transformationen – die horizontale Übersetzung von 200 Einheiten und die vertikale Übersetzung von 100 Einheiten – gelten für den Graphics::D rawRectangle-Aufruf im Container. Die folgende Abbildung zeigt die beiden Rechtecke.

Screenshot eines Fensters mit zwei Rechtecken, die mit einem blauen Stift gezeichnet wurden, eines über dem anderen

Container können in Containern geschachtelt werden. Im folgenden Beispiel wird ein Container in einem Graphics-Objekt und ein anderer Container innerhalb des ersten Containers erstellt. Die Welttransformation des Graphics-Objekts ist eine Übersetzung von 100 Einheiten in x-Richtung und 80 Einheiten in y-Richtung. Die Weltumwandlung des ersten Containers ist eine 30-Grad-Drehung. Die Welttransformation des zweiten Containers ist eine Skalierung um den Faktor 2 in x-Richtung. Im zweiten Container wird die Graphics::D rawEllipse-Methode aufgerufen.

myGraphics.TranslateTransform(100.0f, 80.0f, MatrixOrderAppend);

container1 = myGraphics.BeginContainer();
   myGraphics.RotateTransform(30.0f, MatrixOrderAppend);

   container2 = myGraphics.BeginContainer();
      myGraphics.ScaleTransform(2.0f, 1.0f);
      myGraphics.DrawEllipse(&myPen, -30, -20, 60, 40);
   myGraphics.EndContainer(container2);

myGraphics.EndContainer(container1);

Die folgende Abbildung zeigt die Ellipse.

Screenshot eines Fensters, das eine gedrehte blaue Ellipse mit der Mitte (100,80) enthält

Beachten Sie, dass alle drei Transformationen für den Graphics::D rawEllipse-Aufruf gelten, der im zweiten (innersten) Container ausgeführt wird. Beachten Sie auch die Reihenfolge der Transformationen: zuerst skalieren, dann rotieren, dann übersetzen. Die innerste Transformation wird zuerst angewendet, und die äußerste Transformation wird zuletzt angewendet.

Jede Eigenschaft eines Graphics-Objekts kann in einem Container festgelegt werden (zwischen Aufrufen von Graphics::BeginContainer und Graphics::EndContainer). Beispielsweise kann ein Abschneidebereich in einem Container festgelegt werden. Alle im Container ausgeführten Zeichnungen sind auf den Beschneidungsbereich dieses Containers beschränkt und auch auf die Abschneidebereiche aller äußeren Container und den Abschneidebereich des Graphics-Objekts selbst beschränkt.

Die bisher besprochenen Eigenschaften – die Welttransformation und die Beschneidungsregion – werden durch geschachtelte Container kombiniert. Andere Eigenschaften werden vorübergehend durch einen geschachtelten Container ersetzt. Wenn Sie beispielsweise den Glättungsmodus in einem Container auf SmoothingModeAntiAlias festlegen, verwenden alle in diesem Container aufgerufenen Zeichnungsmethoden den Antialias-Glättungsmodus, aber die nach Graphics::EndContainer aufgerufenen Zeichnungsmethoden verwenden den Glättungsmodus, der vor dem Aufruf von Graphics::BeginContainer vorhanden war.

Für ein weiteres Beispiel für die Kombination der Welttransformationen eines Graphics-Objekts und eines Containers nehmen Sie an, Sie möchten ein Auge zeichnen und es an verschiedenen Stellen auf einer Sequenz von Gesichtern platzieren. Im folgenden Beispiel wird ein Auge am Ursprung des Koordinatensystems zentriert.

void DrawEye(Graphics* pGraphics)
{
   GraphicsContainer eyeContainer;
   
   eyeContainer = pGraphics->BeginContainer();

      Pen myBlackPen(Color(255, 0, 0, 0));
      SolidBrush myGreenBrush(Color(255, 0, 128, 0));
      SolidBrush myBlackBrush(Color(255, 0, 0, 0));

      GraphicsPath myTopPath;
      myTopPath.AddEllipse(-30, -50, 60, 60);

      GraphicsPath myBottomPath;
      myBottomPath.AddEllipse(-30, -10, 60, 60);

      Region myTopRegion(&myTopPath);
      Region myBottomRegion(&myBottomPath);

      // Draw the outline of the eye.
      // The outline of the eye consists of two ellipses.
      // The top ellipse is clipped by the bottom ellipse, and
      // the bottom ellipse is clipped by the top ellipse.
      pGraphics->SetClip(&myTopRegion);
      pGraphics->DrawPath(&myBlackPen, &myBottomPath);
      pGraphics->SetClip(&myBottomRegion);
      pGraphics->DrawPath(&myBlackPen, &myTopPath);

      // Fill the iris.
      // The iris is clipped by the bottom ellipse.
      pGraphics->FillEllipse(&myGreenBrush, -10, -15, 20, 22);

      // Fill the pupil.
      pGraphics->FillEllipse(&myBlackBrush, -3, -7, 6, 9);

   pGraphics->EndContainer(eyeContainer);
}

Die folgende Abbildung zeigt das Auge und die Koordinatenachsen.

Abbildung eines Auges, das aus drei Auslassungspunkten besteht: jeweils eine für den Umriss, die Iris und die Pupillen

Die im vorherigen Beispiel definierte DrawEye-Funktion empfängt die Adresse eines Graphics-Objekts und erstellt sofort einen Container innerhalb dieses Graphics-Objekts . Dieser Container isoliert jeden Code, der die DrawEye-Funktion aus Eigenschafteneinstellungen aufruft, die während der Ausführung der DrawEye-Funktion vorgenommen wurden. Code in der DrawEye-Funktion legt beispielsweise den Abschneidebereich des Graphics-Objekts fest, aber wenn DrawEye die Steuerung an die aufrufende Routine zurückgibt, ist der Abschneidebereich wie vor dem Aufruf von DrawEye.

Im folgenden Beispiel werden drei Auslassungspunkte (Gesichter) mit jeweils einem Auge gezogen.

// Draw an ellipse with center at (100, 100).
myGraphics.TranslateTransform(100.0f, 100.0f);
myGraphics.DrawEllipse(&myBlackPen, -40, -60, 80, 120);

// Draw the eye at the center of the ellipse.
DrawEye(&myGraphics);

// Draw an ellipse with center at 200, 100.
myGraphics.TranslateTransform(100.0f, 0.0f, MatrixOrderAppend);
myGraphics.DrawEllipse(&myBlackPen, -40, -60, 80, 120);

// Rotate the eye 40 degrees, and draw it 30 units above
// the center of the ellipse.
myGraphicsContainer = myGraphics.BeginContainer();
   myGraphics.RotateTransform(-40.0f);
   myGraphics.TranslateTransform(0.0f, -30.0f, MatrixOrderAppend);
   DrawEye(&myGraphics);
myGraphics.EndContainer(myGraphicsContainer);

// Draw a ellipse with center at (300.0f, 100.0f).
myGraphics.TranslateTransform(100.0f, 0.0f, MatrixOrderAppend);
myGraphics.DrawEllipse(&myBlackPen, -40, -60, 80, 120);

// Stretch and rotate the eye, and draw it at the 
// center of the ellipse.
myGraphicsContainer = myGraphics.BeginContainer();
   myGraphics.ScaleTransform(2.0f, 1.5f);
   myGraphics.RotateTransform(45.0f, MatrixOrderAppend);
   DrawEye(&myGraphics);
myGraphics.EndContainer(myGraphicsContainer);

Die folgende Abbildung zeigt die drei Auslassungspunkte.

Screenshot eines Fensters mit drei Auslassungspunkten, die jeweils ein Auge mit einer anderen Größe und Drehung enthalten

Im vorherigen Beispiel werden alle Auslassungspunkte mit dem Aufruf DrawEllipse(&myBlackPen, -40, -60, 80, 120)gezeichnet, der eine Ellipse zentriert am Ursprung des Koordinatensystems zeichnet. Die Auslassungspunkte werden von der oberen linken Ecke des Clientbereichs entfernt, indem die Welttransformation des Grafikobjekts festgelegt wird. Die Anweisung bewirkt, dass die erste Ellipse bei (100, 100) zentriert wird. Die -Anweisung bewirkt, dass der Mittelpunkt der zweiten Ellipse 100 Einheiten rechts neben dem Zentrum der ersten Ellipse ist. Ebenso ist die Mitte der dritten Ellipse 100 Einheiten rechts neben dem Zentrum der zweiten Ellipse.

Die Container im vorherigen Beispiel werden verwendet, um das Auge relativ zum Zentrum einer gegebenen Ellipse zu transformieren. Das erste Auge wird in der Mitte der Ellipse ohne Transformation gezeichnet, sodass sich der DrawEye-Aufruf nicht in einem Container befindet. Das zweite Auge wird um 40 Grad gedreht und 30 Einheiten über dem Mittelpunkt der Ellipse gezeichnet, sodass die DrawEye-Funktion und die Methoden, die die Transformation festlegen, in einem Container aufgerufen werden. Das dritte Auge wird gestreckt und gedreht und in der Mitte der Ellipse gezeichnet. Wie beim zweiten Auge werden die DrawEye-Funktion und die Methoden, die die Transformation festlegen, in einem Container aufgerufen.