CMFCToolBar 中频繁调用AdjustLayout()函数存在严重内存泄露,求大神帮助!

zhouxiaofeng1021 2014-02-26 05:59:40
在CMFCToolBar 的AdjustLayout()函数频繁调用存在严重内存泄露!
经测试发现
AdjustSize();//有内泄露
AdjustLocations();//有严重内存泄露

函数声明:
void CMFCToolBar::AdjustSize();
void CMFCToolBar::AdjustLocations();

代码中设定定时器不停地调用:
	nIndex = m_wndToolBar.CommandToIndex(ID_OBJECT_TESTTIME);
if (nIndex >= 0)
{
m_wndToolBar.SetToolBarBtnText(nIndex, strTimeInfo, TRUE, TRUE);
}

m_wndToolBar.AdjustLayout();


相关定义:
CTestProgressToolBar m_wndToolBar;//这个在我的类里面

class CTestProgressToolBar : public CMFCToolBar
{
virtual void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
{
CMFCToolBar::OnUpdateCmdUI((CFrameWnd*) GetOwner(), bDisableIfNoHndler);
}

virtual BOOL AllowShowOnList() const { return FALSE; }
}


总之,不停地调用AdjustLayout()会有严重内存泄露!

网上说Create和CreateEx会有内存问题,按照网上说的试了没有效果!依旧内存泄露!
// 加载工具栏:
m_wndToolBar.Create(this,
WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC | CBRS_FLOATING,
IDR_TOOLBAR_TMSSVIEW);
m_wndToolBar.LoadToolBar(IDR_TOOLBAR_TMSSVIEW, 0, IDR_TOOLBAR_TMSSVIEW, TRUE, 0, 0, IDR_TOOLBAR_TMSSVIEW);
...全文
807 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhouxiaofeng1021 2014-08-08
  • 打赏
  • 举报
回复
// //采用stack实现 BOOL DeleteFileofDirectory(CString strPath) { stack<CString> folderList; CString filepath; CString filename; if(!RemoveDirectory(strPath)) { folderList.push(strPath); WIN32_FIND_DATA FindFileData; HANDLE hFind = INVALID_HANDLE_VALUE; while (folderList.size() > 0) { CString tempPath = folderList.top(); CString tempfile =tempPath + _T("\\*"); ::PostMessage(theApp.m_pMainWnd->m_hWnd,WM_DLG_PROCESS_SHOW,0L, (LPARAM)(LPCTSTR)tempPath); if (RemoveDirectory(tempPath)) { folderList.pop(); continue; } // Find the first file in the directory. hFind = FindFirstFile(tempfile, &FindFileData); //Is directory ? if( (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && wcscmp(FindFileData.cFileName, _T(".")) && wcscmp(FindFileData.cFileName, _T("..")) ) { filepath = tempPath + _T("\\") + FindFileData.cFileName; folderList.push(filepath); } else if( wcscmp(FindFileData.cFileName, _T(".")) && wcscmp(FindFileData.cFileName, _T("..")) ) { filename = tempPath + _T("\\") + FindFileData.cFileName; DeleteFile(filename); } while (FindNextFile(hFind, &FindFileData)) { //Is directory ? if(wcscmp(FindFileData.cFileName, _T(".")) && wcscmp(FindFileData.cFileName, _T(".."))) { if( (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { filepath = tempPath + _T("\\") + FindFileData.cFileName; folderList.push(filepath); } else { filename = tempPath + _T("\\") + FindFileData.cFileName; DeleteFile(filename); } } } FindClose(hFind); } return TRUE; } return TRUE; }
zhouxiaofeng1021 2014-08-08
  • 打赏
  • 举报
