本帖最后由 VisualEleven 于 2012-11-18 12:09:47 编辑

解决方案 »

  1.   

    m_hdcMem.SelectObject(&m_hBitmap);
    m_hdcMem.SelectObject(&m_font); //使用大字体
    需要将原值保留,退出时复原
      

  2.   

    你没有用多线程或者timeSetEvent()函数吧,因为DC是稀缺资源,同时申请可能不够用.
      

  3.   

    后台是个线程获取各个点的数据,通过一个timer循环对每个Static进行SetWindowText操作
    现在发现,时间长了之后,调试发现m_hdcMem中有个hDC(DC的指针=0x000000000)...问题是BitBlt屏蔽后为什么就不会吃掉内存了啊?我的内存释放有没有问题啊?
    刷新的机制没有进行延时,循环体直接是一个接一个,没有延时,不过
    在刷新内部有对数据的判断,有几十行的代码吧
      

  4.   

    if (m_hdcMem.CreateCompatibelDC(NULL
    为什么不是 dc ?
      

  5.   

    选入的位图和字体  试过都重新Select回去,还是一样的结果schlafenhamster:
    如果使用m_hdcMem.CreateCompatibelDC(dc)也是一样的结果 
      

  6.   

    BOOL ret=m_hBitmap.DeleteObject();
    看看是不是真的。
      

  7.   

    SelectObject选择对象之后一个返回资源指针(上一次的资源指针)。在结束的时候需要重新SelectObject这个资源指针。就是所谓的还原这样才不会出现楼主所说的问题。
      

  8.   

    CDC m_hdcMem;
    CBitmap m_hBitmap;
    都是类成员?换成局部变量试试
      

  9.   

    tiger:
    重新选入老的字体和图片都测试过的,还是有问题的。schlafenhamster:
    嗯,下午去办公室试试,还有其他的函数都看看是不是正常返回
    看有什么问题没有mcmcmc :
    是在OnPaint里面定义的局部变量
      

  10.   

    你不SelectObject原来的,你的这个操作m_hBitmap.DeleteObject();应该会调用失败
      

  11.   

    完整代码
    CPaintDC dc(this)
      

  12.   

    额……手机上发不完
    就是按照几位说的将选出的在bitblt后重新选入
    然后bmp.deleteobject
    m_hdcmem,deletedc
    最后releasedc(&dc)
    程序下载到wince板子后
    用远程堆查看器看,发现堆一直增长
    标记为fixed为大多数
    在两个delete加变量接收结果都是true
      

  13.   

    “最后releasedc(&dc)”
    你把 CPaintDC release 了 ?
    不要的吧
      

  14.   

    难道是bug?
    http://support.microsoft.com/kb/318622/en-us
      

  15.   

    还有
    http://support.microsoft.com/kb/819635/en-ushttp://www.bluemcu.com/designstrategy/2011/1/6/111526_89.html
      

  16.   

    如果是微软bug,用
    hDC = ::GetDC (m_hWnd);
    CPaintDC::FromHandle(hDC)
    不要用
    CPaintDC dc(this),后者调用bug代码
      

  17.   

    好像也不是,看了CPaintDC(CWnd*)源码,也是hwnd调用,可能其他地方有什么问题.
      

  18.   

    我试了下
    改成这种方式后会一直循环调用onpaint,界面死在那儿了。
      

  19.   

    CPaintDC::FromHandle(hDC)
    改成
    CPaintDC::Attach(hDC)不过估计也没有大用方法不对,照理也不会频繁调用OnPaint(),只有WM_PAINT才会,是不是多线程SetWindowText()引起的? 如果可能work thread最好不要碰GUI函数.还有最后一条路就是不用CDC,全部SDK
      

  20.   

    有人说是SetWindowText的问题。
    我试了下,换成用updatedata的方式更新 
    onPaint这里面完善了下
    {
    CPaintDC dc(this);
    CDC m_hdcMem;
    CBitmap m_hBitmap; 
    if (m_hdcMem.CreateCompatibelDC(NULL) == 0)
    {
        m_hdcMem.DeleteDC();
        return;

    CRect rect;
     
    GetClientRect(&rect);
     
    if (m_hBitmap.CreateCompatibleBitmap(&dec, Rect.Width() + 1, rect.Height() + 1) == 0)
    {
        m_hBitmap.DeleteObject();
        m_hdcMem.DeleteDC();
        return;
    }
     
    CBitmap *m_oldBMP = m_hdcMem.SelectObject(&m_hBitmap);
     
    CString strText = _T("");
    GetWindowText(strText);
    ....
     
    m_hdcMem.FillRect(&rect, m_pBrush);//填充黑色
    CFont *m_OldFont = m_hdcMem.SelectObject(&m_font); //使用大字体
    m_hdcMem.SetTextColor(m_rgbText);
    m_hdcMem.SetBkMode(TRANSPARENT);
    m_hdcMem.DrawText(strText, rect, nFormat); 
    //nFormat是设置文字左中右的,用的DWORD dwStyle = GetStyle()
     
    dc.BitBlt(0, 0, rect.Width(), rect.Height(), &m_hdcMem, 0, 0, SRCCOPY);
     
    m_hdcMem.SelectObject(m_OldFont);
    m_hdcMem.SelectObject(m_OldBMP);m_hBitmap.DeleteObject();
    m_hdcMem.DeleteDC();
    }
    内存泄露明显少了很多 
    但是还是有 
    天啦。。
      

  21.   

    可以将m_hdcMem,m_hBitmap变成类成员变量,因为它们并不消耗DC资源,不用每次都建立删除,在OnCreate()的时候建立一下,析构或者OnDestroy()的时候删除,在OnPaint()的时候
    m_hdcMem.DrawText(strText, rect, nFormat); 
    dc.BitBlt(0, 0, rect.Width(), rect.Height(), &m_hdcMem, 0, 0, SRCCOPY);
    甚至可以缓存几套hdcMem,一套用于正常字体,一套用于异常字体,这样SelectObject()也不用每次做了.
      

  22.   

    现在在类里面增加了要显示的TXT变量和一个类函数SHOWTEXT
    将OnPaint中的GetWindowText去掉,和TXT变量联系起来进行写DC
    在SHOWTEXT中接收并修改TXT变量
    调用Invalidate(FALSE)强制刷新界面,就没有泄露了
    但是如果调用Invalidate(TRUE)就还有泄露。
    不知道为什么,有谁知道吗?PS
    在WIN32环境下用同样的类,
    SetWindowText发现居然不显示带色的大字体,还是显示的默认的字体和颜色
    调试发现完全就没有调用OnPaint。
    用其他窗口遮盖后,引起界面刷新就可以看到Paint后的界面了,不过马上又回到默认了那就是说SetWindowText在WinCE和Win32下的机制是不同的?
    还是说所有的问题都是VS 2008的问题?
    弄个EVC或VS2005之类的在试试
      

  23.   

    应该是m_hdcMem.SelectObject(&m_hBitmap); 这个丢的,这个你没有还原回去,删除不掉的
    CBitMap *old = m_hdcMem.SelectObject(&m_hBitmap); 
    ......
    m_hdcMem.SelectObject(old ); 
    m_hdcMem.DeleteObject();
      

  24.   

    InvalidateRect()如何?估计还是程序内部问题,多线程之间传递消息有不干净的内存,并且在windows消息中传播.还有有些字体不是所有系统都支持,比如在win7下有些字体会是乱码...
      

  25.   

    我现在是单独的一个小程序,仅仅只实现用Timer 
    在timr中Random数据,然后显示到文本控件中还有程序是都选入、选出了的了。开头的双缓冲程序是有点问题的,后来我改了
      

  26.   

    这个类的代码如下
    .h// ColorStatic.h ///////////////////////////////////////////////////////////////////////////////
    #ifndef COLORSTATIC_H
    #define COLORSTATIC_H/////////////////////////////////////////////////////////////////////////////
    // CColorStatic windowclass CColorStatic : public CStatic
    {
    // Construction
    public:
    CColorStatic();
    virtual ~CColorStatic();// Attributes
    public: void SetBackgroundColor(COLORREF rgb, BOOL bRedraw = TRUE);
    void SetTextColor(COLORREF rgb, BOOL bRedraw = TRUE);
    void SetFont(LPCTSTR lpszFaceName, int nPointSize);
    void SetTrans(bool bTranslate);
    void ShowText(LPCTSTR sText);
    void SetAlign(DWORD dAlign);// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CColorStatic)
    protected:
     //   virtual void PreSubclassWindow();
    //}}AFX_VIRTUAL// Implementation
    protected:
    COLORREF m_rgbText;
    COLORREF m_rgbBackground;
    BOOL m_bBold;
    BOOL m_bTrans;
    int m_iFontSize;
    CString m_ShowText;
    DWORD m_Align; //SS_CENTER SS_LEFT SS_RIGHT
    LPCTSTR m_sFontName; int GetFontHeight(int nPointSize);
    // Generated message map functions
    protected:
    //{{AFX_MSG(CColorStatic)
    afx_msg void OnPaint();
    afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    //}}AFX_MSG DECLARE_MESSAGE_MAP()
    };///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif //COLORSTATIC_H
      

  27.   

    .cpp// ColorStatic.cpp  Version 1.0
    ///////////////////////////////////////////////////////////////////////////////#include "stdafx.h"
    #include "ColorStatic.h"#ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif///////////////////////////////////////////////////////////////////////////////
    // CColorStatic
    BEGIN_MESSAGE_MAP(CColorStatic, CStatic)
    //{{AFX_MSG_MAP(CColorStatic)
    ON_WM_PAINT()
    ON_WM_ERASEBKGND()
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()///////////////////////////////////////////////////////////////////////////////
    // constructor
    CColorStatic::CColorStatic()
    {
    m_rgbText       = GetSysColor(COLOR_BTNTEXT);
    m_rgbBackground = GetSysColor(COLOR_BTNFACE);
    m_bBold         = FALSE;
    m_ShowText = _T("");
    m_bTrans = TRUE;
    m_Align = SS_CENTER;
    }///////////////////////////////////////////////////////////////////////////////
    // destructor
    CColorStatic::~CColorStatic()
    {
    TRACE(_T("in CColorStatic::~CColorStatic\n"));}///////////////////////////////////////////////////////////////////////////////
    // OnPaint
    void CColorStatic::OnPaint() 
    {
    CPaintDC dc(this);       // device context for painting
    CDC m_hdcMem;
    CBitmap m_hBitmap;
    CFont m_font;
    CBrush m_Brush;
    CString sShowText; if (m_hdcMem.CreateCompatibleDC(NULL) == 0) //Create Fail
    {
    //m_hdcMem.DeleteDC();
    return;
    } CRect rect;
    GetClientRect(&rect);  if (m_hBitmap.CreateCompatibleBitmap(&dc ,rect.Width(), rect.Height()) == 0) //Create Fail
    {
    //m_hBitmap.DeleteObject();
    m_hdcMem.DeleteDC();
    return;
    }
    if (!m_font.CreateFont(m_iFontSize, 0, 0, 0, 0, FALSE, FALSE, 0, 
    GB2312_CHARSET, 0, 0, 0, 0, m_sFontName)) //Create Fail
    {
    m_hBitmap.DeleteObject();
    m_hdcMem.DeleteDC();
    return;
    }
    if (!m_Brush.CreateSolidBrush(m_rgbBackground)) //Create Fail
    {
    m_font.DeleteObject();
    m_hBitmap.DeleteObject();
    m_hdcMem.DeleteDC();
    return;
    }

    CBitmap *m_OldBMP = m_hdcMem.SelectObject(&m_hBitmap);
    CFont * m_OldFont = m_hdcMem.SelectObject(&m_font); GetWindowText(sShowText);
    UINT nFormat = 0; if ((m_Align & SS_CENTER) >0)
    nFormat |= DT_CENTER;
    else if ((m_Align & SS_LEFT) > 0)
    nFormat |= DT_LEFT;
    else if ((m_Align & SS_RIGHT) > 0)
    nFormat |= DT_RIGHT;
    nFormat |= DT_VCENTER | DT_SINGLELINE; m_hdcMem.FillRect(&rect, &m_Brush);//fill
    m_hdcMem.SetTextColor(m_rgbText);
    m_hdcMem.SetBkMode(TRANSPARENT);
    if (!m_ShowText.IsEmpty()) //Choose Text
    m_hdcMem.DrawText(m_ShowText, rect, nFormat);
    else
    m_hdcMem.DrawText(sShowText, rect, nFormat);

    //Copy mem
    dc.BitBlt(0,0,rect.Width() , rect.Height() ,&m_hdcMem,0,0,SRCCOPY);

    m_hdcMem.SelectObject(m_OldBMP);
    m_hdcMem.SelectObject(m_OldFont); m_hBitmap.DeleteObject();
    m_font.DeleteObject();
    m_Brush.DeleteObject();
    m_hdcMem.DeleteDC();

    //ReleaseDC(&dc);
    }// OnEraseBkgnd
    BOOL CColorStatic::OnEraseBkgnd(CDC* pDC) 
    {
    //   CRect cr;
    //   GetClientRect(cr); 
    //  pDC->FillRect(&cr, m_pBrush); return TRUE; //CStatic::OnEraseBkgnd(pDC);//
    }//Set Text
    void CColorStatic::ShowText(LPCTSTR sText)
    {
    m_ShowText = sText; Invalidate(FALSE);
    }//Set Align
    void CColorStatic::SetAlign(DWORD dAlign)
    {
    m_Align = dAlign;
    }//Set Font
    void CColorStatic::SetFont(LPCTSTR lpszFaceName, int nPointSize)
    {
    /*
    if (m_font.GetSafeHandle())
    m_font.DeleteObject();
    m_font.CreateFont(
    GetFontHeight(nPointSize),
    0, 0, 0, 0, FALSE, FALSE,
    0, GB2312_CHARSET, 0,
    0, 0, 0, lpszFaceName);
    */
    m_iFontSize = GetFontHeight(nPointSize);
    m_sFontName = lpszFaceName;
    }//Set TextColor
    void CColorStatic::SetTextColor(COLORREF rgb, BOOL bRedraw /*= TRUE*/) 

    m_rgbText = rgb; 
    if (bRedraw)
    RedrawWindow();
    }
    //Set BackgroundColor
    void CColorStatic::SetBackgroundColor(COLORREF rgb, BOOL bRedraw /*= TRUE*/) 

    m_rgbBackground = rgb; 

    if (bRedraw)
    RedrawWindow();
    }//Set Trans
    void CColorStatic::SetTrans(bool bTranslate)
    {
    m_bTrans = bTranslate; 
    }//Get FontHeight
    int CColorStatic::GetFontHeight(int nPointSize)
    {
    HDC hdc = ::CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
    ASSERT(hdc);
    int cyPixelsPerInch = ::GetDeviceCaps(hdc, LOGPIXELSY);
    ::DeleteDC(hdc); int nHeight = -::MulDiv(nPointSize, cyPixelsPerInch, 72); return nHeight;
    }
      

  28.   

    如果你的控件在普通计算机上没有泄露,估计是MFC WinCE版的bug,你还是用HDC吧
    http://blog.csdn.net/aristolto/article/details/7416302
      

  29.   

    嗯,看了很多地方,该是Wince的问题吧,我试了VS2005 VS2008都有这个问题