使用C#封装Win32API

使用C#封装Win32API

微软.NET框架的类库功能强大,内容丰富,可以处理大部分的编程要求,但在一些场合下,.NET框架类库不提供支持,此时需要借助Win32API来实现了。

一般的小弟不推荐在.NET程序中使用Win32API,因为这样不符合.NET编程的安全框架,而且让程序绑定到特定的操作系统,因为未来你的.NET程序可能不在Win32操作系统下运行。

推荐归推荐,有时候要用还得用,在此说说.NET下使用Win32API,本人现在使用C#,因此在此只说说C#语言来使用Win32API。

在C#使用Win32API很方便,只需要从指定的DLL文件中导入函数声明即可。比如在某个类中写下
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern int GetDeviceCaps(int hDC , int index );

此后程序就像调用静态函数一样调用这个API函数了。这有点类似VB中声明API了。

大家知道,Win32API是平面结构,将一个DLL中的API罗列出来,成百上千的API一字排开,好生壮观,可惜使用不方便,调用它们需要了解各个API入口和出口以及各个API之间的影响,而且一些API比较危险,需要小心调用,若在错误的时间使用错误的参数调用错误的API则可能导致系统资源泄漏,程序突然退出,甚至会伤害操作系统。

而.NET类库则是树状的立体结构,它使用了面向对象的编程结构,从而掩盖了很多细节,我们调用也方便,也很安全。

以前小弟为了调用API就是在到用的时候就声明API,或者作个模块,列出很多API声明供其他地方调用。经验告诉我,这种简单的用法不够好。于是小弟就开始使用C#的语法结构来封装API。

在此使用API函数GetDeviceCaps作例子,这个函数就是获得指定设备上下文的某些信息,参数为设备上下文句柄(hdc)和类型为DeviceCapsConst信息编号。这个设备上下文句柄是个比较重的句柄,严禁浪费,用完只后需要释放掉该句柄,但释放HDC并不简单,需要知道句柄的来源,当使用CreateDC获得的句柄则必须使用DeleteDC来释放。

对于比较重要的资源,比如句柄,文件,数据库连接等等,有个原则就是尽晚获得,尽早释放,因此需要尽量减少持有句柄的时间。

小弟定义了一个类DeviceCapsClass,用于封装GetDeviceCaps,在获得一个句柄时就立即多次调用GetDeviceCaps来获得所有的信息,然后保存到一个缓冲区中,然后立即释放句柄。并定义了方便的访问缓冲数据的接口。这样其他程序只需要实例化一个DeviceCapsClass,调用它的属性就可获得设备上下文信息而无需考虑细节。

其实这种做法.NET框架类库自己就这么搞,大家看看.NET类库的反编译结果,可以看到.NET类库中有很多就是Win32API的封装。相信大家已经这么做了或将来也这样做。
现列出DeviceCapsClass所有代码



 

using System;
namespace Windows32
{
    /// <summary>
    /// 获得指定设备上下文信息的对象,本模块为API函数GetDeviceCaps的封装
    /// </summary>
    /// <remarks>编制 有为青年 XDesigner 2006-5-4</remarks>
    public class DeviceCapsClass
    {
        #region 静态成员 **************************************************************************

        private static DeviceCapsClass myDisplayInstance = null;
        /// <summary>
        /// 针对屏幕的设备上下文信息对象
        /// </summary>
        /// <remarks>程序可能经常访问屏幕的设备上下文信息,在此专门提供静态成员给予访问</remarks>
        public static DeviceCapsClass DispalyInstance
        {
            get
            {
                if( myDisplayInstance == null)
                {
                    myDisplayInstance = new DeviceCapsClass();
                    myDisplayInstance.ResetForDisplay();
                }
                return myDisplayInstance ;
            }
        }

        #endregion

        #region 构造函数 **************************************************************************

        /// <summary>
        /// 无作为的初始化对象
        /// </summary>
        public DeviceCapsClass()
        {
        }
        /// <summary>
        /// 使用指定设备上下文初始化对象
        /// </summary>
        /// <param name="hdc">设备上下文句柄</param>
        public DeviceCapsClass( int hdc )
        {
            Reset( hdc );
        }
        /// <summary>
        /// 使用指定设备名初始化对象
        /// </summary>
        /// <remarks>本函数根据名称创建设备上下文,获得所需数据后立即删除设备上下文</remarks>
        /// <param name="DriverName">设备名</param>
        public DeviceCapsClass( string vDriverName )
        {
            Reset( vDriverName );
        }