回复
//BOOL DeleteFileofDirectory(CString strPath) //{ // WIN32_FIND_DATA FindFileData; // HANDLE hFind = INVALID_HANDLE_VALUE; // CString tempPath = _T(""); // CString strFileName = _T(""); // CString strDIR = strPath; // tempPath = strDIR + _T("\\*"); // // ::PostMessage(theApp.m_pMainWnd->m_hWnd,WM_DLG_PROCESS_SHOW,0L, (LPARAM)(LPCTSTR)strPath); // // // Find the first file in the directory. // hFind = FindFirstFile(tempPath, &FindFileData); // //Is directory ? // if( (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) // && wcscmp(FindFileData.cFileName, _T(".")) && wcscmp(FindFileData.cFileName, _T("..")) ) // { // strDIR = strPath + _T("\\") + FindFileData.cFileName; // DeleteFileofDirectory(strPath); // } // else if( wcscmp(FindFileData.cFileName, _T(".")) && wcscmp(FindFileData.cFileName, _T("..")) ) // { // strFileName = strPath + _T("\\") + FindFileData.cFileName; // DeleteFile(strFileName); // } // //// BOOL bSearchFinished = FALSE; // //循环删除 //// while (!bSearchFinished) //// { //// if (FindNextFile(hFind, &FindFileData)) // while (FindNextFile(hFind, &FindFileData)) // { // //Is directory ? // if( (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) // && wcscmp(FindFileData.cFileName, _T(".")) && wcscmp(FindFileData.cFileName, _T("..")) ) // { // strDIR = strPath + _T("\\") + FindFileData.cFileName; // DeleteFileofDirectory(strDIR); // } // else if( wcscmp(FindFileData.cFileName, _T(".")) && wcscmp(FindFileData.cFileName, _T("..")) ) // { // strFileName = strPath + _T("\\") + FindFileData.cFileName; // DeleteFile(strFileName); // } //* } */ //// else //// { //// if( GetLastError() == ERROR_NO_MORE_FILES ) //Normal Finished //// { //// bSearchFinished = TRUE; //// //// } //// else //// bSearchFinished = TRUE; //Terminate Search //// //// } // strDIR = strPath; // strFileName = _T(""); // } //// FindClose(hFind); //// hFind = FindFirstFile(strPath, &FindFileData); //// //检测目录是否存在 //// if ((hFind != INVALID_HANDLE_VALUE) && (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) //// { //// // 删除根目录 //// if(!RemoveDirectory(strPath)) //// { //// LPVOID lpMsgBuf; //// LPVOID lpDisplayBuf; //// DWORD dw = GetLastError(); //// //// FormatMessage( //// FORMAT_MESSAGE_ALLOCATE_BUFFER | //// FORMAT_MESSAGE_FROM_SYSTEM | //// FORMAT_MESSAGE_IGNORE_INSERTS, //// NULL, //// dw, //// MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //// (LPTSTR) &lpMsgBuf, //// 0, NULL ); //// //// // Display the error message and exit the process //// //// lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, //// (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen(_T("RemoveDirectory"))+40)*sizeof(TCHAR)); //// StringCchPrintf((LPTSTR)lpDisplayBuf, //// LocalSize(lpDisplayBuf), //// TEXT("RemoveDirectory failed with error %d: %s"), //// dw, lpMsgBuf); //// MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); //// FindClose(hFind); //// return FALSE; //// } //// FindClose(hFind); //// return TRUE; //// //// } // FindClose(hFind); // return RemoveDirectory(strPath); //// // 文件查找对象 //// CFileFind tempFind; //// //// // 查找并递归删除文件夹下的文件和文件夹 //// CString strTempFileFind = strPath + _T("\\*.*"); //// BOOL IsFinded = tempFind.FindFile(strTempFileFind); //// while (IsFinded) //// { //// IsFinded = tempFind.FindNextFile(); //// //// if (!tempFind.IsDots()) //// { //// CString strFound = strPath + _T("\\") + tempFind.GetFileName(); //// //// if (tempFind.IsDirectory()) //// { //// // 递归调用删除子文件夹 //// DeleteFileofDirectory(strFound); //// } //// else //// { //// // 删除文件 //// DeleteFile(strFound); //// } //// } //// } //// tempFind.Close(); //// //// // 删除根目录 //// if(!RemoveDirectory(strPath)) //// { //// return FALSE; //// } //// return TRUE; //} //BOOL DeleteFileofDirectory(CString strPath) //{ // // 文件查找对象 // CFileFind tempFind; // // // 查找并递归删除文件夹下的文件和文件夹 // CString strTempFileFind = strPath + _T("\\*.*"); // BOOL IsFinded = tempFind.FindFile(strTempFileFind); // while (IsFinded) // { // IsFinded = tempFind.FindNextFile(); // // if (!tempFind.IsDots()) // { // CString strFound = strPath + _T("\\") + tempFind.GetFileName(); // // if (tempFind.IsDirectory()) // { // // 递归调用删除子文件夹 // DeleteFileofDirectory(strFound); // ::PostMessage(theApp.m_pMainWnd->m_hWnd,WM_DLG_PROCESS_SHOW,0L, (LPARAM)(LPCTSTR)strFound); // } // else // { // // 删除文件 // DeleteFile(strFound); // } // } // } // tempFind.Close(); // // // 删除根目录 // if(!RemoveDirectory(strPath)) // { // return FALSE; // } // return TRUE; // } // // BOOL DeleteFileofDirectory(CString strPath) // { // TCHAR path[MAX_PATH]; // wcscpy(path, strPath); // if(!RemoveDirectory(path)) // { // deque<wstring> delfiles; // deque<wstring> folderList; // folderList.push_back(wstring(path)); // wcscat(path,_T("\\*.*")); // delfiles.push_back(wstring(path)); // wstring filepath; // wstring filename; // // while(delfiles.size()>0) // { // WIN32_FIND_DATA fd; // wstring pathfile=delfiles.front(); // HANDLE hFind=FindFirstFile((LPCWSTR)pathfile.c_str(),&fd); // delfiles.pop_front(); // if(hFind!=INVALID_HANDLE_VALUE) // { // BOOL bWorking=TRUE; // while(bWorking) // { // bWorking=FindNextFile(hFind,&fd); // if((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && fd.cFileName[0] != '.') // { // filename=pathfile; // basic_string<TCHAR>::iterator _It=filename.begin()+filename.find(_T("\\*.*")); // filename.insert(_It++,'\\'); // filename.insert(_It-filename.begin(),fd.cFileName); // // WIN32_FIND_DATA fd2; // HANDLE hFound=FindFirstFile((LPCWSTR)filename.c_str(),&fd2); // if(hFound!=INVALID_HANDLE_VALUE) // { // BOOL aWorking=TRUE; // while(aWorking) // { // aWorking=FindNextFile(hFound,&fd2); // filepath=filename; // _It=filepath.begin()+filepath.find(_T("\\*.*")); // filepath.insert(_It++,'\\'); // // if((fd2.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && fd2.cFileName[0] != '.') // { // filepath.insert(_It-filepath.begin(),fd2.cFileName); // //delfiles.push_back(filepath); // folderList.push_back(filepath); // } // else if(!(fd2.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && fd2.cFileName[0] != '.') // { // filepath.replace(_It,filepath.end(),fd2.cFileName); // DeleteFile((LPCWSTR)filepath.c_str()); // ::PostMessage(theApp.m_pMainWnd->m_hWnd,WM_DLG_PROCESS_SHOW,0L, (LPARAM)(LPCTSTR)fd2.cFileName); // } // } // FindClose(hFound); // } // } // else if(!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && fd.cFileName[0] != '.') // { // wstring pathname=pathfile; // pathname.replace(pathname.find(_T("*.*")),3,fd.cFileName); // DeleteFile((LPCWSTR)pathname.c_str()); // ::PostMessage(theApp.m_pMainWnd->m_hWnd,WM_DLG_PROCESS_SHOW,0L, (LPARAM)(LPCTSTR)fd.cFileName); // } // } // FindClose(hFind); // } // } // // while(folderList.size()>0) // { // wstring folder=folderList.back(); // filepath=folder; // folder.erase(folder.find(_T("\\*.*")),folder.length()); // if(RemoveDirectory((LPCWSTR)folder.c_str())) // folderList.pop_back(); // else // { // WIN32_FIND_DATA fdata; // HANDLE hFind=FindFirstFile((LPCWSTR)filepath.c_str(),&fdata); // if(hFind!=INVALID_HANDLE_VALUE) // { // BOOL bWorking=TRUE; // while(bWorking) // { // bWorking=FindNextFile(hFind,&fdata); // if((fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && fdata.cFileName[0] != '.') // { // basic_string<TCHAR>::iterator it=filepath.begin()+filepath.find(_T("\\*.*")); // filepath.insert(it++,'\\'); // filepath.insert(it-filepath.begin(),fdata.cFileName); // folderList.push_back(filepath); // } // } // } // FindClose(hFind); // } // } // } // // return TRUE; // } // //
zhouxiaofeng1021 2014-08-08
  • 打赏
  • 举报
