在我的程序中引用了一个别人提供的类:CxSkinButton,这个类可以根据Button的状态显示不同的位图,是非常不错的一个类。但最近发现这个类显示位图存在内存泄漏的问题,通常程序运行了几十分钟后会报错,跟进去发现就是这个类中显示位图的地方出的错。通常vc里显示位图都需要先创建一个内存设备环境CreateCompatibleDC
,发现就是这个地方失败了,就是返回值是0。这种情况只会在程序运行了较长一段时间才会出现。我觉得可能出现内存泄漏的地方有下面几个:
1、每次CreateCompatibleDC后没用DeleteDC释放,长此反复可能不行。
2、每次SelectObject后返回当前Bitmap的句柄,后来没有SelectObject回去,这里我已经做了修改,正在测试。
不知道上面的看法对不对。另外我还有两个疑问:
1、每次CreateCompatibleDC是不是一定要用DeleteDC释放?CreateCompatibleDC能不能只做一次,不要每次显示的时候都Create一次
2、GetDC后是不是一定要用ReleaseDC释放?
请各位说说自己的看法,一并感谢!
,发现就是这个地方失败了,就是返回值是0。这种情况只会在程序运行了较长一段时间才会出现。我觉得可能出现内存泄漏的地方有下面几个:
1、每次CreateCompatibleDC后没用DeleteDC释放,长此反复可能不行。
2、每次SelectObject后返回当前Bitmap的句柄,后来没有SelectObject回去,这里我已经做了修改,正在测试。
不知道上面的看法对不对。另外我还有两个疑问:
1、每次CreateCompatibleDC是不是一定要用DeleteDC释放?CreateCompatibleDC能不能只做一次,不要每次显示的时候都Create一次
2、GetDC后是不是一定要用ReleaseDC释放?
请各位说说自己的看法,一并感谢!
奇怪的是:
HINSTANCE hSkinDll = LoadLibrary(".\\SkinImg.Dll");
FreeLibrary(hSkinDll);
这样两句倒会有泄露:
Resource leak: allocated by LoadLibraryA in dllinit.cpp (505), HANDLE: 0x62170000
Location of Error
DllMain dllinit.cpp 505
共享一下。
这是.h文件
#if !defined(AFX_MYB_H__3832DDEF_0C12_11D5_B6BE_00E07D8144D0__INCLUDED_)
#define AFX_MYB_H__3832DDEF_0C12_11D5_B6BE_00E07D8144D0__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// CxSkinButton.h : header file
/** 15/03/2001 v1.00
* [email protected]
** 29/03/2001 v1.10
* [email protected]
* - mouse tracking
** 02/04/2001 v1.20
* [email protected]
* - new CreateRgnFromBitmap
** 14/04/2001 v1.21
* - OnMouseLeave cast fixed
* - Over bitmap consistency check
** 25/04/2001 v1.30
* [email protected]
* - ExtCreateRegion replacement
*//////////////////////////////////////////////////////////////////////////////
// CxSkinButton window
//默认为普通按钮,否则是两种状态的按钮
enum BUTTONTYPE {NORMAL_BUTTON,SUPER_BUTTON};
//状态。在SUPER_BUTTON按钮的时候使用
enum BUTTONSTATE{NORMAL_STATE,PUSHED_STATE};
class CxSkinButton : public CButton
{
// Construction
public:
CxSkinButton();// Attributes
private:// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CxSkinButton)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
protected:
//}}AFX_VIRTUAL
// Implementation
public:
HBITMAP LoadImage(LPCSTR lpStrName);//load file from a file.
void DeleteObject(HBITMAP hBitmap);//
void SetToolTipText(CString s);
COLORREF SetTextColor(COLORREF new_color);
// void SetSkin(UINT normal,UINT down, UINT over=NULL, UINT disabled=NULL,UINT mask=NULL,
// short drawmode=1,short border=1,short margin=4);
void SetSkin(char *NormalName,char *DownName,char *OverName=NULL,char *DisabledName=NULL,char *MaskName=NULL,
short drawmode=1,short border=1,short margin=4);
void SetSkin(UINT normal,UINT down,UINT over=NULL,UINT disabled=NULL,UINT mask=NULL,
short drawmode=1, short border=1, short margin=4);
//两个状态的按钮 按一下凹下,再按一下弹起
BUTTONSTATE m_uState;//0---Normal 1---Down
void SetSuperButtonState(BUTTONSTATE state);
BUTTONSTATE GetSuperButtonState();
BUTTONTYPE m_btType;
//设置按钮的类型
void SetType(BUTTONTYPE type);
BUTTONTYPE GetType();
virtual ~CxSkinButton();
// Generated message map functions
protected:
bool m_tracking;
bool m_button_down;
void RelayEvent(UINT message, WPARAM wParam, LPARAM lParam);
CToolTipCtrl m_tooltip;
// CBitmap m_bNormal,m_bDown,m_bDisabled,m_bMask,m_bOver; //skin bitmaps
HBITMAP m_hNormal,m_hDown,m_hDisabled,m_hMask,m_hOver; //skin bitmaps
short m_FocusRectMargin; //dotted margin offset
COLORREF m_TextColor; //button text color
HRGN hClipRgn; //clipping region
BOOL m_Border; //0=flat; 1=3D;
short m_DrawMode; //0=normal; 1=stretch; 2=tiled;
HRGN CreateRgnFromBitmap(HBITMAP hBmp, COLORREF color);
void FillWithBitmap(CDC* dc, HBITMAP hbmp, RECT r);
void DrawBitmap(CDC* dc, HBITMAP hbmp, RECT r, int DrawMode);
int GetBitmapWidth (HBITMAP hBitmap);
int GetBitmapHeight (HBITMAP hBitmap); //{{AFX_MSG(CxSkinButton)
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg BOOL OnClicked();
afx_msg LRESULT OnMouseLeave(WPARAM, LPARAM);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MYB_H__3832DDEF_0C12_11D5_B6BE_00E07D8144D0__INCLUDED_)