        #endregion

        private string strDriverName = null;
        /// <summary>
        /// 设备名称
        /// </summary>
        public string DriverName
        {
            get{ return strDriverName ;}
        }
        public void Reset( int hDC )
        {
            strDriverName = null;
            System.Array myValues = System.Enum.GetValues( typeof( enumDeviceCapsConst ));
            intValues = new int[ myValues.Length * 2 ];
            for(int iCount = 0 ; iCount < myValues.Length ; iCount ++ )
            {
                int CapsValue = Convert.ToInt32( myValues.GetValue( iCount ));
                intValues[iCount * 2 ] = CapsValue ;
                intValues[iCount * 2 + 1] = GetDeviceCaps( hDC , CapsValue );
            }
        }
        public void Reset( string vDriverName )
        {
            int hdc = CreateDC( vDriverName , null , 0 , 0 );
            if( hdc != 0 )
            {
                Reset( hdc );
                DeleteDC( hdc );
                strDriverName = vDriverName ;
            }
        }
        public void ResetForDisplay( )
        {
            Reset( "DISPLAY" );
        }

        /// <summary>
        /// 已重载:获得对象所有内容的字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            if( intValues == null)
                return "DeviceCapsClass:对象尚未初始化";
            System.Text.StringBuilder myStr = new System.Text.StringBuilder();
            myStr.Append("DeviceCapsClass");
            if( strDriverName != null)
                myStr.Append(" Driver:" + strDriverName );
            System.Array myValues = System.Enum.GetValues( typeof( enumDeviceCapsConst ));
            foreach( enumDeviceCapsConst dc in myValues )
            {
                myStr.Append( System.Environment.NewLine );
                myStr.Append( dc.ToString() + " = " + GetValue( dc ) );
            }
            return myStr.ToString();
        }

        #region 获得数据的属性群 ******************************************************************

