GDI+ 平面 API

Windows GDI+ 公开一个由大约 600 个函数组成的平面 API,这些函数在 Gdiplus.dll 中实现,并在 Gdiplusflat.h 中声明。 GDI+ 平面 API 中的函数由大约 40 个 C++ 类的集合包装。 建议不要直接调用平面 API 中的函数。 每当调用 GDI+ 时,都应该通过调用 C++ 包装器提供的方法和函数来执行此操作。 Microsoft 产品支持服务不会为直接调用平面 API 的代码提供支持。

作为 C++ 包装器的替代方法,Microsoft .NET Framework 为 GDI+ 提供了一组托管代码包装器类。 GDI+ 的托管代码包装器属于以下命名空间。

两组包装器(C++ 和托管代码)都使用面向对象的方法,因此参数传递到包装方法的方式与参数传递到平面 API 中函数的方式之间存在一些差异。 例如,C++ 包装器之一是 Matrix 类。 每个 Matrix 对象都有字段 nativeMatrix,该字段指向 GpMatrix 类型的内部变量。 将参数传递给 Matrix 对象的方法时,该方法会将这些参数(或一组相关参数)传递到 GDI+ 平面 API 中的某个函数。 但该方法还会将 nativeMatrix 字段(作为输入参数)传递给平面 API 函数。 以下代码演示 Matrix::Shear 方法如何调用 GdipShearMatrix(GpMatrix *matrix, REAL shearX, REAL shearY, GpMatrixOrder order) 函数。

Status Shear(
      IN REAL shearX, 
      IN REAL shearY,
      IN MatrixOrder order = MatrixOrderPrepend)
{
   ...
   GdipShearMatrix(nativeMatrix, shearX, shearY, order);
   ...
}

Matrix 构造函数将 GpMatrix指针变量(作为输出参数)的地址传递给 GdipCreateMatrix(GpMatrix **matrix) 函数。 GdipCreateMatrix 创建并初始化内部 GpMatrix 变量,然后将 GpMatrix 的地址分配给指针变量。 然后,构造函数将指针的值复制到 nativeMatrix 字段。

Matrix()
{
   GpMatrix *matrix = NULL;
   lastResult = DllExports::GdipCreateMatrix(&matrix);
   SetNativeMatrix(matrix);
}

VOID SetNativeMatrix(GpMatrix *nativeMatrix)
{
   this->nativeMatrix = nativeMatrix;
}

包装器类中的克隆方法不接收任何参数,但通常会将两个参数传递给 GDI+ 平面 API 中的基础函数。 例如,Matrix::Clone 方法将 nativeMatrix(作为输入参数)和 GpMatrix 指针变量(作为输出参数)的地址传递给 GdipCloneMatrix 函数。 以下代码演示 Matrix::Clone 方法如何调用 GdipCloneMatrix(GpMatrix *matrix, GpMatrix **cloneMatrix) 函数。

Matrix *Clone() const
{
   GpMatrix *cloneMatrix = NULL;
   ...
   GdipCloneMatrix(nativeMatrix, &cloneMatrix));
   ...
   return new Matrix(cloneMatrix);
 }

平面 API 中的函数返回 GpStatus 类型的值。 GpStatus 枚举与包装器方法使用的 Status 枚举相同。 在 GdiplusGpStubs.h 中,GpStatus 定义如下:

typedef Status GpStatus;

包装器类中的大多数方法都返回指示方法是否成功的状态值。 但某些包装器方法返回状态值。 调用返回状态值的包装器方法时,包装器方法会将相应的参数传递给 GDI+ 平面 API 中的基础函数。 例如,Matrix 类具有 Matrix::IsInvertible 方法,该方法将 nativeMatrix 字段和 BOOL 变量的地址(作为输出参数)传递给 GdipIsMatrixInvertible 函数。 以下代码演示 Matrix::IsInvertible 方法如何调用 GdipIsMatrixInvertible(GDIPCONST GpMatrix *matrix, BOOL *result) 函数。

BOOL IsInvertible() const
{
   BOOL result = FALSE;
   ...
   GdipIsMatrixInvertible(nativeMatrix, &result);
   return result;
}

包装器的另一个是 Color 类。 Color 对象具有 ARGB 类型的单一字段,定义为 DWORD。 将 Color 对象传递到包装器方法之一时,该方法会将 ARGB 字段传递到 GDI+ 平面 API 中的基础函数。 以下代码演示 Pen::SetColor 方法如何调用 GdipSetPenColor(GpPen *pen, ARGB argb) 函数。 Color::GetValue 方法返回 ARGB 字段的值。

Status SetColor(IN const Color& color)
{
   ...
   GdipSetPenColor(nativePen, color.GetValue());
}

以下主题显示了 GDI+ 平面 API 与 C++ 包装器方法之间的关系。