CWnd::Attach()详解

CWnd::Attach

Attaches a Windows window to a CWnd object.

BOOL Attach(

   HWND hWndNew

);

Parameters

hWndNew

Specifies a handle to a Windows window.

一个概念:C++对象和Windows对象的区别(来自MSDN)

The window object is an object of the C++ CWnd class (or a derived class) that your program creates directly. It comes and goes in response to your program‘s constructor and destructor calls. The Windows window, on the
other hand, is an opaque handle to an internal Windows data structure that corresponds to a window and consumes system resources when present. A Windows window is identified by a "window handle" (HWND) and is created after the CWndobject
is created by a call to the Create member function of class CWnd. The window may be destroyed either by a program call or by a user‘s action. The window handle is stored in the window object‘s m_hWnd member
variable. The following figure shows the relationship between the C++ window object and the Windows window. Creating windows is discussed in Creating Windows. Destroying windows is discussed in Destroying
Window Objects

一段讲解:

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

C++对象(即MFC类CWnd)实际上并没有把整个Windows对象都包装在其中,它只是有一个窗口句柄。(在MSDN上查看CWnd类的成员变量,确实只有一个HWND
hWnd,成员函数有Attach()和Dettach()、Create()等)。这个窗口句柄如果指向一个实际存在的窗口对象,那么这个C++对象就是有效的,否则这个MFC对象是空的。

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

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

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

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

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

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

一个代码示例:

1void CMyCapView::OnLButtonUp(UINT nFlags, CPoint point)

2{

3    // TODO: 在此添加消息处理程序代码和/或调用默认值

4

5    CMyCapDoc* pDoc=(CMyCapDoc*)GetDocument();

6    if (m_nStatus==1)

7    {

8        CWnd srcWnd;

9        //将一个窗口attach到一个CWnd对象上。原因如下句注释;具体见CSDN笔记

10        //MSDN原文:Attaches a Windows window to a CWnd object.

11        srcWnd.Attach(hwndCapture);

12        //CaptureDIB函数参数要求是CWnd类的指针,所以不能直接用hwndCapture,而要将hwndCapture跟一个

13        //CWnd对象结合起来,使这个CWnd对象就是hwndCapture指向的窗口。

14        pDoc->m_dib.CaptureDIB(&srcWnd,rectCapture);

15        //终止鼠标捕获

16        ReleaseCapture();

17        //恢复窗口显示模式

18        CMyCapApp* theApp=(CMyCapApp*)AfxGetApp();

19        theApp->m_pMainWnd->ShowWindow(SW_NORMAL);

20        m_nStatus=0;

21        srcWnd.Detach();

22        Invalidate(false);

23    }

24    CView::OnLButtonUp(nFlags, point);

25}

总结:因为Detach()函数是CWnd对象来调用的,所以可以理解为一个内部空虚的C++对象在呼唤一个有模有样的Windows窗口。

CWnd::Attach()详解,布布扣,bubuko.com

时间: 2024-10-24 04:51:38

CWnd::Attach()详解的相关文章

CWnd::MoveWindow 详解

