VC++中对GetSafeHwnd的使用
在看代码时,发现有不少地方使用GetSafeHwnd, 比如代码中的一些断言
ASSERT(NULL != m_UserId.GetSafeHwnd());
这里的m_UserId是CFilterEdit类型,它继承自afxwin.h中的CEdit, 而这个CEdit又继承自afxwin.h中的CWnd类
CWnd类是MFC窗口类的基类,它提供了微软基础类库中所有窗口类的基本功能, 比如CreatWindow, ShowWindow等. CWnd类封装了窗口的句柄m_hWnd成员, 我们知道在C++中每个窗口都会有一个句柄HWND来操作它。
看到这里,我们可能马上会想到,当我想得到一个窗口对象(CWnd的派生对象)指针的句柄(HWND)时,是不是直接获取它的m_hwnd成员就可以了,如下:
CWnd *pwnd = FindWindow("ExploreWClass",NULL) //得到资源管理器窗口 HWND hWnd = pWnd->m_hwnd; //得到它的HWND 通过它的窗口句柄m_hWnd成员,来得到这个窗口的句柄
表面上看,这个代码好像没有什么问题,但是实际上,这里可能有个漏洞,那就是当pWnd为空/null的时候,我们不能对一个NULL指针来访问其成员, 这时会报错"General protection error", 并关闭应用程序
那针对这种情况,怎么办呢。 针对这种情况,CWnd类中提供一个可以安全访问窗口句柄的方法 => GetSafeHwnd(), 修改如下
CWnd *pwnd = FindWindow("ExploreWClass",NULL) //得到资源管理器窗口 HWND hWnd = pWnd->GetSafeHwnd(); //通过GetSafeHwnd()方法来安全的获取窗口句柄
这里使用GetSafeHwnd()方法来安全的获取窗口句柄,在这种情况下,即便pWnd是NULL, 这个方法GetSafeHwnd()依然可以顺利执行而不报错,只不过它返回的是NULL. 我们可以看看CWnd类中GetSafeHwnd()函数的实现
_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const { return this == NULL ? NULL : m_hWnd; }
所以我们在进行C++开发时,在获取窗口句柄时,通常都使用这个安全获取窗口句柄的函数GetSafeHwnd()