快速业务通道

托管C++中GDI+和GDI混合编程技术

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-30

(1) 封送结构

在托管C++中,当调用的GDI API函数有内置结构时,需要对其使用StructLayout属性来进行封送。通过该属性类的构造函数来指定被封送的结构的数据成员在非托管内存中的排列方式。当为LayoutKind::Explicit时,则每个成员必须使用FieldOffset属性来指定该字段在类型中的位置。当为LayoutKind::Sequential时,则强制将成员按其出现的顺序进行顺序布局。例如:

namespace GDI32API
{
  using namespace System;
  using namespace System::Runtime::InteropServices;
  typedef void* HDC;
  [StructLayout(LayoutKind::Sequential)]
  public __value struct RECT
  {
   public:
    long left; // long或Int32
    long top;
    long right;
    long bottom;
  };
  [DllImport("gdi32", EntryPoint="GetClipBox")]
  extern "C" int GetClipBox(HDC hDC, RECT* rect);
}

(2) 封送字符串和数组等

在托管C++中,使用MarshalAs属性类可以封送GDI API函数中的参数、内置结构的字段或返回值。MarshalAs属性通常需要指定UnmanagedType枚举来标识非托管数据的格式。

当需要封送String *字符串时,可指定UnmanagedType枚举中的LPStr、LPWStr或LPTStr来封送,这些类型分别对应于GDI API中的LPSTR、LPWSTR或LPTSTR字符串类型。例如:

[DllImport("gdi32", EntryPoint="TextOut")]
extern "C" bool TextOut(HDC hDC, int x, int y,
[MarshalAs(UnmanagedType::LPWStr)] String *str, int nNum);

若封送结构中的字符串成员,则需指定UnmanagedType::ByValTStr类型,并指定SizeConst值来确定要导入的字符串中的字符数。

当需要封送数组时,需指定UnmanagedType::LPArray类型,并指定SizeConst值来确定要导入的数组大小,根据需要也可用ArraySubType字段指定数组元素的数据类型。例如,若有DLL中有这样的非托管函数:

HRESULT New1(int ar[10]);
HRESULT New2(double ar[10][20]);
HRESULT New3(LPWSTR ar[10]);

则封送的托管代码如下:

void New1([MarshalAs(UnmanagedType::LPArray, SizeConst=10)] int ar __gc[]);
void New2([MarshalAs(UnmanagedType::LPArray, SizeConst=200)] double ar __gc[]);
void New2([MarshalAs(UnmanagedType::LPArray,
ArraySubType=UnmanagedType::LPWStr, SizeConst=10)] String[] ar);

若封送结构中的数组成员,则需指定UnmanagedType::ByValArray类型,并指定SizeConst值来确定要导入的数组大小。

3.3 实例

这个实例是用来显示实现绘制直线的橡皮条过程,如图1所示的窗体。其中平台调用的GDI函数和结构如下面的代码:

namespace GDI32
{
  using namespace System;
  using namespace System::Runtime::InteropServices;
  typedef void* HDC;
  typedef void* HPEN;
  [StructLayout(LayoutKind::Sequential)]
  public __value struct POINT
  {
   public:
    long x; // long或Int32
    long y;
  };
  [DllImport("gdi32", EntryPoint="SetROP2")]
  extern "C" int SetROP2(HDC hDC, int fnDrawMode); // 设置光栅操作模式
  [DllImport("gdi32", EntryPoint="CreatePen")]
  extern "C" HPEN CreatePen(int fnPenStyle, int nWidth, unsigned long crColor);
  // 创建画笔
  [DllImport("gdi32", EntryPoint="SelectObject")]
  extern "C" void* SelectObject(HDC hDC, void* hGdiobj);
  // 选入GDI属性对象
  [DllImport("gdi32", EntryPoint=&quo

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号