Partager via


Conteneurs Graphics

L’état graphique (zone de découpage, transformations et paramètres de qualité) est stocké dans un objet Graphics . Windows GDI+ vous permet de remplacer ou d’augmenter temporairement une partie de l’état dans un objet Graphics à l’aide d’un conteneur. Vous démarrez un conteneur en appelant la méthode Graphics::BeginContainer d’un objet Graphics et vous terminez un conteneur en appelant la méthode Graphics::EndContainer . Entre Graphics::BeginContainer et Graphics::EndContainer, toutes les modifications d’état que vous apportez à l’objet Graphics appartiennent au conteneur et ne remplacent pas l’état existant de l’objet Graphics .

L’exemple suivant crée un conteneur dans un objet Graphics . La transformation mondiale de l’objet Graphics est une traduction de 200 unités vers la droite, et la transformation mondiale du conteneur est une traduction de 100 unités vers le bas.

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);

Notez que dans l’exemple précédent, l’instruction myGraphics.DrawRectangle(&myPen, 0, 0, 50, 50) effectuée entre les appels à Graphics::BeginContainer et Graphics::EndContainer produit un rectangle différent de la même instruction effectuée après l’appel à Graphics::EndContainer. Seule la traduction horizontale s’applique à l’appel DrawRectangle effectué en dehors du conteneur. Les deux transformations , la traduction horizontale de 200 unités et la traduction verticale de 100 unités, s’appliquent à l’appel Graphics::D rawRectangle effectué à l’intérieur du conteneur. L’illustration suivante montre les deux rectangles.

capture d’écran d’une fenêtre avec deux rectangles dessinés avec un stylet bleu, l’un placé au-dessus de l’autre

Les conteneurs peuvent être imbriqués dans des conteneurs. L’exemple suivant crée un conteneur dans un objet Graphics et un autre conteneur dans le premier conteneur. La transformation mondiale de l’objet Graphics est une traduction de 100 unités dans la direction x et de 80 unités dans la direction y. La transformation mondiale du premier conteneur est une rotation de 30 degrés. La transformation mondiale du deuxième conteneur est une mise à l’échelle d’un facteur de 2 dans la direction x. Un appel à la méthode Graphics::D rawEllipse est effectué à l’intérieur du deuxième conteneur.

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);

L’illustration suivante montre l’ellipse.

capture d’écran d’une fenêtre qui contient une ellipse bleue pivotée avec son centre étiqueté comme (100,80)

Notez que les trois transformations s’appliquent à l’appel Graphics::D rawEllipse effectué dans le deuxième conteneur (le plus interne). Notez également l’ordre des transformations : d’abord mettre à l’échelle, puis faire pivoter, puis traduire. La transformation la plus interne est appliquée en premier, et la transformation la plus externe est appliquée en dernier.

Toute propriété d’un objet Graphics peut être définie à l’intérieur d’un conteneur (entre les appels à Graphics::BeginContainer et Graphics::EndContainer). Par exemple, une zone de découpage peut être définie à l’intérieur d’un conteneur. Tout dessin effectué à l’intérieur du conteneur sera limité à la zone de découpage de ce conteneur et sera également limité aux régions de découpage de tous les conteneurs externes et à la zone de découpage de l’objet Graphics lui-même.

Les propriétés abordées jusqu’à présent ( la transformation du monde et la région de découpage ) sont combinées par des conteneurs imbriqués. Les autres propriétés sont temporairement remplacées par un conteneur imbriqué. Par exemple, si vous définissez le mode de lissage sur SmoothingModeAntiAlias dans un conteneur, toutes les méthodes de dessin appelées à l’intérieur de ce conteneur utilisent le mode de lissage anticrénelique, mais les méthodes de dessin appelées graphics::EndContainer utilisent le mode de lissage qui était en place avant l’appel à Graphics::BeginContainer.

Pour un autre exemple de combinaison des transformations du monde d’un objet Graphics et d’un conteneur, supposons que vous souhaitiez dessiner un œil et le placer à différents emplacements sur une séquence de visages. L’exemple suivant dessine un œil centré à l’origine du système de coordonnées.

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);
}

L’illustration suivante montre l’œil et les axes de coordonnées.

illustration montrant un œil composé de trois ellipses : une pour le contour, l’iris et la pupille

La fonction DrawEye, définie dans l’exemple précédent, reçoit l’adresse d’un objet Graphics et crée immédiatement un conteneur dans cet objet Graphics . Ce conteneur isole tout code qui appelle la fonction DrawEye des paramètres de propriété créés pendant l’exécution de la fonction DrawEye. Par exemple, le code dans la fonction DrawEye définit la zone de découpage de l’objet Graphics , mais lorsque DrawEye retourne le contrôle à la routine appelante, la zone de découpage est telle qu’elle était avant l’appel à DrawEye.

L’exemple suivant dessine trois ellipses (visages), chacune avec un œil à l’intérieur.

// 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);

L’illustration suivante montre les trois ellipses.

capture d’écran d’une fenêtre avec trois ellipses, chacune contenant un œil de taille et de rotation différentes

Dans l’exemple précédent, toutes les ellipses sont dessinées avec l’appel DrawEllipse(&myBlackPen, -40, -60, 80, 120), qui dessine une ellipse centrée à l’origine du système de coordonnées. Les points de suspension sont déplacés du coin supérieur gauche de la zone cliente en définissant la transformation de monde de l’objet Graphics . L’instruction entraîne le centre de la première ellipse sur (100, 100). L’instruction fait que le centre de la deuxième ellipse est de 100 unités à droite du centre de la première ellipse. De même, le centre de la troisième ellipse est de 100 unités à droite du centre de la deuxième ellipse.

Les conteneurs de l’exemple précédent sont utilisés pour transformer l’œil par rapport au centre d’une ellipse donnée. Le premier œil étant dessiné au centre de l’ellipse sans transformation, l’appel DrawEye n’est pas à l’intérieur d’un conteneur. Le deuxième œil étant pivoté de 40 degrés et dessiné 30 unités au-dessus du centre de l’ellipse, la fonction DrawEye et les méthodes qui définissent la transformation sont appelées à l’intérieur d’un conteneur. Le troisième œil est étiré et pivoté et dessiné au centre de l’ellipse. Comme avec le deuxième œil, la fonction DrawEye et les méthodes qui définissent la transformation sont appelées à l’intérieur d’un conteneur.