共用方式為


圖形容器

圖形狀態 — 裁剪區域、轉換和品質設定 — 會儲存在 Graphics 物件中。 Windows GDI+ 可讓您使用容器暫時取代或增強 Graphics 物件中狀態的一部分。 您可以呼叫Graphics物件的Graphics::BeginContainer方法來啟動容器,並呼叫Graphics::EndContainer方法結束容器。 在Graphics::BeginContainer 與 Graphics::EndContainer之間,您對Graphics物件所做的任何狀態變更都屬於容器,而且不會覆寫Graphics物件的現有狀態。

下列範例會在 Graphics 物件內建立容器。 Graphics物件的世界轉換是右邊的翻譯 200 單位,而容器的世界轉換則是向下轉譯 100 單位。

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

請注意,在上一個範例中,在對 Graphics::BeginContainerGraphics::EndContainer的呼叫之間所做的 語句 myGraphics.DrawRectangle(&myPen, 0, 0, 50, 50) 會產生與呼叫Graphics::EndContainer之後所做的相同語句不同的矩形。 只有水準轉譯會套用至容器外部進行的 DrawRectangle 呼叫。 這兩個轉換 — 水準轉譯為 200 個單位,以及垂直轉譯為 100 個單位 — 適用于容器內進行的 Graphics::D rawRectangle 呼叫。 下圖顯示兩個矩形。

以藍色畫筆繪製兩個矩形的視窗螢幕擷取畫面,一個位於另一個矩形上方

容器可以巢狀在容器內。 下列範例會在 Graphics 物件內建立容器,並在第一個容器內建立另一個容器。 Graphics物件的世界轉換是 x 方向的轉譯 100 單位,80 個單位以 y 方向。 第一個容器的世界轉換是 30 度旋轉。 第二個容器的世界轉換是以 x 方向的 2 乘以比例調整。 第二個容器內會呼叫 Graphics::D rawEllipse 方法。

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

下圖顯示省略號。

視窗的螢幕擷取畫面,其中包含旋轉的藍色橢圓形,其中心標示為 (100,80)

請注意,這三個轉換都會套用至第二個 (最內部) 容器中所做的 Graphics::D rawEllipse 呼叫。 另請注意轉換的順序:第一次縮放,然後旋轉,然後轉譯。 最內部的轉換會先套用,最後套用最外層的轉換。

Graphics物件的任何屬性都可以在容器內設定, (呼叫 Graphics::BeginContainer 和 Graphics::EndContainer) 。 例如,裁剪區域可以在容器內設定。 容器內完成的任何繪圖都會受限於該容器的裁剪區域,也會限制為任何外部容器的裁剪區域,以及 Graphics 物件本身的裁剪區域。

到目前為止所討論的屬性— 世界轉換和裁剪區域— 會由巢狀容器結合。 其他屬性會暫時由巢狀容器取代。 例如,如果您將平滑模式設定為容器內的 SmoothingModeAntiAlias,在該容器內呼叫的任何繪圖方法都會使用反鋸齒平滑處理模式,但在 Graphics::EndContainer 之後呼叫的繪製方法將會使用 呼叫 Graphics::BeginContainer之前就地的平滑模式。

如需結合 Graphics 物件和容器世界轉換的另一個範例,假設您想要繪製眼睛,並將它放在一連串臉部上的各種位置。 下列範例會繪製位於座標系統原點的眼睛。

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

下圖顯示眼睛和座標軸。

圖例顯示由三個橢圓形組成的眼睛:一個用於外框、鳶尾花和鳶尾花

在上一個範例中定義的 DrawEye 函式會接收 Graphics 物件的位址,並立即在該 Graphics 物件內建立容器。 此容器會隔離任何呼叫 DrawEye 函式的程式碼,以及執行 DrawEye 函式期間所做的屬性設定。 例如,DrawEye 函式中的程式碼會設定 Graphics 物件的裁剪區域,但是當 DrawEye 將控制項傳回呼叫常式時,裁剪區域會如同呼叫 DrawEye 之前一樣。

下列範例會繪製三個橢圓形, (臉部) ,每個橢圓形內都有一個眼睛。

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

下圖顯示三個省略號。

具有三個橢圓形的視窗螢幕擷取畫面,每個橢圓形都包含不同大小和旋轉的眼睛

在上一個範例中,所有省略號都是使用 呼叫 DrawEllipse(&myBlackPen, -40, -60, 80, 120) 繪製,它會繪製以座標系統原點置的橢圓形。 省略號會藉由設定 Graphics 物件的世界轉換,從工作區左上角移出。 語句會使第一個省略號置中 (100, 100) 。 語句會使第二個省略號的中心在第一個橢圓形中央的右邊 100 個單位。 同樣地,第三個橢圓形的中心是第二個橢圓形中央的 100 單位。

上一個範例中的容器是用來轉換相對於指定橢圓形中央的眼睛。 第一個眼睛是在省略號中央繪製,沒有轉換,因此 DrawEye 呼叫不在容器內。 第二個眼睛會旋轉 40 度,並在橢圓形中央繪製 30 個單位,因此 DrawEye 函式和設定轉換的方法會在容器內呼叫。 第三個眼睛會伸展並旋轉,並繪製在橢圓形的中心。 如同第二眼,DrawEye 函式和設定轉換的方法會在容器內呼叫。