CWnd与HWND的简单辨析
今天在写一个小的网络应用,需要用到HWND类型的一个参数。而程序中有的“窗口操作句柄”只有一个CWnd类型的指针。这俩不都是“窗口句柄”么?而且反正都是地址直接转换使用如何?结果出现了调用失效的情况。别处自信不会出错,问题只能出在这个参数上了。可是这两个不都是“窗口句柄“?!
既然我加了双引号,显然后来明白了,这显然不是正解。那么怎么解释和区别两者?又怎么灵活使用两者?由于技术水平限制,在此仅仅做简单区分,灵活使用等到我称为伪大神时,再做深究。好,废话少说,进入正题。
首先转载一段文章:
***************************************************
概念:
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来填充。
***************************************************
HWND是句柄,CWnd是MFC窗体类,CWnd中包含HWND句柄成员对象是m_hWnd.
HWND是Windows系统中对所有窗口的一种标识,即窗口句柄。
CWnd是MFC类库中所有窗口类的基类。微软在MFC中将所有窗口的通用操作都封装到了这个类中,如:ShowWindow等等,同时它也封装了窗口句柄即m_hWnd成员。
个人理解,HWND是Window内核处理对象,而MFC对Windows API进行封装而提供了操作类,类中包含了对象句柄的成员变量。系统通过HWND进行操作,而我们则更多的通过CWnd提供的函数来间接操作HWND,进而实现目的操作。
不完全的理解是两者都可以实现某种功能,而且在一定条件下可以互相转换,但是,HWND是CWnd基础的构成部分,CWnd是对HWND操作的类,是一个封装后的成果类,更加高级也更加简化。
两者不同,却密不可分。HWND是CWnd类的组成部分,CWnd对象的成员中有HWND对象。
两者怎么转换?!CWnd类中封装了这么几个成员函数:
CWnd::operator HWND //可cWndp->operator HWND()调用,得到CWnd对象中HWND句柄对象。
//return this == NULL ? NULL : m_hWnd;
CWnd::FromHandle //Returns a pointer to a CWnd object
//when given a handle to a window.
// If a CWnd object is not attached to the handle,
// a temporary CWnd object is created and attached.
//直译过来就是,由传递的HWND类型参数,
//得到一个与之关联的CWnd对象或者一个
//临时的CWnd对象(当所给HWND没有关
//联CWnd对象时)。
//那么,这个函数就可以由一个对象句柄的到所在窗口的指针。
//进而可以从HWnd转换为CWnd。
CWnd::Attach //简单理解就是将HWND句柄与CWnd对象关联。
CWnd::Detach //由于WNDCLASS其实和CWnd根本没有什么关系,
//它们之间只是通过CWnd的成员HWND联系起来的。
//Detach的作用是切断一个CWnd对象和一个有效窗口的联系。
//因为CWnd是C++的对象,C++的对象有一个生存期的概念,脱离了该对象的作用域,
//这个对象就要被销毁,但是Windows对象没有这个特点,当销毁CWnd对象的时候,
//我们不一定希望WNDCLASS一起被
//销毁,那么在此之前,我们就先要把这个联系切断。
//说白了,就是Attach()的逆操作。
CWnd::GetSafeHwnd //得到用于获取窗体的安全句柄
常用的可以如下转换:
CWnd * pCWnd;
HWND Handle;
pCWnd=FromHandle(Handle);
Handle=GetSafeHwnd(pCWnd);
最后自己总结下上面毫无逻辑性的介绍:就是HWND是一个对象句柄,可以指向窗口对象、窗口中的空间对象和其他Windows对象。而CWnd是一个窗口类,它的对象一定代表了一个窗口,CWnd类型指针只能指向CWnd的窗口对象。HWND更加底层。
因为时间原因,此上解释不太靠谱,待手头工作完成后,对CWnd和HWND进行更进一步的学习和探索,再进行补充和修改。如大神看到勿喷,如有理解偏差,欢迎指出共同讨论、修改,一起进步。
另附上指针和句柄的分析:http://www.cnblogs.com/suanec/p/3892940.html
CWnd与HWND的简单辨析的更多相关文章
- (转)CWnd与HWND的区别与转换
一.区别HWND是句柄,CWnd是MFC窗体类,CWnd中包含HWND句柄成员对象是m_hWnd.HWND是Windows系统中对所有窗口的一种标识,即窗口句柄.这是一个SDK概念. CWnd是M ...
- CWnd *和HWnd转换
CWnd *和HWnd转换 CWnd*得到HWnd CWnd wnd; HWND hWnd; hWnd = wnd.m_hWnd; // or ...
- CWnd与HWND的区别与转换
CWnd与HWND的区别与转换 2011-10-20 10:29:30| 分类: VC学习库|字号 订阅 一.区别HWND是句柄,CWnd是MFC窗体类,CWnd中包含HWND句柄成员对象是 ...
- CWnd和HWND的区别(hWnd只是CWnd对象的一个成员变量,代表与这个对象绑定的窗口)
所有控件类都是CWnd类的派生类,CWnd的所有成员函数在控件类中都可以使用.在MFC中,CWnd类是一个很重要的类,它封装了Windows的窗口句柄HWND.在Windows编程中, ...
- CWnd与HWND,GetSafeHwnd()与m_hWnd
HWND是Windows系统中的窗口句柄,CWnd是MFC中的窗体类,两者的所属不同.CWnd对HWND进行了封装类,更加高级也更加简化. HWND是Window内核处理对象,系统通过HWND进行操作 ...
- URL和URI简单辨析
URI 全称为 Universal Resource Identifier,统一资源标识符,用来唯一的标识一个资源. URL 全称为Universal Resource Locator,统一资源定位器 ...
- C语言工具的简单辨析
- Injection的简单辨析
依赖注入(injection)是一种对任何编程语言都有效的概念.依赖注入背后的一般概念称为控制反转.根据这个概念,类不应该静态配置其依赖项,而应该从外部配置. 如果Java类使用此类的实例,则Java ...
- 深入解析Windows窗口创建和消息分发(三个核心问题:怎么将不同的窗口过程勾到一起,将不同的hwnd消息分发给对应的CWnd类去处理,CWnd如何简单有效的去处理消息,由浅入深,非常清楚) good
笔记:争取不用看下面的内容,只看自己的笔记,就能记住这个流程,就算明白了: _tWinMain-->AfxWinMain,它调用四个函数: -->AfxWinInit用于做一些框架的初始化 ...
随机推荐
- 在windows系统的文件右键菜单中增加“命令提示符”
本实用小工具能够在windows系统的文件右键菜单中增加“命令提示符”,方便快速进入制定文件的命令提示窗口,避免逐层输入或复制文件夹路径,极其实用. 工具下载地址如下:360云盘(访问密码:5b71) ...
- 通过PID获取进程路径的几种方法
通过PID获取进程路径的几种方法 想获得进程可执行文件的路径最常用的方法是通过GetModuleFileNameEx函数获得可执行文件的模块路径这个函数从Windows NT 4.0开始到现在的Vis ...
- cocos2dx游戏开发——微信打飞机学习笔记(三)——WelcomeScene的搭建
一.场景与层的关系: cocos2dx的框架可以说主要由导演,场景,层,精灵来构成: 1.其中导演,意如其名,就是操控整个游戏的一个单例,管理着整个游戏. 2.场景就像电影的一幕剧情,所以说,懂得如何 ...
- 【SSH】 之 Struts2环境搭建及简单应用开发
在上一篇文章中,我们一起了解了一下struts2的工作机制原理,接下来让我们进行一下简单应用的开发 (一)配置环境 1.建立web项目 2.导入jar包 其中struts2中有很多jar包,我们不需要 ...
- Java Math floor round ceil 函数
public final class Math extends Object public static double floor(double a) public static long round ...
- 记一次小团队Git实践(中)
对于初学者,从使用上先入手,往往学的最快,并从中汲取教训,再回头更深入的学习,效果尤佳. 安装git 安装git自不必说,mac已经内置了git,linux下一个命令就能搞定,windows下需要下载 ...
- Hdu2544 最短路径 四种方法
Problem Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要 ...
- 手持终端打印POS机(安装移动销售开单订货会软件)无线传输到订货会后台销售管理系统
当今的服装市场是品牌竞争时代,产品能否紧随潮流前线并迅速推出市场抢得先机,是品牌成功与否的关键.而订货会是每个鞋服企业新产品走向市场至关重要的开端,订货会如何演绎.成功与否,与品牌在竞争洪流中的命运息 ...
- Manthan, Codefest 16
暴力 A - Ebony and Ivory import java.util.*; import java.io.*; public class Main { public static void ...
- iOS 安装Cocoapods以及安装第三方库的操作流程
安装cocoapods的流程: 1.打开终端,输入: sudo gem update —system 2.输入密码,稍等 3.gem sources --remove https://rubygem ...