当前位置:C++技术网 > 资讯 > 安全获取窗口GetSafeHwnd详细解说

安全获取窗口GetSafeHwnd详细解说

更新时间:2015-07-01 17:11:59浏览次数:1+次

    安全获取窗口指的是正确的获取窗口句柄和操作句柄,避免错误的操作窗口导致程序崩溃。

    我想,写过MFC程序的程序员,都知道一个函数,GetDlgItem(控件ID) ,此函数返回控件对象的指针。比如:

CWnd * pWnd = GetDlgItem(IDC_BUTTON1);

     这样就得到了一个控件或者窗口的对象的指针。控件是包装了基本窗口的窗口,因此,基本窗口拥有的特性,控件可以有,控件还包含了控件特有的东西。如果你只是想对控件操作基本窗口的东西,那么直接使用pWnd指针即可,比如设置控件的文字。代码为:

pWnd->SetWindowText(_T("新设置的控件文字"));

     但是,如果你要操作控件特有的东西,比如设置复选框按钮选中:

pWnd->SetCheck(TRUE);//这样写是错误的。

     这是因为CButton类是继承自CWnd类的,SetCheck是CButton类增加的,CWnd类没有,所以用CWnd指针去操作,就有危险。因为CWnd类指针没法操作CWnd类范围之外的东西,即没法操作派生的子类CButton类的东西。
    然而因为你的控件确实是CButton类对象窗口,所以,你可以将返回的指针类型由CWnd *转成 CButton *即可。代码如下:

CButton * pBtn = (CButton *)GetDlgItem(IDC_BUTTON1);
pBtn->SetCheck(TRUE);//这样写是正确的。

     以上就是获取控件窗口对象的一个简单例子。
    对于这些控件的基本操作,在MFC中,基本就使用控件类就可以完成了。但是,有时候,我们需要知道窗口的句柄,来操作窗口。比如像窗口发送消息,使用SendMessage,就需要知道窗口句柄。我们的目标就是要得到窗口句柄。如果一切正常,我们可以通过获取对象的m_hWnd成员来得到窗口的句柄。方法为:

HWND hWnd = pWnd->m_hwnd;

     或者

HWND hWnd = pBtn->m_hwnd;
 

    问题就是:如果你给的ID的控件不存在,GetDlgItem从而得不到对应的控件类对象。因此,pWnd是一个NULL指针。这个时候,你发现问题了吗?既然对象指针是空指针,那么怎么能获取对象的成员呢?因为对象指针为空,说明这个对象不存在,对象都不存在,你还能得到对象的窗口句柄么?是吧。那么此时不只是得不到句柄这么简单哦。如果你运行这个代码,那么,程序就会崩溃。这是内存访问违规了。因为你要操作NULL指针。
    当然,如果你细心,编程习惯好,你就会对这个对象指针做检查,方法如下:

HWND hWnd = NULL;
if(pWnd!=NULL)
{
    hWnd = pWnd->m_hwnd;
}
else
{
    hWnd = NULL;
}

    这个就是安全获取窗口的意思。然而GetSafeHwnd()干嘛的呢?哈哈哈,你应该想到了吧。GetSafeHwnd()就是完成上面的检测咯。功能和上面的一样。如果你不喜欢用这个函数,自己写上面的代码也是一样。下面让你看看这个函数内部代码,你就可以放心用了吧。代码如下:

_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const

{

    return this == NULL?NULL:m_hWnd;

}
     那么此时我们是不是可以放心的用了呢?这个函数当然就省去我们写这些代码了。之前我不熟,也不敢用,其实了解之后,释然了。你觉得呢?哈哈哈。