回复
// RelativePath.cpp: implementation of the CRelativePath class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "RelativePath.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CRelativePath::CRelativePath() { m_strExePathName = GetExeFilePathName(); m_strExePath = GetExeFilePath(); } CRelativePath::~CRelativePath() { } CString CRelativePath::GetExeFilePath() { CString strExePathName = GetExeFilePathName(); return strExePathName.Left(strExePathName.ReverseFind(_T('\\')) + 1); } CString CRelativePath::GetExeFilePathName() { CString strExePathName; GetModuleFileName(NULL, strExePathName.GetBuffer(MAX_PATH), MAX_PATH); strExePathName.ReleaseBuffer(); // 统一分隔符 strExePathName.Replace(_T('/'), _T('\\')); return strExePathName; } CString CRelativePath::GetRelativePath(CString strAbsolutePath) { return GetRelativePath(CRelativePath::GetExeFilePath(), strAbsolutePath); } CString CRelativePath::GetRelativePath(CString strRefPath, CString strAbsolutePath) { CString strRelativePath; // 统一分隔符 strRefPath.Replace(_T('/'), _T('\\')); strAbsolutePath.Replace(_T('/'), _T('\\')); // int iRefStart = 0, iAbsoluteStart = 0; int iRefEnd = strRefPath.Find(_T('\\')); int iAbsoluteEnd = strAbsolutePath.Find(_T('\\')); CString strRefDir = strRefPath.Left(iRefEnd); CString strAbsoluteDir = strAbsolutePath.Left(iAbsoluteEnd); // 盘符不同则绝对路径也是相对路径 if (strRefDir.CompareNoCase(strAbsoluteDir) != 0) { return strAbsolutePath; } // 逐级路径比较 while (strRefDir.CompareNoCase(strAbsoluteDir) == 0) { iRefStart = iRefEnd + 1; iAbsoluteStart = iAbsoluteEnd + 1; iRefEnd = strRefPath.Find(_T('\\'), iRefStart); iAbsoluteEnd = strAbsolutePath.Find(_T('\\'), iAbsoluteStart); if ((iAbsoluteEnd == -1) || (iRefEnd == -1)) { break; } strRefDir = strRefPath.Mid(iRefStart, iRefEnd - iRefStart); strAbsoluteDir = strAbsolutePath.Mid(iAbsoluteStart, iAbsoluteEnd - iAbsoluteStart); } while (iRefEnd != -1) { iRefStart = iRefEnd + 1; iRefEnd = strRefPath.Find(_T('\\'), iRefStart); strRelativePath += _T("..\\"); } strRelativePath += strAbsolutePath.Right(strAbsolutePath.GetLength() - iAbsoluteStart); return strRelativePath; } CString CRelativePath::GetSumPath(CString strBasePath, CString strRelativePath) { // 绝对路径 CString strSumPath; // 统一分隔符 strBasePath.Replace(_T('/'), _T('\\')); strRelativePath.Replace(_T('/'), _T('\\')); // 组合分析相对路径生成绝对路径 if (strRelativePath.IsEmpty()) // 如果是空路经,返回根路经 { return strBasePath; } else if ((strRelativePath.GetLength() > 1) && (_T(':') == strRelativePath.GetAt(1))) // 如果是绝对路径,直接返回 { strSumPath = strRelativePath; } else { // 先去掉最后的'\' while (strBasePath.Right(1) == _T("\\")) { strBasePath.Delete(strBasePath.GetLength() - 1); } // 去掉"..\" int iPos = strRelativePath.Find(_T("..\\"), 0); while (iPos >= 0) { strRelativePath.Delete(iPos, 3); strBasePath = strBasePath.Left(strBasePath.ReverseFind(_T('\\'))); iPos = strRelativePath.Find(_T("..\\"), 0); } // 去掉".\" iPos = strRelativePath.Find(_T(".\\"), 0); if (iPos >= 0) { strRelativePath.Delete(iPos, 2); } // 去掉最左边的所有"\" while (strRelativePath.Left(1) == _T("\\")) { strRelativePath.Delete(0); } strSumPath = strBasePath + _T("\\") + strRelativePath; } // 如果是目录,添加\符号 if (!strSumPath.IsEmpty() && (strSumPath.Right(1) != _T('\\'))) { int iDir = strSumPath.ReverseFind(_T('\\')); int iExt = strSumPath.ReverseFind(_T('.')); if (iDir > iExt) { strSumPath += _T("\\"); } } return strSumPath; } CString CRelativePath::GetSumPath(CString strRelativePath) { return GetSumPath(CRelativePath::GetExeFilePath(), strRelativePath); } void CRelativePath::StandardPath(CString &strPath) { // 统一路径分隔符 strPath.Replace(_T('/'), _T('\\')); if (strPath.Right(1) != _T('\\')) { strPath += _T("\\"); } } BOOL CRelativePath::MakeDirEx(CString strPathName) { // 统一路径分隔符 if (strPathName.Find(_T('/')) >= 0) { strPathName.Replace(_T('/'), _T('\\')); } // 获取最顶层路径 int iStart = strPathName.Find('\\'); if (strPathName[iStart - 1] == ':') { iStart = strPathName.Find('\\', iStart + 1); } // 检查路径是否存在,不存在则需要逐级创建文件夹 int iEnd = strPathName.ReverseFind('\\'); CString strPath = strPathName.Left(iEnd); if (PathIsDirectory(strPath)) { return TRUE; } // 逐级检查路径,如果不存在则创建 BOOL boolDirExist; while(iStart != -1 && iStart <= iEnd) { strPath = strPathName.Left(iStart+1); boolDirExist = PathIsDirectory(strPath); if (!boolDirExist) { if (!CreateDirectory(strPath, NULL)) { return FALSE; } } iStart = strPathName.Find('\\', iStart + 1); } return TRUE; }
zhouxiaofeng1021 2014-08-08
  • 打赏
  • 举报
