句柄类 windows核心对象

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

C++对象(即MFCCWnd)实际上并没有把整个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就创建了一 个窗口。

 

. attach()detach()的用法

用Attach:其实就是让一个C++对象——CWnd对象的HWND成员等于这个窗口句柄。这就是Attach主要完成的任务。 

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

 

void CMyCapView::OnLButtonUp(UINT nFlags, CPoint point)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    
    CMyCapDoc* pDoc=(CMyCapDoc*)GetDocument();
    if (m_nStatus==1)
    {
        CWnd srcWnd;
        //将一个窗口attach到一个CWnd对象上。原因如下句注释;具体见CSDN笔记
        //MSDN原文:Attaches a Windows window to a CWnd object.
        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);
}


注意:

 所有临时MFC对象和持久(permanent)MFC对象都是以线程为单位进行维护管理的。也就是说,一个线程不能够访问另一个线程的MFC包装类对象,不管它是临时的还是持久的。

 
 为了在不同的线程间传递这些Windows对象,总是应该通过HANDLE类型传递。从一个线程向另一个线程传递MFC包装对象将可能引起不可预料的结果。
二.句柄泄漏
一般,create()创建句柄后,一定要closehandle()关闭句柄,否则问题很麻烦。
#include <windows.h>
void fun1(void);
void fun2(void);
void fun3(void);
void fun4(void);
int main(int argc,char*argv[])
{
	while(1)
	{
		fun1();
		fun2();
		Sleep(100);
	}
	return 0;
}
void fun1(void)
{
	fun3();
}
void fun2(void)
{
	fun4();
}
void fun3(void)
{
	HANDLE hEvent;
	hEvent=CreateEvent(NULL,TRUE,TRUE,NULL);
	CloseHandle(hEvent);
}
void fun4(void)
{
	HANDLE hEvent2;
	hEvent2=CreateEvent(NULL,TRUE,TRUE,NULL);//这里只打开但是没关闭句柄
}

一般可以在windows任务管理器中查看句柄数。
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值