CWnd::MoveWindow void MoveWindow( int x, int y, int nWidth, int nHeight, BOOL bRepaint = TRUE ); void MoveWindow( LPCRECT lpRect, BOOL bRepaint = TRUE ); 函数功能:该函数改变指定窗口的位置和尺寸.对于顶层窗口,位置和尺寸是相对于屏幕的左上角的:对于子窗口,位置和尺寸是相对于父窗口客户区的左上角坐标的. 函数原型:BOOL MoveWindow(

MoveWindow();函数使用详解

摘自:http://blog.csdn.net/yjkwf/article/details/5281207 CWnd::MoveWindow 详解 2010-02-02 16:08 3432人阅读 评论(0) 收藏 举报 mfc CWnd::MoveWindow void MoveWindow( int x, int y, int nWidth, int nHeight, BOOL bRepaint = TRUE ); void MoveWindow( LPCRECT lpRect, BOOL

EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解

EntityFramework Core 1.1方法理论详解 当我们利用EF Core查询数据库时如果我们不显式关闭变更追踪的话,此时实体是被追踪的,关于变更追踪我们下节再叙.就像我们之前在EF 6.x中讨论的那样,不建议手动关闭变更追踪,对于有些特殊情况下,关闭变更追踪可能会导致许多问题的发生. 实体状态 对于EF Core 1.1中依然有四种状态,有的人说不是有五种状态么,UnChanged.Added.Modified.Deleted.Detached.如果我们按照变更追踪来划分的话,实际

【数字图像处理】三.MFC实现图像灰度、采样和量化功能详解

本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程<数字图像处理>及课件进行讲解,主要通过MFC单文档视图实现显示BMP格式图片,并通过Bitmap进行灰度处理.图片采样和量化功能. 个人认为对初学者VC++6.0可能还是很值得学习的工具,所以采用它来讲解,而不是VS或C#.同时文章比较详细基础,希望该篇文章对你有所帮助~ [数字图像处理]一.MFC详解显示BMP格式图片 [数字图像处理]二.MFC单文档分割窗口显示图片 免费资源下载地址: http://dow

Java--设计模式详解(23种)

一.设计模式的理解 刚开始“不懂”为什么要把很简单的东西搞得那么复杂.后来随着软件开发经验的增加才开始明白我所看到的“复杂”恰恰就是设计模式的精髓所在,我所理解的“简单”就是一把钥匙开一把锁的模式,目的仅仅是着眼于解决现在的问题,而设计模式的“复杂”就在于它是要构造一个“万能钥匙”,目的是提出一种对所有锁的开锁方案.在真正理解设计模式之前我一直在编写“简单”的代码.这个“简单”不是功能的简单,而是设计的简单.简单的设计意味着缺少灵活性,代码很钢硬,只在这个项目里有用,拿到其它的项目中就是垃圾,我

迈向angularjs2系列(2):angular2组件和指令详解

<%= INIT %> 内容 一:angular2 helloworld! 为了简单快速的运行一个ng2的app,那么通过script引入预先编译好的angular2版本和页面的基本框架. index.html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> &l

转载iOS---&gt;NSRunLoop详解

转载--->NSRunLoop(详解) NSRunLoop大部分情况在多线程编程的时候才会用到..但是一般不会用NSRunLoop,因为它不是线程安全的.一般都建议用CFRunLoop,这个是线程安全的.input source and port-based custom source这些操作,是向线程里面添加操作的.添加的这些操作,会在该线程执行空间的调度下执行. 通俗的理解就是如果你创建的了一个子线程,子线程的运行函数如下- (void) subThread (void*)unused { 

MVC之前的那点事儿系列(3):HttpRuntime详解分析(下)(转载)

MVC之前的那点事儿系列(3):HttpRuntime详解分析(下) 文章内容 话说,经过各种各样复杂的我们不知道的内部处理,非托管代码正式开始调用ISPAIRuntime的ProcessRequest方法了(ISPAIRuntime继承了IISPAIRuntime接口,该接口可以和COM进行交互,并且暴露了ProcessRequest接口方法).至于为什么要调用这个方法,大叔也不太清楚,找不到微软相关的资料哦.但大叔确定该方法就是我们进入HttpRuntime的正式大门,接着看吧. publi

expdp impdp 数据库导入导出命令详解

一.创建逻辑目录,该命令不会在操作系统创建真正的目录,最好以system等管理员创建. create directory dpdata1 as 'd:\test\dump'; 二.查看管理理员目录(同时查看操作系统是否存在,因为Oracle并不关心该目录是否存在,如果不存在,则出错) select * from dba_directories; 三.给scott用户赋予在指定目录的操作权限,最好以system等管理员赋予. grant read,write on directory dpdata