回复
// RelativePath.h: interface for the CRelativePath class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_RELATIVEPATH_H__D51AE358_A247_4D9B_B269_5A5F6B618576__INCLUDED_) #define AFX_RELATIVEPATH_H__D51AE358_A247_4D9B_B269_5A5F6B618576__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CRelativePath : public CObject { public: CRelativePath(); virtual ~CRelativePath(); // Operation CString m_strExePath; CString m_strExePathName; // Implementation public: static CString GetExeFilePath(); static CString GetExeFilePathName(); static CString GetSumPath(CString strRelativePath); static CString GetSumPath(CString strBasePath, CString strRelativePath); static CString GetRelativePath(CString strAbsolutePath); static CString GetRelativePath(CString strRefPath, CString strAbsolutePath); static void StandardPath(CString &strPath); static BOOL MakeDirEx(CString strPathName); }; #endif // !defined(AFX_RELATIVEPATH_H__D51AE358_A247_4D9B_B269_5A5F6B618576__INCLUDED_)
zhouxiaofeng1021 2014-07-10
  • 打赏
  • 举报
回复
解决办法是:自己制作工具栏 #pragma once // CTestInfoToolBarWND class CTestInfoToolBarWND : public CWnd { DECLARE_DYNAMIC(CTestInfoToolBarWND) public: CTestInfoToolBarWND(); virtual ~CTestInfoToolBarWND(); private: // 用于保存窗口中含有多少个按钮 CMap<DWORD, DWORD, CMFCButton*, CMFCButton*> m_mapButton; //定义一个变量来标识是否追踪当前鼠标状态 BOOL m_bTracking; public: //获得该索引号的按钮指针 CMFCButton * GetButton(DWORD dwIndex); //增加按钮 BOOL AddButton(DWORD dwIndex, HBITMAP hBitmap); //删除按钮 BOOL RemoveButton(DWORD dwIndex); //删除所有按钮 void RemoveAll(); //绘制单独按钮 void InvalidateButton(DWORD dwIndex); //获取颜色 COLORREF GetAPPColor(); //自动调整 void AdjustLayout(); protected: DECLARE_MESSAGE_MAP() public: afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg void OnPaint(); afx_msg void OnDestroy(); afx_msg void OnDispSelChange(UINT id); }; // TestInfoToolBarWND.cpp : 实现文件 // #include "stdafx.h" #include "TMSS.h" #include "TestInfoToolBarWND.h" #include "UserMessageDef.h" // CTestInfoToolBarWND IMPLEMENT_DYNAMIC(CTestInfoToolBarWND, CWnd) CTestInfoToolBarWND::CTestInfoToolBarWND() : m_bTracking(FALSE) { } CTestInfoToolBarWND::~CTestInfoToolBarWND() { } //获得该索引号的按钮指针 CMFCButton* CTestInfoToolBarWND::GetButton(DWORD dwIndex) { CMFCButton* pBtn; if (m_mapButton.Lookup(dwIndex,pBtn)) //已有 { return pBtn; } else return NULL; } //增加按钮 BOOL CTestInfoToolBarWND::AddButton(DWORD dwIndex, HBITMAP hBitmap) { CMFCButton* pBtn; if (m_mapButton.Lookup(dwIndex,pBtn)) //已有 { return FALSE; } else //新增 { pBtn = new CMFCButton(); m_mapButton.SetAt(dwIndex, pBtn); // 控件显示区域 CRect rectDummy,rectButton; GetClientRect(rectDummy); rectButton.SetRect(rectDummy.left, rectDummy.top, rectDummy.left+10,rectDummy.top + rectDummy.Height()); pBtn->Create(_T(""), WS_CHILD|WS_VISIBLE|WS_TABSTOP | BS_AUTOCHECKBOX , rectButton, this, dwIndex); // Resize the button. pBtn->EnableFullTextTooltip(TRUE); // Use the application menu font at the button text font. pBtn->EnableMenuFont(); // Use the current Windows theme to draw the button borders. pBtn->EnableWindowsTheming(TRUE); // Set the background color for the button text. pBtn->SetFaceColor(GetAPPColor(),TRUE); pBtn->SetTextColor(RGB(0,0,0)); //pBtn->m_bTransparent = TRUE; pBtn->m_nFlatStyle = CMFCButton::BUTTONSTYLE_NOBORDERS; pBtn-> m_bHighlightChecked = TRUE; return TRUE; } } //删除按钮 BOOL CTestInfoToolBarWND::RemoveButton(DWORD dwIndex) { CMFCButton* pBtn; if (m_mapButton.Lookup(dwIndex,pBtn)) { delete pBtn; pBtn = NULL; m_mapButton.RemoveKey(dwIndex); return TRUE; } else return FALSE; } //删除所有按钮 void CTestInfoToolBarWND::RemoveAll() { POSITION pos = m_mapButton.GetStartPosition(); DWORD dwKey; CMFCButton* pBtn; while (pos != NULL)//删除内存 { m_mapButton.GetNextAssoc(pos, dwKey, pBtn); delete pBtn; pBtn = NULL; } m_mapButton.RemoveAll(); } //绘制单独按钮 void CTestInfoToolBarWND::InvalidateButton(DWORD dwIndex) { CMFCButton* pBtn; if (m_mapButton.Lookup(dwIndex,pBtn)) { pBtn->Invalidate(TRUE); } } //获取颜色 COLORREF CTestInfoToolBarWND::GetAPPColor() { COLORREF refColor = NULL; switch (theApp.m_nAppLook) { case ID_VIEW_APPLOOK_WIN_2000: refColor = RGB(240, 240, 240); break; case ID_VIEW_APPLOOK_OFF_XP: refColor = RGB(240, 240, 240); break; case ID_VIEW_APPLOOK_WIN_XP: refColor = RGB(211, 218, 237); break; case ID_VIEW_APPLOOK_OFF_2003: refColor = RGB(149, 194, 240); break; case ID_VIEW_APPLOOK_VS_2005: refColor = RGB(220, 220, 220); break; default: switch (theApp.m_nAppLook) { case ID_VIEW_APPLOOK_OFF_2007_BLUE: refColor = RGB(191, 219, 255); break; case ID_VIEW_APPLOOK_OFF_2007_BLACK: refColor = RGB(83, 83, 83); break; case ID_VIEW_APPLOOK_OFF_2007_SILVER: refColor = RGB(224,229, 238); break; case ID_VIEW_APPLOOK_OFF_2007_AQUA: refColor = RGB(196,202, 217); break; } } return refColor; } BEGIN_MESSAGE_MAP(CTestInfoToolBarWND, CWnd) ON_WM_SIZE() ON_WM_PAINT() ON_WM_DESTROY() ON_COMMAND_RANGE(ID_TESTINFO_INFO, ID_TESTINFO_ERROR, &CTestInfoToolBarWND::OnDispSelChange) END_MESSAGE_MAP() // CTestInfoToolBarWND 消息处理程序 void CTestInfoToolBarWND::OnSize(UINT nType, int cx, int cy) { CWnd::OnSize(nType, cx, cy); // TODO: 在此处添加消息处理程序代码 AdjustLayout(); } void CTestInfoToolBarWND::OnPaint() { AdjustLayout(); CWnd::OnPaint(); } //自动调整 void CTestInfoToolBarWND::AdjustLayout() { CPaintDC dc(this); // 控件显示区域 CRect rectDummy; GetClientRect(rectDummy); COLORREF refAppColor = GetAPPColor(); CBrush myBrush(refAppColor); dc.FillRect(rectDummy, &myBrush); //绘制背景 DWORD dwSize = -1; dwSize = m_mapButton.GetSize(); if (dwSize > 0) //按钮个数大于0 { CRect rectDummy; GetClientRect(rectDummy); POSITION pos = m_mapButton.GetStartPosition(); DWORD dwKey; CMFCButton* pBtn; DWORD dwLocation = rectDummy.left; //绘制位置 int i = 0; while (pos != NULL)//绘制按钮 { m_mapButton.GetNextAssoc(pos, dwKey, pBtn); //获取字体宽度 TEXTMETRIC tm; CString strwindowText; CPaintDC dc(pBtn); dc.GetTextMetrics(&tm); pBtn->GetWindowText(strwindowText); //计算文字长度 DWORD dwTextWidth = (strwindowText.GetLength()+2)*tm.tmAveCharWidth*2; DWORD dwWidth = dwTextWidth + 24; pBtn->MoveWindow(dwLocation ,rectDummy.top,dwWidth, rectDummy.Height(),TRUE); dwLocation = dwLocation + dwWidth; //绘制按钮背景 if (pBtn->GetCheck() == BST_CHECKED) { pBtn->SetFaceColor(RGB(252,144,7), TRUE); } else { pBtn->SetFaceColor(refAppColor, TRUE); } if (i < m_mapButton.GetSize()-1) { //画2条深一点的线条和浅一点的颜色 //深一点的线条 CPen deepPen(PS_SOLID, 2, RGB(118,161,218)); CPen* pOldPen = dc.SelectObject(&deepPen); dc.MoveTo(dwLocation + 1, rectDummy.top + 2); dc.LineTo(dwLocation + 1, rectDummy.top+rectDummy.Height() - 4); dc.SelectObject(pOldPen); //浅一点的颜色 CPen lightPen(PS_SOLID,2, RGB(255,255,255)); pOldPen = dc.SelectObject(&lightPen); dc.MoveTo(dwLocation + 2, rectDummy.top + 2); dc.LineTo(dwLocation + 2, rectDummy.top+rectDummy.Height() - 4); dc.SelectObject(pOldPen); dwLocation = dwLocation + 2; } i++; } //绘制背景 dc.FillRect(CRect(dwLocation, rectDummy.top, rectDummy.right, rectDummy.bottom), &myBrush); } } void CTestInfoToolBarWND::OnDestroy() { CWnd::OnDestroy(); // TODO: 在此处添加消息处理程序代码 RemoveAll(); } void CTestInfoToolBarWND::OnDispSelChange(UINT id) { ::SendMessage(GetParent()->m_hWnd, WM_INFOVIEW_DISPINFO_SELCHANGE, id, NULL); CMFCButton* pBtn = GetButton(id); if (pBtn != NULL) { if (pBtn->GetCheck() == BST_CHECKED) { pBtn->SetFaceColor(RGB(252,144,7), TRUE); } else { pBtn->SetFaceColor(GetAPPColor(), TRUE); } } } 全部自己控制 ,挺好的
zhouxiaofeng1021 2014-07-10
  • 打赏
  • 举报
