由于内存释放问题,使用BitBlt方法会导致内存占用慢慢长大而不会被释放,使用普通的双缓冲没有这个问题,而且速度可以
由于是裁剪了部分代码,因此存在代码不完整的问题
Cementing.CurveSplit.DrawCurvePress  再memDC指向的位图(memBmp)上画压力曲线图,其它类似private Graphics memDC;      //屏幕外的图像
private Graphics clientDC;
private Bitmap memBmp;
private static SolidBrush backBrush;
#region DrawCurve BitBltprivate void DrawCurveBitBlt(int p_ScrollValue)
{
    try
    {
        if (m_RealTime == true)
        {
            mAL = Cementing.PortValues.AL;  //曲线图数据来源,mAL是System.Collections.ArrayList mAL
        }        if (memBmp == null)                                         //初始化要双缓冲的位图
        {
            memBmp = null;
            memBmp = new Bitmap(m_intWidth, m_intHeight);
        }
        else
        {
            if ((mWidthOld != m_intWidth) || (mHeightOld != m_intHeight))   //位图尺寸发生了变化
            {
                memBmp = null;
                mWidthOld = m_intWidth;
                mHeightOld = m_intHeight;
                memBmp = new Bitmap(m_intWidth, m_intHeight);
            }
        }        clientDC = this.CreateGraphics();   //获取绘图区的Graphics        IntPtr hdc = clientDC.GetHdc();
        IntPtr memdc = Win32Support.CreateCompatibleDC(hdc);
        Win32Support.SelectObject(memdc, memBmp.GetHbitmap());
        memDC = Graphics.FromHdc(memdc);
        double pWidth = (double)(m_intWidth - m_H) / (double)m_WidthRange;
        double pHeight = (double)(m_intHeight - m_V) / (double)m_HeightRange;        memDC.FillRectangle(Brushes.White, 0, 0, m_intWidth, m_intHeight);        switch (m_intType)
        {
            case 1:
                SetScrollBar();
                Cementing.CurveSplit.DrawCurvePress(memDC, p_ScrollValue, mAL, mPen, backBrush, m_intWidth, m_intHeight);
                break;
            case 2:
                SetScrollBar();
                Cementing.CurveSplit.DrawCurvePressDif(memDC, p_ScrollValue, mAL, mPen, backBrush, m_intWidth, m_intHeight);
                break;
            case 3:
                SetScrollBar();
                Cementing.CurveSplit.DrawCurveRate(memDC, p_ScrollValue, mAL, mPen, backBrush, m_intWidth, m_intHeight);
                break;
            case 4:
                SetScrollBar();
                Cementing.CurveSplit.DrawCurveTemperature(memDC, p_ScrollValue, mAL, mPen, backBrush, m_intWidth, m_intHeight);
                break;
        }        IntPtr hMemdc = memDC.GetHdc();
        Win32Support.BitBlt(hdc, 0, 0, m_intWidth, m_intHeight, hMemdc, 0, 0, Win32Support.TernaryRasterOperations.SRCCOPY);        clientDC.ReleaseHdc(hdc);
        memDC.ReleaseHdc(hMemdc);    }
    catch (NullReferenceException NullEx)
    {
        throw NullEx;
    }
    catch (Exception ex)
    {
        throw ex;
    }}#endregion DrawCurve BitBlt#region DrawCurveprivate void DrawCurve(int p_ScrollValue)
{
    try
    {
        if (m_RealTime == true)
        {
            mAL = Cementing.PortValues.AL;  //曲线图数据来源,mAL是System.Collections.ArrayList mAL
        }        if (memBmp == null)                                         //初始化要双缓冲的位图
        {
            memBmp = null;
            memBmp = new Bitmap(m_intWidth, m_intHeight);
        }
        else
        {
            if ((mWidthOld != m_intWidth) || (mHeightOld != m_intHeight))
            {
                memBmp = null;
                mWidthOld = m_intWidth;
                mHeightOld = m_intHeight;
                memBmp = new Bitmap(m_intWidth, m_intHeight);
            }
        }        memDC = Graphics.FromImage(memBmp);
        memDC.Clear(Color.White);
        backBrush = new SolidBrush(Color.White);
        memDC.FillRectangle(backBrush, 0, 0, m_intWidth, m_intHeight);        switch (m_intType)
        {
            case 1:
                SetScrollBar();
                Cementing.CurveSplit.DrawCurvePress(memDC, p_ScrollValue, mAL, mPen, backBrush, m_intWidth, m_intHeight);
                break;
            case 2:
                SetScrollBar();
                Cementing.CurveSplit.DrawCurvePressDif(memDC, p_ScrollValue, mAL, mPen, backBrush, m_intWidth, m_intHeight);
                break;
            case 3:
                SetScrollBar();
                Cementing.CurveSplit.DrawCurveRate(memDC, p_ScrollValue, mAL, mPen, backBrush, m_RealTime, m_intWidth, m_intHeight);
                break;
            case 4:
                SetScrollBar();
                Cementing.CurveSplit.DrawCurveTemperature(memDC, p_ScrollValue, mAL, mPen, backBrush, m_intWidth, m_intHeight);
                break;
        }        clientDC = this.CreateGraphics();
        clientDC.DrawImage(memBmp, 0, 0);
    }
    catch (NullReferenceException NullEx)
    {
        throw NullEx;
    }
    catch (Exception ex)
    {
        throw ex;
    }}#endregion DrawCurve

