您的位置:首页 > 其它

Attach函数的讲解

2010-10-10 11:34 78 查看
CWnd::Attach

Attaches a Windows window to a CWnd object.


BOOL Attach(
   HWND hWndNew
);


Parameters

hWndNew

Specifies a handle to a Windows window.

用处:将一个窗口attach到一个CWnd 对象上。(该函数为CWnd对象的成员函数,更好的理解是:一个C++的Cwnd对象在召唤一个Windows的window.)

概念:

C++对象和Windows窗口(对象)的区别:

一段比较好的讲解:

首先,你要明白Windows对象和MFC对象的区别。

MFC对象实际上并没有把整个Windows对象都包装在其中,它只是有一个窗口句柄而已,这个窗 口句柄如果指向一个实际存在的窗口对象,那么这个MFC对象就是有效的,否则这个MFC对象是空的。

如果你还不明白,请回忆一下,当我们使用MFC创建一 个窗口时,是分两步进行的:

第一步,new一个CWnd对象,这一步是创建MFC对象,但是其中的HWND还是非法的,因为对应的Windows对象还没 有被创建出来;

第二步,调用CWnd的成员函数Create创建真正的Windows对象,同时,把先前创建的MFC的CWnd对象的HWND成员指向该 窗口,这样才算创建完毕一个窗口。

而如果你是用SDK方式,那么只要创建一个WNDCLASS结构,然后调用Create或者CreateEx就创建了一 个窗口。

好,现在回答你的问题,你可以假设,现在你已经有了一个有效窗口句柄,那么你想把这个窗口和一个CWnd对象关联起来怎么办?很简单,用Attach,其实就是让一个CWnd对象的HWND成员指向这个窗口句柄。这就是Attach主要完成的任务。

第二个,关于Detach。如前所述,WNDCLASS其实和CWnd根本没有什么关系。它们之间只是通过CWnd的成员HWND联系起来的。如果把 Attach看做“联姻”的话,那么Detach就是“离婚”了,通俗地说,就是切断一个CWnd对象和一个有效窗口的脐带。为什么要切断呢?因为 CWnd是C++的对象,C++的对象有一个生存期的概念,脱离了该对象的作用域,这个对象就要被销毁,但是Windows对象没有这个特点,当销毁 CWnd对象的时候,我们不一定希望WNDCLASS一起被销毁,那么在此之前,我们就先要把这个“脐带”剪断,以免“城门失火,殃及池鱼”。

另外一个描述:

基本就是把一个句柄附加到一个mfc的对象上

比如你通过loadimage创建了一个handle,现在想用cbitmap类的成员函数,

你就可以声明一个cbitmap对象,通过attach将他们关联在一起,

以后就可以使用cbitmap的成员函数来操作hbitmap了

==========================

黑体字的描述并不准确,根据英文原文的翻译,应该是将一个Windows窗口(Windows window)附加到一个

Cwnd对象(MFC里的概念)上。

具体的操作如第一个描述里面,是将CWnd对象的HWND成员指向这个窗口句柄。(感觉也不够准确,两者应该是一样的了。

都是HWND,赋值即可。)这样描述会比较好:CWnd对象的HWND成员指向这个窗口,操作为将HWND成员赋为:

原有的“有效窗口句柄”。

第二个描述里的用法可以在以后继续验证(调用MFC类的成员函数)。


总结:

Cwnd对象是个空壳壳,需要一个具体的Windows window来填充。

一个代码示例:

void CMyCapView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值

CMyCapDoc* pDoc=(CMyCapDoc*)GetDocument();
if (m_nStatus==1)
{
CWnd srcWnd;
//此处用到了Attach函数,将hwndCapture(一个窗口句柄)attach到上一行新建的Cwnd对象srcWnd上。原因是因为下面的函数参数要求为一个CWnd对象
srcWnd.Attach(hwndCapture);
//CaptureDIB函数参数要求是CWnd类的指针,所以不能直接用hwndCapture,而要将hwndCapture跟一个
//CWnd对象结合起来,使这个CWnd对象就是hwndCapture指向的窗口。
pDoc->m_dib.CaptureDIB(&srcWnd,rectCapture);
//终止鼠标捕获
ReleaseCapture();
//恢复窗口显示模式
CMyCapApp* theApp=(CMyCapApp*)AfxGetApp();
theApp->m_pMainWnd->ShowWindow(SW_NORMAL);
m_nStatus=0;
srcWnd.Detach();
Invalidate(false);
}
CView::OnLButtonUp(nFlags, point);
}


结合操作是出于具体需要——CaptureDib()函数需要一个CWnd对象指针,而不是一个窗口句柄。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: