, GetDlgItem是建立临时对象,疑惑
在线等,高手进, GetDlgItem是建立临时对象,疑惑
GetDlgItem这里创建子窗口控件
CWnd* CWnd::GetDlgItem(int nID) const
{ ASSERT(::IsWindow(m_hWnd));
return CWnd::FromHandle(::GetDlgItem(m_hWnd,nID)); }
m_hWnd是主窗口句柄
FromHandle是会创建临时对象,但是它不销毁阿,至少我没看到其在哪里销毁的源代码。为什么书上说不能用其返回的指针,只要子窗口存在
请高手释疑.....................................
------解决方案--------------------
MFC中FromHandle函数会在CHandleMap中查找句柄,如果没有查到永久对象的话将创建临时对象。CWinApp的Run消息循环时这样设计的,在应用程序空闲时调用OnIdle函数。临时对象就是在OnIdle中被释放的。
也就是说临时对象在当前消息处理函数中可以放心使用,但是消息处理返回后,临时对象可能就已经销毁,因此不能保存临时对象指针使用
以下是CWinThread的代码片段
在OnIdle中
// free temp maps, OLE DLLs, etc.
AfxLockTempMaps();
AfxUnlockTempMaps();
int CWinThread::Run()
{
ASSERT_VALID(this);
// for tracking the idle time state
BOOL bIdle = TRUE;
LONG lIdleCount = 0;
// acquire and dispatch messages until a WM_QUIT message is received.
for (;;)
{
// phase1: check to see if we can do idle work
while (bIdle &&
!::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))
{
// call OnIdle while in bIdle state
if (!OnIdle(lIdleCount++)) // 在这里调用的OnIdle
bIdle = FALSE; // assume "no idle " state
}
// phase2: pump messages while available
do
{
// pump message, but quit on WM_QUIT
if (!PumpMessage())
return ExitInstance();
// reset "no idle " state after pumping "normal " message
if (IsIdleMessage(&m_msgCur))
{
bIdle = TRUE;
lIdleCount = 0;
}
} while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
}
ASSERT(FALSE); // not reachable
}
GetDlgItem这里创建子窗口控件
CWnd* CWnd::GetDlgItem(int nID) const
{ ASSERT(::IsWindow(m_hWnd));
return CWnd::FromHandle(::GetDlgItem(m_hWnd,nID)); }
m_hWnd是主窗口句柄
FromHandle是会创建临时对象,但是它不销毁阿,至少我没看到其在哪里销毁的源代码。为什么书上说不能用其返回的指针,只要子窗口存在
请高手释疑.....................................
------解决方案--------------------
MFC中FromHandle函数会在CHandleMap中查找句柄,如果没有查到永久对象的话将创建临时对象。CWinApp的Run消息循环时这样设计的,在应用程序空闲时调用OnIdle函数。临时对象就是在OnIdle中被释放的。
也就是说临时对象在当前消息处理函数中可以放心使用,但是消息处理返回后,临时对象可能就已经销毁,因此不能保存临时对象指针使用
以下是CWinThread的代码片段
在OnIdle中
// free temp maps, OLE DLLs, etc.
AfxLockTempMaps();
AfxUnlockTempMaps();
int CWinThread::Run()
{
ASSERT_VALID(this);
// for tracking the idle time state
BOOL bIdle = TRUE;
LONG lIdleCount = 0;
// acquire and dispatch messages until a WM_QUIT message is received.
for (;;)
{
// phase1: check to see if we can do idle work
while (bIdle &&
!::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))
{
// call OnIdle while in bIdle state
if (!OnIdle(lIdleCount++)) // 在这里调用的OnIdle
bIdle = FALSE; // assume "no idle " state
}
// phase2: pump messages while available
do
{
// pump message, but quit on WM_QUIT
if (!PumpMessage())
return ExitInstance();
// reset "no idle " state after pumping "normal " message
if (IsIdleMessage(&m_msgCur))
{
bIdle = TRUE;
lIdleCount = 0;
}
} while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
}
ASSERT(FALSE); // not reachable
}