解决方案 »

  1.   

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.InteropServices;namespace Cementing
    {
        class Win32Support
        {
            /// <summary>
            /// Enumeration to be used for those Win32 function that return BOOL
            /// </summary>
            public enum Bool
            {
                False = 0,
                True
            };        /// <summary>
            /// Enumeration for the raster operations used in BitBlt.
            /// In C++ these are actually #define. But to use these
            /// constants with C#, a new enumeration type is defined.
            /// </summary>
            public enum TernaryRasterOperations
            {
                SRCCOPY = 0x00CC0020, /* dest = source                   */
                SRCPAINT = 0x00EE0086, /* dest = source OR dest           */
                SRCAND = 0x008800C6, /* dest = source AND dest          */
                SRCINVERT = 0x00660046, /* dest = source XOR dest          */
                SRCERASE = 0x00440328, /* dest = source AND (NOT dest )   */
                NOTSRCCOPY = 0x00330008, /* dest = (NOT source)             */
                NOTSRCERASE = 0x001100A6, /* dest = (NOT src) AND (NOT dest) */
                MERGECOPY = 0x00C000CA, /* dest = (source AND pattern)     */
                MERGEPAINT = 0x00BB0226, /* dest = (NOT source) OR dest     */
                PATCOPY = 0x00F00021, /* dest = pattern                  */
                PATPAINT = 0x00FB0A09, /* dest = DPSnoo                   */
                PATINVERT = 0x005A0049, /* dest = pattern XOR dest         */
                DSTINVERT = 0x00550009, /* dest = (NOT dest)               */
                BLACKNESS = 0x00000042, /* dest = BLACK                    */
                WHITENESS = 0x00FF0062, /* dest = WHITE                    */
            };        /// <summary>
            /// CreateCompatibleDC
            /// </summary>
            [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
            public static extern IntPtr CreateCompatibleDC(IntPtr hDC);        /// <summary>
            /// DeleteDC
            /// </summary>
            [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
            public static extern Bool DeleteDC(IntPtr hdc);        /// <summary>
            /// SelectObject
            /// </summary>
            [DllImport("gdi32.dll", ExactSpelling = true)]
            public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);        /// <summary>
            /// DeleteObject
            /// </summary>
            [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
            public static extern Bool DeleteObject(IntPtr hObject);        /// <summary>
            /// CreateCompatibleBitmap
            /// </summary>
            [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
            public static extern IntPtr CreateCompatibleBitmap(IntPtr hObject, int width, int height);        /// <summary>
            /// BitBlt
            /// </summary>
            [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
            public static extern Bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjSource, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);
        }
    }
      

  2.   

    在VS2005里双缓冲技术做的最好了,
    参见VS2005的MSDN:使用双缓冲 或双缓冲图形部分,
    或 
    如何:手动管理缓冲图形 
      

  3.   

    在VS2005里双缓冲技术做的最好了,
    参见VS2005的MSDN:使用双缓冲 或双缓冲图形部分,
    或 
    如何:手动管理缓冲图形 
    测试了,这个方法没有我的方法顺滑,不过如果当时我就发现可以调用这个的话,就不会去写双缓冲了