﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-挪威的森林-文章分类-Visual C++</title><link>http://www.blogjava.net/kenneth/category/3130.html</link><description>不需要完美的可怕，太快乐如何招架！！！</description><language>zh-cn</language><lastBuildDate>Thu, 08 Mar 2007 06:37:41 GMT</lastBuildDate><pubDate>Thu, 08 Mar 2007 06:37:41 GMT</pubDate><ttl>60</ttl><item><title>句柄的本质</title><link>http://www.blogjava.net/kenneth/articles/11851.html</link><dc:creator>Kenneth Blog</dc:creator><author>Kenneth Blog</author><pubDate>Fri, 02 Sep 2005 13:17:00 GMT</pubDate><guid>http://www.blogjava.net/kenneth/articles/11851.html</guid><wfw:comment>http://www.blogjava.net/kenneth/comments/11851.html</wfw:comment><comments>http://www.blogjava.net/kenneth/articles/11851.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kenneth/comments/commentRss/11851.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kenneth/services/trackbacks/11851.html</trackback:ping><description><![CDATA[<SPAN id=ArticleContent1_ArticleContent1_lblContent>
<P><FONT size=2><STRONG>一、书上定义：</STRONG></FONT></P>
<P><FONT size=2><U>&lt;&lt;Microsoft Windows 3 Developer's Workshop&gt;&gt;(Microsoft Press,by Richard Wilton)</U><BR>&nbsp;&nbsp;&nbsp; 在Windows环境中，句柄是用来标识项目的，这些项目包括：模块(module)、任务(task)、实例 </FONT><FONT size=2>(instance)、文件(file)、内存块(block of memory)、菜单(menu)、控制(control)、字体(font)、资</FONT><FONT size=2>源(resource)，包括图标(icon)，光标 (cursor)，字符串(string)等、GDI对象(GDI object)，包括位</FONT><FONT size=2>图(bitmap)，画刷(brush)，元文件（metafile）,调色板(palette)，画笔(pen)，区域 (region)，以及</FONT><FONT size=2>设备描述表(device context)。 </FONT></P>
<P><FONT size=2><U>&lt;&lt;WINDOWS编程短平快&gt;&gt;(南京大学出版社)：</U><BR>&nbsp;&nbsp;&nbsp; 句柄是WONDOWS用来标识被应用程序所建立或使用的对象的唯一整数，WINDOWS使用各种各样的句柄</FONT><FONT size=2>标识诸如应用程序实例，窗口，控制，位图，GDI对象等等。WINDOWS句柄有点象C语言中的文件句柄。 </FONT></P>
<P><FONT size=2><STRONG>二、MFC源代码：</STRONG></FONT></P>
<P><FONT size=2>#ifdef STRICT<BR>typedef void *<FONT color=#ff0000>HANDLE</FONT>;<BR>#define <FONT color=#ff0000>DECLARE_HANDLE(name)</FONT> struct name##__ { int <FONT color=#ff0000>unused</FONT>; }; typedef struct name##__ *name<BR>#else<BR>typedef PVOID HANDLE;<BR>#define DECLARE_HANDLE(name) typedef HANDLE name<BR>#endif</FONT></P>
<P><FONT size=2>DECLARE_HANDLE(HMODULE); <BR>DECLARE_HANDLE(HINSTANCE); <BR>DECLARE_HANDLE(HLOCAL); <BR>DECLARE_HANDLE(HGLOBAL); <BR>DECLARE_HANDLE(HDC); <BR>DECLARE_HANDLE(HRGN); <BR>DECLARE_HANDLE(HWND); <BR>DECLARE_HANDLE(HMENU); <BR>DECLARE_HANDLE(HACCEL); <BR>DECLARE_HANDLE(HTASK); </FONT></P><FONT size=2>
<P><BR><STRONG>三、理解：</STRONG><BR>&nbsp;&nbsp;&nbsp; HANDLE就是PVOID，也就是无类型指针，<BR>&nbsp;&nbsp;&nbsp; 上面这些资源的句柄Handles都不过是指向struct的指针，至于这个struct的用处，连M$都说unused了，现在解释下M$这么做的意义，这就是所谓数据封装，你可以在你的程序中把M$的内部结构指针传来传去，可是你却不知道它到底指向的内容是什么。</P>
<P>&nbsp;&nbsp;&nbsp; 句柄与指针确实是完全不同的两个概念。句柄仅仅是一个32位整数，WIN32中用于标记某个系统或进程的对象，可以理解为对象索引（由于M$未完全公开相关技术，在一定程度上只能如此理解），这个索引更像是一种映射关系（从句柄到对象指针的映射），而不是纯粹意义上的“数组下标”。 <BR></P>
<P>&nbsp;&nbsp;&nbsp;&nbsp; 句柄可以理解为用于指向或标识内存的一块“资源”，这些资源如：文件(file)、内存块(block of memory)、菜单(menu)等等。操作系统通过句柄来定位核心对象和系统资源。<BR>&nbsp;&nbsp;&nbsp; 指针即为指向内存的“数据或指令”某一单元。</P>
<P>&nbsp;&nbsp;&nbsp; 说的确切一点，句柄实际上是一种指向某种资源的指针，但与指针又有所不同：指针对应着一个数据在内存中的地址，得到了指针就可以自由地修改该数据。Windows并不希望一般程序修改其内部数据结构，因为这样太不安全。所以Windows给每个使用GlobalAlloc等函数声明的内存区域指定一个句柄(本质上仍是一个指针，但不要直接操作它)，平时你只是在调用API函数时利用这个句柄来说明要操作哪段内存。</P>
<P><STRONG>&nbsp;&nbsp;&nbsp; <BR>四、引喻：</STRONG><BR>&nbsp;&nbsp; 牧童遥指杏花村<BR>&nbsp;&nbsp; 牧童的手为指针，杏花村的牌子为句柄，杏花村酒店为对象的实例. </P>
<P></P>
<P><STRONG>附注：获得窗口句柄三种方法</STRONG></P>
<P>1.HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName)&nbsp;</P>
<P dir=ltr style="MARGIN-RIGHT: 0px">&nbsp;&nbsp;&nbsp;HWND FindWindowEx(HWND hwndParent, HWND hwndChildAfter,LPCTSTR lpClassName, LPCTSTR lpWindowName)&nbsp;</P>
<P dir=ltr style="MARGIN-RIGHT: 0px">2.HWND WindowFromPoint(POINT&amp; Point)//获得当前鼠标光标位置的窗口HWND</P>
<P dir=ltr style="MARGIN-RIGHT: 0px">3.BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)</P>
<P dir=ltr style="MARGIN-RIGHT: 0px">&nbsp;&nbsp; BOOL CALLBACK EnumChildWindows(HWND hWndParent, WNDENUMPROC lpEnumFunc,LPARAM lParam)</P>
<P dir=ltr style="MARGIN-RIGHT: 0px">&nbsp;&nbsp; BOOL CALLBACK EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)</P>
<P dir=ltr style="MARGIN-RIGHT: 0px">&nbsp;&nbsp; BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)<BR></P></FONT></SPAN><img src ="http://www.blogjava.net/kenneth/aggbug/11851.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kenneth/" target="_blank">Kenneth Blog</a> 2005-09-02 21:17 <a href="http://www.blogjava.net/kenneth/articles/11851.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>