回复
我已经解决了
dreamswang 2014-04-08
  • 打赏
  • 举报
回复
遇到和楼主同样的问题,求解决方法。
向立天 2014-04-03
  • 打赏
  • 举报
回复
您好 我是本版版主 此帖已多日无人关注 请您及时结帖 如您认为问题没有解决可按无满意结帖处理 另外本版设置了疑难问题汇总帖 并已在版面置顶 相关规定其帖子中有说明 您可以根据规定提交您帖子的链接 如您目前不想结帖只需回帖说明 我们会删除此结帖通知 见此回复三日内无回应 我们将强制结帖 相关规定详见界面界面版关于版主结帖工作的具体办法
zhouxiaofeng1021 2014-03-03
  • 打赏
  • 举报
回复
有没有人可以解决这个问题啊! 技术牛人们!
zhouxiaofeng1021 2014-02-27
  • 打赏
  • 举报
回复
我采用的事拆分窗口!每个窗口都有一个工具栏!!!
zhouxiaofeng1021 2014-02-27
  • 打赏
  • 举报
回复
我这里不止一一个 有5个 是的 和你一样! 求大神解救! MFC~~~
worldy 2014-02-27
  • 打赏
  • 举报
回复
测试发现,如果只创建一个CMFCToolBar没有发现泄漏,但是如果创建了2个,则发生泄漏,lz测试一下看看是否跟我发现的现象相同
zhouxiaofeng1021 2014-02-27
  • 打赏
  • 举报