        /// <summary>
        /// Device driver version
        /// </summary>
        public int DRIVERVERSION{ get { return GetValue( enumDeviceCapsConst.DRIVERVERSION );} }
        /// <summary>
        /// Device classification
        /// </summary>
        public int TECHNOLOGY { get { return GetValue( enumDeviceCapsConst.TECHNOLOGY );} }
        /// <summary>
        /// Horizontal size in millimeters
        /// </summary>
        public int HORZSIZE { get { return GetValue( enumDeviceCapsConst.HORZSIZE );} }
        /// <summary>
        ///  Vertical size in millimeters
        /// </summary>
        public int VERTSIZE { get { return GetValue( enumDeviceCapsConst.VERTSIZE );} }
        /// <summary>
        ///  Horizontal width in pixels
        /// </summary>
        public int HORZRES { get { return GetValue( enumDeviceCapsConst.HORZRES );} }
        /// <summary>
        /// Vertical width in pixels
        /// </summary>
        public int VERTRES { get { return GetValue( enumDeviceCapsConst.VERTRES );} }
        /// <summary>
        /// Logical pixels/inch in X
        /// </summary>
        public int LOGPIXELSX { get { return GetValue( enumDeviceCapsConst.LOGPIXELSX );} }
        /// <summary>
        /// Logical pixels/inch in Y
        /// </summary>
        public int LOGPIXELSY { get { return GetValue( enumDeviceCapsConst.LOGPIXELSY );} }
        /// <summary>
        /// Number of planes
        /// </summary>
        public int PLANES { get { return GetValue( enumDeviceCapsConst.PLANES );} }
        /// <summary>
        /// Number of brushes the device has
        /// </summary>
        public int NUMBRUSHES { get { return GetValue( enumDeviceCapsConst.NUMBRUSHES );} }
        /// <summary>
        /// Number of colors the device supports
        /// </summary>
        public int NUMCOLORS { get { return GetValue( enumDeviceCapsConst.NUMCOLORS );} }
        /// <summary>
        /// Number of fonts the device has
        /// </summary>
        public int NUMFONTS { get { return GetValue( enumDeviceCapsConst.NUMFONTS );} }
        /// <summary>
        /// Number of pens the device has
        /// </summary>
        public int NUMPENS { get { return GetValue( enumDeviceCapsConst.NUMPENS );} }
        /// <summary>
        /// Length of the X leg
        /// </summary>
        public int ASPECTX { get { return GetValue( enumDeviceCapsConst.ASPECTX );} }
        /// <summary>
        /// Length of the hypotenuse
        /// </summary>
        public int ASPECTXY { get { return GetValue( enumDeviceCapsConst.ASPECTXY );} }
        /// <summary>
        /// Length of the Y leg
        /// </summary>
        public int ASPECTY { get { return GetValue( enumDeviceCapsConst.ASPECTY );} }
        /// <summary>
        /// Size required for device descriptor
        /// </summary>
        public int PDEVICESIZE { get { return GetValue( enumDeviceCapsConst.PDEVICESIZE );} }
        /// <summary>
        /// Clipping capabilities
        /// </summary>
        public int CLIPCAPS { get { return GetValue( enumDeviceCapsConst.CLIPCAPS );} }
        /// <summary>
        /// Number of entries in physical palette
        /// </summary>
        public int SIZEPALETTE { get { return GetValue( enumDeviceCapsConst.SIZEPALETTE );} }
        /// <summary>
        /// Number of reserved entries in palette
        /// </summary>
        public int NUMRESERVED { get { return GetValue( enumDeviceCapsConst.NUMRESERVED );} }
        /// <summary>
        /// Actual color resolution
        /// </summary>
        public int COLORRES { get { return GetValue( enumDeviceCapsConst.COLORRES );} }
        /// <summary>
        /// Physical Printable Area x margin
        /// </summary>
        public int PHYSICALOFFSETX { get { return GetValue( enumDeviceCapsConst.PHYSICALOFFSETX );} }
        /// <summary>
        /// Physical Printable Area y margin
        /// </summary>
        public int PHYSICALOFFSETY { get { return GetValue( enumDeviceCapsConst.PHYSICALOFFSETY );} }
        /// <summary>
        /// Physical Height in device units
        /// </summary>
        public int PHYSICALHEIGHT{ get { return GetValue( enumDeviceCapsConst.PHYSICALHEIGHT );} }
        /// <summary>
        /// Physical Width in device units
        /// </summary>
        public int PHYSICALWIDTH { get { return GetValue( enumDeviceCapsConst.PHYSICALWIDTH );} }
        /// <summary>
        /// Scaling factor x
        /// </summary>
        public int SCALINGFACTORX { get { return GetValue( enumDeviceCapsConst.SCALINGFACTORX );} }
        /// <summary>
        /// Scaling factor y
        /// </summary>
        public int SCALINGFACTORY { get { return GetValue( enumDeviceCapsConst.SCALINGFACTORY );} }
        public int LISTEN_OUTSTANDING{ get { return GetValue( enumDeviceCapsConst.LISTEN_OUTSTANDING );} }
        /// <summary>
        ///  Curve capabilities
        /// </summary>
        public int CURVECAPS{ get { return GetValue( enumDeviceCapsConst.CURVECAPS );} }
        /// <summary>
        /// Line capabilities
        /// </summary>
        public int LINECAPS{ get { return GetValue( enumDeviceCapsConst.LINECAPS );} }
        /// <summary>
        /// Polygonal capabilities
        /// </summary>
        public int POLYGONALCAPS { get { return GetValue( enumDeviceCapsConst.POLYGONALCAPS );} }
        /// <summary>
        /// Text capabilities
        /// </summary>
        public int TEXTCAPS { get { return GetValue( enumDeviceCapsConst.TEXTCAPS );} }

        #endregion

        #region 声明 Win32 API 函数及常量 *********************************************************

