严重问题,高手请进。

yangl79 2004-04-02 10:41:02
msdn在介绍GetDlgItem的时候,明确指出:
The returned pointer may be temporary and should not be stored for later use.
如果真是这样那我不惨了!在我的一个软件中,因为常常要使切换按钮的可用与不可用以及改变按钮文字,所以我用DetDlgItem把它们存了起来,用的时候直接到数组里面取,这样的话这个软件不是犯了一个重大的错误了?可是用这么久也没出错。
另外,它也是说可能是临时的,那一定在某种情况下不是临时的,高手能不能解释一下这个问题?
...全文
112 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
QunKangLi 2004-04-02
  • 打赏
  • 举报
回复
临时包装对象会在空闲时间删除.在同一函数中多次使用是没用问题的,不同函数中使用先前保存下来的指针就有可能出

错,特别是对话框初使化时候存下来的指针.

在MFC层次上的函数使用CWnd对象,而本地Windows代码(API)使用句柄.如:当Windows系统调用一个窗口过程时将传递

一个HWND参数,而MFC本身的消息机制使用CWnd类;为了更好更高效的实现,MFC需要与Windows系统合作,将句柄与CWnd对象

进行关联---它用CHandleMap完成关联.


CHandleMap有两个CMapPtrToPtr的成员变量:m_permanentMap(永久映射表,程序运行过程中对象/句柄之间的关系),m_tem

poraryMap(临时映射表,在消息存在的过程中才存在).永久表保存显式创建的CWnd对象,当对象创建时将在永久目录下插

入一个条目,在CWnd::OnNcDestrory时删除对应条目.但是Windows有时会传入某些不是由开发人员显式创建的窗口的句柄

,此时MFC会分配一个临时对象来包装这个句柄并将它们的映射保存到临时映射表中,这些临时对象会在空闲时间被删除并

移走相应的临时映射表条目.类似的MFC对象与Windows句柄的映射表有:
m_pmapHWND: 窗口句柄与CWnd对象
m_pampHMENU: 菜单句柄与CMenu对象
m_pmapHDC: 设备环境句柄与CDC对象
m_pmapHGDIOBJ: GDI句柄与CGDI对象
m_mapHIMAGELIST: 图像链表句柄到CImageList对象

当给定句柄,如HWND时,MFC简单调用CWnd* PASCAL CWnd::FromHandle(HWND hWnd),

此函数内部使用CHandleMap::FromHandle(hWnd)获取相关联的CWnd对象.在CHandleMap::FromHandle(h)内部(源代码在Wi

nHand.cpp),先使用CObject* pObject = LookupPermanent(h); if (pObject != NULL)return pObject; 检查永久表;

如永久表中不存在,使用pObject = LookupTemporary(h)) != NULL检查临时表,都不存在时,使用pTemp = =

m_pClass->CreateObject();if (pTemp == NULL)AfxThrowMemoryException();

m_temporaryMap.SetAt((LPVOID)h, pTemp);创建临时对象并将其插入到临时表中去,同时返回该临时对象.
void CHandleMap::RemoveHandle(HANDLE h)的注释说明临时对象将在空闲时由OnIdel释放:
// remove only from permanent map -- temporary objects are removed
// at idle in CHandleMap::DeleteTemp, always!
如果想不自动释放临时对象,使用void AFXAPI AfxLockTempMaps()/BOOL AFXAPI AfxUnlockTempMaps(BOOL bDeleteTemps)进行锁定.

MFC源代码真TMD是好东西啊!



kundy 2004-04-02
  • 打赏
  • 举报
回复
同意楼上的见解 ^_^
yu_hl 2004-04-02
  • 打赏
  • 举报
回复
// Most Windows objects are represented with a HANDLE, including
// the most important ones, HWND, HDC, HPEN, HFONT etc.
// We want C++ objects to wrap these handle based objects whenever we can.
// Since Windows objects can be created outside of C++ (eg: calling
// ::CreateWindow will return an HWND with no C++ wrapper) we must
// support a reasonably uniform mapping from permanent handles
// (i.e. the ones allocated in C++) and temporary handles (i.e.
// the ones allocated in C, but passed through a C++ interface.
// We keep two dictionaries for this purpose. The permanent dictionary
// stores those C++ objects that have been explicitly created by
// the developer. The C++ constructor for the wrapper class will
// insert the mapping into the permanent dictionary and the C++
// destructor will remove it and possibly free up the associated
// Windows object.
// When a handle passes through a C++ interface that doesn't exist in
// the permanent dictionary, we allocate a temporary wrapping object
// and store that mapping into the temporary dictionary.
// At idle time the temporary wrapping objects are flushed (since you better
// not be holding onto something you didn't create).
//


在CWinThread::OnIdle里调用AfxUnlockTempMaps,AfxUnlockTempMaps会释放temporary maps.

所以不要保留GetDlgItem等返回的临时指针,可以直接保存HWND objects,然后CWnd::FromHandle获取临时指针来用。
VCSQLVB 2004-04-02
  • 打赏
  • 举报
回复
GetDlgItem返回指向一个控件的指针,根本不需要将其保存在数组里,要的时候直接用该函数就获取了,然后操作它。
oldforest 2004-04-02
  • 打赏
  • 举报
回复
GetDlgItem()返回的是CWnd指针,操作系统中内存的数据在满负荷时经常会移动,你最好再取它的句柄,GetDlgItem()->m_hWnd,句柄操作就可确保万无一失了。
Caps77 2004-04-02
  • 打赏
  • 举报
回复
关注
Caps77 2004-04-02
  • 打赏
  • 举报
回复
请问QunKangLi(晓风吹泪醉霜林) 您的这些知识点是从哪本书看来的,能否将资料发给我一份
feng0907@sina.com

仰慕!
学习!
kundy 2004-04-02
  • 打赏
  • 举报
回复
QunKangLi(晓风吹泪醉霜林) 真强,向你学习 ^_^
QunKangLi 2004-04-02
  • 打赏
  • 举报
回复
在记事本里格式写时都还好好的东西,COPY上来格式就乱了,将记事本有自动换行符的地方都转成了段标记,555

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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