回复
AdjustLocations是CMFCToolBar的成员函数!而且百分之百肯定是在这里!
	//nIndex = m_wndToolBar.CommandToIndex(ID_OBJECT_TESTTIME);
// if (nIndex >= 0)
// {
// m_wndToolBar.SetToolBarBtnText(nIndex, strTimeInfo, TRUE, TRUE);
// }

m_wndToolBar.AdjustLayout();

这样只调用AdjustLayout()有泄露!
当你

class CTestProgressToolBar : public CMFCToolBar
{
virtual void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
{
CMFCToolBar::OnUpdateCmdUI((CFrameWnd*) GetOwner(), bDisableIfNoHndler);
}

virtual BOOL AllowShowOnList() const { return FALSE; }

public:
virtual void AdjustLayout()
{
if (GetSafeHwnd() == NULL)
{
return;
}

BOOL bHorz = GetCurrentAlignment() & CBRS_ORIENT_HORZ ? TRUE : FALSE;

for (POSITION pos = m_Buttons.GetHeadPosition(); pos != NULL;)
{
CMFCToolBarButton* pButton = (CMFCToolBarButton*) m_Buttons.GetNext(pos);
if (pButton == NULL)
{
break;
}

ASSERT_VALID(pButton);

pButton->m_bTextBelow = ((pButton->m_nStyle & TBBS_SEPARATOR) == 0) && m_bTextLabels && bHorz;
}

CMFCReBar* pBar = DYNAMIC_DOWNCAST(CMFCReBar, GetParent());
if (pBar != NULL)
{
CReBarCtrl& wndReBar = pBar->GetReBarCtrl();
UINT uiReBarsCount = wndReBar.GetBandCount();

REBARBANDINFO bandInfo;
bandInfo.cbSize = pBar->GetReBarBandInfoSize ();
bandInfo.fMask = (RBBIM_CHILDSIZE | RBBIM_CHILD | RBBIM_IDEALSIZE);

UINT uiBand = 0;
for (uiBand = 0; uiBand < uiReBarsCount; uiBand ++)
{
wndReBar.GetBandInfo(uiBand, &bandInfo);
if (bandInfo.hwndChild == GetSafeHwnd())
{
break;
}
}

bandInfo.fMask ^= RBBIM_CHILD;

if (uiBand >= uiReBarsCount)
{
ASSERT(FALSE);
}
else
{
CSize size = CMFCBaseToolBar::CalcFixedLayout(FALSE, TRUE);

m_nMaxBtnHeight = CalcMaxButtonHeight();
CSize sizeMin = CalcSize(FALSE);

CRect rect; rect.SetRectEmpty();
CalcInsideRect(rect, TRUE);
sizeMin.cy -= rect.Height();
sizeMin.cx -= rect.Width();

sizeMin.cx = max(sizeMin.cx, size.cx);
sizeMin.cy = max(sizeMin.cy, size.cy);

bandInfo.cxMinChild = m_sizeButton.cx;
bandInfo.cyMinChild = sizeMin.cy;

bandInfo.cxIdeal = sizeMin.cx;

wndReBar.SetBandInfo(uiBand, &bandInfo);
}
}
else
{
//AdjustSize();//+有内存泄露
}

//AdjustLocations();//+++ 有严重内存泄露
RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
}
virtual void AdjustSize()
{
CFrameWnd* pParent = AFXGetParentFrame(this);
if (pParent != NULL && pParent->GetSafeHwnd() != NULL)
{
BOOL bMode = (m_pParentDockBar == NULL);
CSize sizeCurr = CalcFixedLayout(bMode, IsHorizontal());

if (sizeCurr.cx == 32767 || sizeCurr.cy == 32767)
{
CRect rectParent;
GetParent()->GetClientRect(&rectParent);

if (sizeCurr.cx == 32767)
{
sizeCurr.cx = rectParent.Width();

if (m_nMaxLen != 0)
{
sizeCurr.cx = min(sizeCurr.cx, m_nMaxLen);
}
}
else
{
sizeCurr.cy = rectParent.Height();

if (m_nMaxLen != 0)
{
sizeCurr.cy = min(sizeCurr.cy, m_nMaxLen);
}
}
}

CRect rect;
GetWindowRect(rect);

CMFCTabCtrl* pTab = DYNAMIC_DOWNCAST(CMFCTabCtrl, GetParent());
if (pTab != NULL)
{
CRect rectWndArea;
pTab->GetWndArea(rectWndArea);
SetWindowPos(NULL, -1, -1, rectWndArea.Width(), rectWndArea.Height(), SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE);
}
else
{
if (IsCustomizeMode())
{
if (rect.Height() != sizeCurr.cy && sizeCurr.cy != 32767 && IsHorizontal() ||
rect.Width() != sizeCurr.cx && sizeCurr.cx != 32767 && !IsHorizontal())
{
SetWindowPos(NULL, 0, 0, sizeCurr.cx, sizeCurr.cy, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
UpdateVirtualRect();
}
}
else
{
if (rect.Height() != sizeCurr.cy && sizeCurr.cy != 32767 && IsHorizontal() ||
rect.Width() != sizeCurr.cx && sizeCurr.cx != 32767 && !IsHorizontal())
{
CSize sizeMin;
GetMinSize(sizeMin);

int nNewWidth = max(sizeMin.cx, sizeCurr.cx);
int nNewHeight = max(sizeMin.cy, sizeCurr.cy);

SetWindowPos(NULL, 0, 0, nNewWidth, nNewHeight, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
UpdateVirtualRect();
}
}
}

if (!IsFloating() && IsVisible() && m_pParentDockBar != NULL && m_pDockBarRow != NULL)
{
CRect rectWnd;
BOOL bIsHorz = IsHorizontal();
BOOL bResize = FALSE;

m_pDockBarRow->GetClientRect(rectWnd);

if (rectWnd.Height() != sizeCurr.cy && bIsHorz)
{
rectWnd.bottom = rectWnd.top + sizeCurr.cy;
bResize = TRUE;
}
else if (rectWnd.Width() != sizeCurr.cx && !bIsHorz)
{
rectWnd.right = rectWnd.left + sizeCurr.cx;
bResize = TRUE;
}

if (bResize)
{
m_pParentDockBar->ResizeRow(m_pDockBarRow, bIsHorz ? sizeCurr.cy : sizeCurr.cx);
}

if (IsCustomizeMode())
{
UpdateVirtualRect(sizeCurr);
m_pDockBarRow->ArrangePanes(this);
}

pParent->RecalcLayout();
}
else
{
CPaneFrameWnd* pParentMiniFrame = GetParentMiniFrame();
if (pParentMiniFrame != NULL && GetParent() == pParentMiniFrame)
{
pParentMiniFrame->SizeToContent();
pParentMiniFrame->RedrawWindow();
}
else if (!IsKindOf(RUNTIME_CLASS(CMFCDropDownToolBar)))
{
pParent->RecalcLayout(); //这里有内存泄露
}
}
}
}
};


这样时,自己重写就不会出现内存泄露,注释那两个函数!
可是工具栏就不位置还有图片文字就刷不出来了!

Eleven 2014-02-26
  • 打赏
  • 举报
回复
AdjustLocations是CMFCToolBar的成员函数吗?我在MSDN的CMFCToolBar中没有搜索到,在CMFCToolBar的基类中也没有找到/ 你如何确定是由这两个函数引起的?而不是由你其他绘图的代码所引起的呢?
zhouxiaofeng1021 2014-02-26
  • 打赏
  • 举报
回复
就是定时刷新界面!有严重内存泄露!

15,980

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