用window api 不斷地回圈創建視窗顯示視窗釋放視窗,會存在記憶體泄露,查了很多資料都沒有找到解決辦法,有沒有大牛幫一下忙?
demo如下
只是回圈
createwindow
showwindow
destorywindow
void CTest1Dlg::initWnd(int screenWidth, int screenHeight, HWND parent)
{
WNDCLASSEX wc;
int posX = 0, posY = 0;
// Get an external pointer to this object.
//ApplicationHandle = this;
// Get the instance of this application.
m_hinstance = GetModuleHandle(NULL);
// Give the application a name.
m_applicationName = L"Ticker";
// Setup the windows class with default settings.
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = m_hinstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hIconSm = wc.hIcon;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = m_applicationName;
wc.cbSize = sizeof(WNDCLASSEX);
// Register the window class.
RegisterClassEx(&wc);
// Create the window with the screen settings and get the handle to it.
m_hwnd = CreateWindow(m_applicationName, m_applicationName,
WS_POPUP,
posX, posY, screenWidth, screenHeight, parent, NULL, m_hinstance, NULL);
//::SetProcessWorkingSetSize(m_hwnd,-1,-1);
::ShowWindow(m_hwnd, SW_HIDE);
}
void CTest1Dlg::ReleaseWnd()
{
::DestroyWindow(m_hwnd);
m_hwnd = NULL;
if (!UnregisterClass(m_applicationName, m_hinstance))
{
auto err = GetLastError();
}
if (m_hinstance != NULL)
{
FreeLibrary(m_hinstance);
m_hinstance = NULL;
}
}
void CTest1Dlg::OnBnClickedOk()
{
// TODO: 在此添加控制元件通知處理程式代碼
//CDialogEx::OnOK();
HWND hWnd = this->GetSafeHwnd();
while (1)
{
initWnd(100, 100, hWnd);
::ShowWindow(m_hwnd, SW_SHOW);
ReleaseWnd();
//Sleep(100);
}
}
uj5u.com熱心網友回復:
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);wc.hIconSm = wc.hIcon;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
這些load起來的東西, 你釋放了嗎?
uj5u.com熱心網友回復:
何以見得有記憶體泄漏 ?uj5u.com熱心網友回復:
通過記憶體監控,發現每回圈一次,記憶體就會增加4-8k,而不會減少
uj5u.com熱心網友回復:
if (wc.hCursor != NULL)
{
DestroyCursor(wc.hCursor);
wc.hCursor = NULL;
}
if (wc.hIcon != NULL)
{
DestroyIcon(wc.hIcon);
wc.hIcon = NULL;
}
if (wc.hbrBackground!=NULL)
{
DeleteObject(wc.hbrBackground);
wc.hbrBackground = NULL;
}
加上這幾句,全釋放了,還是有記憶體泄露
uj5u.com熱心網友回復:
你用什么記憶體監控 ?uj5u.com熱心網友回復:
搜“GDI泄露檢測”uj5u.com熱心網友回復:
1 與 ::ShowWindow(m_hwnd, SW_SHOW);//= | WS_VISIBLE 無關、2 用win7 “cpu meter” 檢測 無 mem leak
////////////////////////////////////////
HINSTANCE m_hinstance;
HWND m_hwnd;
char *m_applicationName;
void CShowWinTestDlg::initWnd(int Width, int Height, HWND parent)
{
WNDCLASSEX wc;
int posX = 450, posY = 200;
// Get the instance of the application.
m_hinstance = GetModuleHandle(NULL);
// TCHAR FileName[MAX_PATH];
// GetModuleFileName(m_hinstance, FileName, MAX_PATH);
// afxDump << FileName << "\n";// ShowWinTest.exe
// Give the application a name.
m_applicationName = "Ticker";
// Setup the windows class with default settings.
wc.style = CS_HREDRAW | CS_VREDRAW ;
wc.lpfnWndProc = ::DefWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = m_hinstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hIconSm = wc.hIcon;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = m_applicationName;
wc.cbSize = sizeof(WNDCLASSEX);
// Register the window class.
RegisterClassEx(&wc);
// Create the window with the screen settings and get the handle to it.
m_hwnd = CreateWindow(m_applicationName, m_applicationName,
WS_POPUP|WS_CAPTION,posX,posY,Width,Height,parent,NULL,m_hinstance,NULL);
//::SetProcessWorkingSetSize(m_hwnd,-1,-1);
::ShowWindow(m_hwnd, SW_SHOW);//= | WS_VISIBLE
}
void CShowWinTestDlg::ReleaseWnd()
{
::DestroyWindow(m_hwnd);
m_hwnd = NULL;
if (!UnregisterClass(m_applicationName, m_hinstance))
{
auto err = GetLastError();
}
if (m_hinstance != NULL)
{// decrements the reference count
BOOL ret=FreeLibrary(m_hinstance);
//afxDump << ret << "\n";// =1
m_hinstance = NULL;
}
}
void DoEvents()
{
MSG msg;
// Process existing messages in the application's message queue.
// When the queue is empty, do clean up and return.
while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
{// has msg
if (!AfxGetThread()->PumpMessage()) break;
}
}
void CShowWinTestDlg::OnOK()
{
// TODO: Add extra validation here
HWND hWnd = this->GetSafeHwnd();
while (m_bRun)
{
initWnd(100, 100, hWnd);
Sleep(400);
DoEvents();
ReleaseWnd();
}
// CDialog::OnOK();
}
void CShowWinTestDlg::OnCancel()
{
// TODO: Add extra cleanup here
m_bRun=FALSE;
CDialog::OnCancel();
}
// use win7 "cpu meter", no mem leak detected!
uj5u.com熱心網友回復:
既然你呼叫::ShowWindow(....); 還得檢查WM_PAINT訊息處理的代碼,ShowWindow會有WM_PAINT訊息uj5u.com熱心網友回復:
可是WM_PAINT訊息處理都是默認的啊
uj5u.com熱心網友回復:
真正的默認是 wc.lpfnWndProc = ::DefWindowProc;而不是 wc.lpfnWndProc = WndProc;
uj5u.com熱心網友回復:
LRESULT CALLBACK WndProc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam)
{
return DefWindowProc(hwnd, umessage, wparam, lparam);
//return 0;
}
是默認啊
uj5u.com熱心網友回復:
1. 視窗本來就沒有 WS_VISIBLE 用 ::ShowWindow(m_hwnd, SW_HIDE); 完全是多余2. UnregisterClass 的引數是 RegisterClass 的回傳值,傳 m_applicationName 做什么?
3. m_hinstance 這個需要用 FreeLibrary 釋放?
如果你需要頻繁的更新視窗內容,那么你可以隱藏/顯示視窗,或者重繪視窗。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/93907.html
標籤:界面
上一篇:關于release和debug生成的dll和不同版本的vc編譯器生成的dll之間呼叫問題
下一篇:openni2 sdk安裝失敗
