VC++中对GetSafeHwnd的使用

发布时间 2023-08-30 17:57:40作者: 新西兰程序员

在看代码时,发现有不少地方使用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()