        [System.Runtime.InteropServices.DllImport("gdi32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)]
        private static extern int GetDeviceCaps(int hDC , int index );

        [System.Runtime.InteropServices.DllImport("User32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)]
        private static extern int ReleaseDC(int hWnd, int hDC);


        [System.Runtime.InteropServices.DllImport("gdi32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)]
        private static extern int CreateDC( string strDriver , string strDevice , int Output , int InitData );


        [System.Runtime.InteropServices.DllImport("gdi32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)]
        private static extern int DeleteDC( int Hdc );

        /// <summary>
        /// 为Win32API函数GetDeviceCaps的第二个参数配备的枚举变量
        /// </summary>
        private enum enumDeviceCapsConst
        {
            /// <summary>
            /// Device driver version
            /// </summary>
            DRIVERVERSION = 0      , 
            /// <summary>
            /// Device classification
            /// </summary>
            TECHNOLOGY = 2         , 
            /// <summary>
            /// Horizontal size in millimeters
            /// </summary>
            HORZSIZE = 4           , 
            /// <summary>
            ///  Vertical size in millimeters
            /// </summary>
            VERTSIZE = 6           , 
            /// <summary>
            ///  Horizontal width in pixels
            /// </summary>
            HORZRES = 8            , 
            /// <summary>
            /// Vertical width in pixels
            /// </summary>
            VERTRES = 10           , 
            /// <summary>
            /// Logical pixels/inch in X
            /// </summary>
            LOGPIXELSX = 88        , 
            /// <summary>
            /// Logical pixels/inch in Y
            /// </summary>
            LOGPIXELSY = 90        , 
            /// <summary>
            /// Number of planes
            /// </summary>
            PLANES = 14            , 
            /// <summary>
            /// Number of brushes the device has
            /// </summary>
            NUMBRUSHES = 16        , 
            /// <summary>
            /// Number of colors the device supports
            /// </summary>
            NUMCOLORS = 24         , 
            /// <summary>
            /// Number of fonts the device has
            /// </summary>
            NUMFONTS = 22          , 
            /// <summary>
            /// Number of pens the device has
            /// </summary>
            NUMPENS = 18           , 
            /// <summary>
            /// Length of the X leg
            /// </summary>
            ASPECTX = 40           , 
            /// <summary>
            /// Length of the hypotenuse
            /// </summary>
            ASPECTXY = 44          , 
            /// <summary>
            /// Length of the Y leg
            /// </summary>
            ASPECTY = 42           , 
            /// <summary>
            /// Size required for device descriptor
            /// </summary>
            PDEVICESIZE = 26       , 
            /// <summary>
            /// Clipping capabilities
            /// </summary>
            CLIPCAPS = 36          , 
            /// <summary>
            /// Number of entries in physical palette
            /// </summary>
            SIZEPALETTE = 104      , 
            /// <summary>
            /// Number of reserved entries in palette
            /// </summary>
            NUMRESERVED = 106      , 
            /// <summary>
            /// Actual color resolution
            /// </summary>
            COLORRES = 108         , 
            /// <summary>
            /// Physical Printable Area x margin
            /// </summary>
            PHYSICALOFFSETX = 112  , 
            /// <summary>
            /// Physical Printable Area y margin
            /// </summary>
            PHYSICALOFFSETY = 113  , 
            /// <summary>
            /// Physical Height in device units
            /// </summary>
            PHYSICALHEIGHT = 111   , 
            /// <summary>
            /// Physical Width in device units
            /// </summary>
            PHYSICALWIDTH = 110   , 
            /// <summary>
            /// Scaling factor x
            /// </summary>
            SCALINGFACTORX = 114   , 
            /// <summary>
            /// Scaling factor y
            /// </summary>
            SCALINGFACTORY = 115   , 
            LISTEN_OUTSTANDING = 1 ,
            /// <summary>
            ///  Curve capabilities
            /// </summary>
            CURVECAPS = 28         , 
            /// <summary>
            /// Line capabilities
            /// </summary>
            LINECAPS = 30          , 
            /// <summary>
            /// Polygonal capabilities
            /// </summary>
            POLYGONALCAPS = 32     , 
            /// <summary>
            /// Text capabilities
            /// </summary>
            TEXTCAPS = 34          , 
        }

        #endregion

        #region 内部私有成员 **********************************************************************

        private int[] intValues = null;

        private int GetValue( enumDeviceCapsConst CapsValue)
        {
            if( intValues == null)
                return int.MinValue ;
            for(int iCount = 0 ; iCount < intValues.Length ; iCount += 2 )
            {
                if( intValues[iCount] == Convert.ToInt32( CapsValue) )
                    return intValues[iCount+1];
            }
            return int.MinValue ;
        }

        #endregion

    }//public class DeviceCapsClass
}

posted on 2006-05-04 19:09  袁永福 电子病历,医疗信息化  阅读(5388)  评论(10编辑  收藏  举报

导航