Partager via


Conteneurs graphiques

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, 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 à 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'Graphics ::D rawRectangle appel 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, un positionné 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 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 par 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 un ellipse bleu pivoté avec son centre intitulé (100 80)

Notez que les trois transformations s’appliquent au Graphics ::D rawEllipse appel effectué dans le deuxième conteneur (le plus interne). Notez également l’ordre des transformations : la première échelle, puis la rotation, puis la traduction. 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 graphicspeut être définie à l’intérieur d’un conteneur (entre les appels à Graphics ::BeginContainer et Graphics ::EndContainer). Par exemple, une région 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 région de découpage de l’objet Graphics lui-même.

Les propriétés abordées jusqu’à présent — la transformation mondiale et la région de découpage — sont combinées par des conteneurs imbriqués. D’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 antialias, mais les méthodes de dessin appelées après Graphics ::EndContainer utiliseront le mode de lissage qui était en place avant l’appel à Graphics ::BeginContainer.

Pour un autre exemple de combinaison des transformations mondiales d’un Graphics objet et d’un conteneur, supposons que vous souhaitez 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 points de suspension : un pour le contour, l’iris et l’élève

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 à partir des paramètres de propriété effectué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 région de découpage sera comme avant l’appel à DrawEye.

L’exemple suivant dessine trois points de suspension (visages), chacun 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 points de suspension.

capture d’écran d’une fenêtre avec trois points de suspension, chacun contenant un œil à une taille et une rotation différentes

Dans l’exemple précédent, tous les points de suspension sont dessinés avec l’appel DrawEllipse(&myBlackPen, -40, -60, 80, 120), qui dessine un ellipse centré à l’origine du système de coordonnées. Les points de suspension sont déplacés de l’angle supérieur gauche de la zone cliente en définissant la transformation mondiale de l’objet Graphics. L’instruction provoque le centre de la première ellipse (100, 100). L’instruction fait en sorte que le centre du deuxième ellipse soit 100 unités à droite du centre du premier ellipse. De même, le centre du 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’un ellipse donné. Le premier œil est dessiné au centre de l’ellipse sans transformation, de sorte que l’appel DrawEye n’est pas à l’intérieur d’un conteneur. Le second œil est pivoté de 40 degrés et dessiné 30 unités au-dessus du centre de l’ellipse, de sorte que 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 pour 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.