<?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>C++博客-C++ Programmer's Cookbook-随笔分类-Windows API</title><link>http://www.cppblog.com/mzty/category/298.html</link><description>&lt;br/&gt;  
&lt;br/&gt;
&lt;a href = "http://www.cppblog.com/mzty/archive/2007/03/02/19109.html"&gt;&lt;font size = 5 color ="#00FFFF"&gt;{C++ 基础}&lt;font/&gt;&lt;/a&gt;

&lt;a href = "http://www.cppblog.com/mzty/archive/2007/08/13/29922.html"&gt;&lt;font size = 5 color ="#00FFFF"&gt;{C++ 高级}&lt;font/&gt;&lt;/a&gt;

&lt;a href = "http://www.cppblog.com/mzty/archive/2007/04/16/22064.html"&gt;&lt;font size = 5 color ="#00FFFF"&gt;{C#界面，C++核心算法}&lt;font/&gt;&lt;/a&gt;

&lt;a href = "http://www.cppblog.com/mzty/archive/2007/03/04/19163.html"&gt;&lt;font size = 5 color ="#00FFFF"&gt;{设计模式}&lt;font/&gt;&lt;/a&gt;

&lt;a href = "
http://www.cppblog.com/mzty/archive/2007/03/04/19167.html"&gt;&lt;font size = 5 color ="#FF0000"&gt;{C#基础}&lt;font/&gt;&lt;/a&gt;





</description><language>zh-cn</language><lastBuildDate>Mon, 19 May 2008 13:34:32 GMT</lastBuildDate><pubDate>Mon, 19 May 2008 13:34:32 GMT</pubDate><ttl>60</ttl><item><title>windows消息机制</title><link>http://www.cppblog.com/mzty/archive/2006/11/24/15619.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Fri, 24 Nov 2006 05:08:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2006/11/24/15619.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/15619.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2006/11/24/15619.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/15619.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/15619.html</trackback:ping><description><![CDATA[
		<p>一 Windows中有一个系统消息队列，对于每一个正在执行的Windows应用程序,系统为其建立一个“消息队列”，即应用程序队列，用来存放该程序可能创建的各种窗口的消息。应用程序中含有一段称作“消息循环”的代码，用来从消息队列中检索这些消息并把它们分发到相应的窗口函数中。</p>
		<p>
				<img height="211" alt="o_windowsmessage2.jpg" src="http://www.cppblog.com/images/cppblog_com/mzty/2021/o_windowsmessage2.jpg" width="450" border="0" />
				<br />
				<br />二 Windows为当前执行的每个Windows程序维护一个「消息队列」。在发生输入事件之后，Windows将事件转换为一个「消息」并将消息放入程序的消息队列中。程序通过执行一块称之为「消息循环」的程序代码从消息队列中取出消息：<br />while(GetMessage (&amp;msg, NULL, 0, 0))        <br />{        <br />    TranslateMessage (&amp;msg) ;        <br />    DispatchMessage (&amp;msg) ;        <br />}</p>
		<p>msg变量是型态为MSG的结构，型态MSG在WINUSER.H中定义如下：<br />typedef struct tagMSG        <br />{        <br />    HWND   hwnd ;        <br />    UINT   message ;        <br />    WPARAM wParam ;        <br />    LPARAM lParam ;        <br />    DWORD  time ;        <br />    POINT  pt ;        <br />}        <br />MSG, * PMSG ;<br />      <br />POINT数据型态也是一个结构，它在WINDEF.H中定义如下：<br />typedef struct tagPOINT        <br />{        <br />    LONG  x ;        <br />    LONG  y ;        <br />}        <br />POINT, * PPOINT;<br />TranslateMessage(&amp;msg); 将msg结构传给Windows，进行一些键盘转换。（关于这一点，我们将在第六章中深入讨论。）<br />DispatchMessage(&amp;msg);又将msg结构回传给Windows。然后，Windows将该消息发送给适当的窗口消息处理程序，让它进行处理。这也就是说，Windows将呼叫窗口消息处理程序。在HELLOWIN中，这个窗口消息处理程序就是WndProc函数。处理完消息之后，WndProc传回到Windows。此时，Windows还停留在DispatchMessage呼叫中。在结束DispatchMessage呼叫的处理之后，Windows回到HELLOWIN程序中，并且接着从下一个GetMessage呼叫开始消息循环。<br />        <br />三 队列化消息与非队列化消息<br />    <br />消息能够被分为「队列化的」和「非队列化的」。队列化的消息是由Windows放入程序消息队列中的。在程序的消息循环中，重新传回并分配给窗口消息处理程序。非队列化的消息在Windows呼叫窗口时直接送给窗口消息处理程序。也就是说，队列化的消息被「发送」给消息队列，而非队列化的消息则「发送」给窗口消息处理程序。任何情况下，窗口消息处理程序都将获得窗口所有的消息--包括队列化的和非队列化的。窗口消息处理程序是窗口的「消息中心」。</p>
		<p>队列化消息基本上是使用者输入的结果，以击键（如WM_KEYDOWN和WM_KEYUP消息）、击键产生的字符（WM_CHAR）、鼠标移动（WM_MOUSEMOVE）和鼠标按钮（WM_LBUTTONDOWN）的形式给出。队列化消息还包含时钟消息（WM_TIMER）、更新消息（WM_PAINT）和退出消息（WM_QUIT）。</p>
		<p>非队列化消息则是其它消息。在许多情况下，非队列化消息来自呼叫特定的Windows函数。例如，当WinMain呼叫CreateWindow时，Windows将建立窗口并在处理中给窗口消息处理程序发送一个WM_CREATE消息。当WinMain呼叫ShowWindow时，Windows将给窗口消息处理程序发送WM_SIZE和WM_SHOWWINDOW消息。当WinMain呼叫UpdateWindow时，Windows将给窗口消息处理程序发送WM_PAINT消息。键盘或鼠标输入时发出的队列化消息信号，也能在非队列化消息中出现。例如，用键盘或鼠标选择了一个菜单项时，键盘或鼠标消息就是队列化的，而说明菜单项已选中的WM_COMMAND消息则可能就是非队列化的。</p>
		<p>四 SendMessage()与PostMessage()之间的区别是什么？<br />它们两者是用于向应用程序发送消息的。PostMessagex()将消息直接加入到应用程序的消息队列中，不等程序返回就退出；而SendMessage()则刚好相反，应用程序处理完此消息后，它才返回。我想下图能够比较好的体现这两个函数的关系：<br /><br /><img height="407" alt="o_postmessage.gif" src="http://www.cppblog.com/images/cppblog_com/mzty/2021/o_postmessage.gif" width="609" border="0" /></p>
		<p>
				<br />五 函数peekmessage和getmessage的区别？</p>
		<p>两个函数主要有以下两个区别:<br />1.GetMessage将等到有合适的消息时才返回,而PeekMessage只是撇一下消息队列。<br />2.GetMessage会将消息从队列中删除,而PeekMessage可以设置最后一个参数wRemoveMsg来决定是否将消息保留在队列中。<br /></p>
<img src ="http://www.cppblog.com/mzty/aggbug/15619.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2006-11-24 13:08 <a href="http://www.cppblog.com/mzty/archive/2006/11/24/15619.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>windows消息大全 </title><link>http://www.cppblog.com/mzty/archive/2006/11/24/15618.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Fri, 24 Nov 2006 05:00:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2006/11/24/15618.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/15618.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2006/11/24/15618.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/15618.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/15618.html</trackback:ping><description><![CDATA[
		<p style="MARGIN: 8px; LINE-HEIGHT: 150%">
		</p>
		<table style="FLOAT: right; BORDER-COLLAPSE: collapse" cellspacing="0" cellpadding="0" border="0">
				<tbody>
						<tr>
						</tr>
				</tbody>
		</table>消息，就是指Windows发出的一个通知，告诉应用程序某个事情发生了。例如，单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序。消息本身是作为一个记录传递给应用程序的，这个记录中包含了消息的类型以及其他信息。例如，对于单击鼠标所产生的消息来说，这个记录中包含了单击鼠标时的坐标。这个记录类型叫做TMsg， 
<p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%"></p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">它在Windows单元中是这样声明的： 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">type 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">TMsg = packed record 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">hwnd: HWND; / /窗口句柄 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">message: UINT; / /消息常量标识符 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">wParam: WPARAM ; // 32位消息的特定附加信息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">lParam: LPARAM ; // 32位消息的特定附加信息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">time: DWORD; / /消息创建时的时间 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">pt: TPoint; / /消息创建时的鼠标位置 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">end; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%"></p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">消息中有什么？ 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">是否觉得一个消息记录中的信息像希腊语一样？如果是这样，那么看一看下面的解释： 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">hwnd 32位的窗口句柄。窗口可以是任何类型的屏幕对象，因为Win32能够维护大多数可视对象的句柄(窗口、对话框、按钮、编辑框等)。 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">message 用于区别其他消息的常量值，这些常量可以是Windows单元中预定义的常量，也可以是自定义的常量。 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">wParam 通常是一个与消息有关的常量值，也可能是窗口或控件的句柄。 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">lParam 通常是一个指向内存中数据的指针。由于W P a r a m、l P a r a m和P o i n t e r都是3 2位的， 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">因此，它们之间可以相互转换。 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%"></p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NULL = $0000; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CREATE = $0001; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">应用程序创建一个窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DESTROY = $0002; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">一个窗口被销毁 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MOVE = $0003; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">移动一个窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SIZE = $0005; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">改变一个窗口的大小 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_ACTIVATE = $0006; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">一个窗口被激活或失去激活状态； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SETFOCUS = $0007; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">获得焦点后 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_KILLFOCUS = $0008; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">失去焦点 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_ENABLE = $000A; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">改变enable状态 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SETREDRAW = $000B; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">设置窗口是否能重画 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SETTEXT = $000C; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">应用程序发送此消息来设置一个窗口的文本 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_GETTEXT = $000D; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">应用程序发送此消息来复制对应窗口的文本到缓冲区 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_GETTEXTLENGTH = $000E; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">得到与一个窗口有关的文本的长度（不包含空字符） 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PAINT = $000F; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">要求一个窗口重画自己 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CLOSE = $0010; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个窗口或应用程序要关闭时发送一个信号 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_QUERYENDSESSION = $0011; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户选择结束对话框或程序自己调用ExitWindows函数 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_QUIT = $0012; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">用来结束程序运行或当程序调用postquitmessage函数 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_QUERYOPEN = $0013; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户窗口恢复以前的大小位置时，把此消息发送给某个图标 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_ERASEBKGND = $0014; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当窗口背景必须被擦除时（例在窗口改变大小时） 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SYSCOLORCHANGE = $0015; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当系统颜色改变时，发送此消息给所有顶级窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_ENDSESSION = $0016; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当系统进程发出WM_QUERYENDSESSION消息后，此消息发送给应用程序， 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">通知它对话是否结束 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SYSTEMERROR = $0017; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SHOWWINDOW = $0018; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当隐藏或显示窗口是发送此消息给这个窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_ACTIVATEAPP = $001C; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发此消息给应用程序哪个窗口是激活的，哪个是非激活的； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_FONTCHANGE = $001D; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当系统的字体资源库变化时发送此消息给所有顶级窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_TIMECHANGE = $001E; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当系统的时间变化时发送此消息给所有顶级窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CANCELMODE = $001F; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息来取消某种正在进行的摸态（操作） 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SETCURSOR = $0020; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">如果鼠标引起光标在某个窗口中移动且鼠标输入没有被捕获时，就发消息给某个窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MOUSEACTIVATE = $0021; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当光标在某个非激活的窗口中而用户正按着鼠标的某个键发送此消息给当前窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CHILDACTIVATE = $0022; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息给MDI子窗口当用户点击此窗口的标题栏，或当窗口被激活，移动，改变大小 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_QUEUESYNC = $0023; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息由基于计算机的训练程序发送，通过WH_JOURNALPALYBACK的hook程序 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">分离出用户输入消息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_GETMINMAXINFO = $0024; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息发送给窗口当它将要改变大小或位置； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PAINTICON = $0026; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送给最小化窗口当它图标将要被重画 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_ICONERASEBKGND = $0027; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息发送给某个最小化窗口，仅当它在画图标前它的背景必须被重画 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NEXTDLGCTL = $0028; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息给一个对话框程序去更改焦点位置 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SPOOLERSTATUS = $002A; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">每当打印管理列队增加或减少一条作业时发出此消息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DRAWITEM = $002B; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当button，combobox，listbox，menu的可视外观改变时发送 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息给这些空件的所有者 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MEASUREITEM = $002C; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当button, combo box, list box, list view control, or menu item 被创建时 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息给控件的所有者 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DELETEITEM = $002D; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当the list box 或 combo box 被销毁 或 当 某些项被删除通过LB_DELETESTRING, LB_RESETCONTENT, CB_DELETESTRING, or CB_RESETCONTENT 消息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_VKEYTOITEM = $002E; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息有一个LBS_WANTKEYBOARDINPUT风格的发出给它的所有者来响应WM_KEYDOWN消息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CHARTOITEM = $002F; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息由一个LBS_WANTKEYBOARDINPUT风格的列表框发送给他的所有者来响应WM_CHAR消息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SETFONT = $0030; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当绘制文本时程序发送此消息得到控件要用的颜色 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_GETFONT = $0031; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">应用程序发送此消息得到当前控件绘制文本的字体 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SETHOTKEY = $0032; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">应用程序发送此消息让一个窗口与一个热键相关连 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_GETHOTKEY = $0033; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">应用程序发送此消息来判断热键与某个窗口是否有关联 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_QUERYDRAGICON = $0037; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息发送给最小化窗口，当此窗口将要被拖放而它的类中没有定义图标，应用程序能返回一个图标或光标的句柄，当用户拖放图标时系统显示这个图标或光标 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_COMPAREITEM = $0039; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息来判定combobox或listbox新增加的项的相对位置 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_GETOBJECT = $003D; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_COMPACTING = $0041; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">显示内存已经很少了 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_WINDOWPOSCHANGING = $0046; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息给那个窗口的大小和位置将要被改变时，来调用setwindowpos函数或其它窗口管理函数 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_WINDOWPOSCHANGED = $0047; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息给那个窗口的大小和位置已经被改变时，来调用setwindowpos函数或其它窗口管理函数 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_POWER = $0048;（适用于16位的windows） 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当系统将要进入暂停状态时发送此消息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_COPYDATA = $004A; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个应用程序传递数据给另一个应用程序时发送此消息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CANCELJOURNAL = $004B; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当某个用户取消程序日志激活状态，提交此消息给程序 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NOTIFY = $004E; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当某个控件的某个事件已经发生或这个控件需要得到一些信息时，发送此消息给它的父窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_INPUTLANGCHANGEREQUEST = $0050; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户选择某种输入语言，或输入语言的热键改变 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_INPUTLANGCHANGE = $0051; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当平台现场已经被改变后发送此消息给受影响的最顶级窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_TCARD = $0052; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当程序已经初始化windows帮助例程时发送此消息给应用程序 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_HELP = $0053; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息显示用户按下了F1，如果某个菜单是激活的，就发送此消息个此窗口关联的菜单，否则就 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送给有焦点的窗口，如果当前都没有焦点，就把此消息发送给当前激活的窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_USERCHANGED = $0054; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户已经登入或退出后发送此消息给所有的窗口，当用户登入或退出时系统更新用户的具体 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">设置信息，在用户更新设置时系统马上发送此消息； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NOTIFYFORMAT = $0055; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">公用控件，自定义控件和他们的父窗口通过此消息来判断控件是使用ANSI还是UNICODE结构 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">在WM_NOTIFY消息，使用此控件能使某个控件与它的父控件之间进行相互通信 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CONTEXTMENU = $007B; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户某个窗口中点击了一下右键就发送此消息给这个窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_STYLECHANGING = $007C; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当调用SETWINDOWLONG函数将要改变一个或多个 窗口的风格时发送此消息给那个窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_STYLECHANGED = $007D; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当调用SETWINDOWLONG函数一个或多个 窗口的风格后发送此消息给那个窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DISPLAYCHANGE = $007E; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当显示器的分辨率改变后发送此消息给所有的窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_GETICON = $007F; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息发送给某个窗口来返回与某个窗口有关连的大图标或小图标的句柄； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SETICON = $0080; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序发送此消息让一个新的大图标或小图标与某个窗口关联； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCCREATE = $0081; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当某个窗口第一次被创建时，此消息在WM_CREATE消息发送前发送； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCDESTROY = $0082; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息通知某个窗口，非客户区正在销毁 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCCALCSIZE = $0083; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当某个窗口的客户区域必须被核算时发送此消息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCHITTEST = $0084;//移动鼠标，按住或释放鼠标时发生 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCPAINT = $0085; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序发送此消息给某个窗口当它（窗口）的框架必须被绘制时； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCACTIVATE = $0086; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息发送给某个窗口 仅当它的非客户区需要被改变来显示是激活还是非激活状态； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_GETDLGCODE = $0087; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息给某个与对话框程序关联的控件，widdows控制方位键和TAB键使输入进入此控件 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">通过响应WM_GETDLGCODE消息，应用程序可以把他当成一个特殊的输入控件并能处理它 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCMOUSEMOVE = $00A0; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当光标在一个窗口的非客户区内移动时发送此消息给这个窗口 //非客户区为：窗体的标题栏及窗 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">的边框体 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCLBUTTONDOWN = $00A1; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当光标在一个窗口的非客户区同时按下鼠标左键时提交此消息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCLBUTTONUP = $00A2; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户释放鼠标左键同时光标某个窗口在非客户区十发送此消息； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCLBUTTONDBLCLK = $00A3; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户双击鼠标左键同时光标某个窗口在非客户区十发送此消息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCRBUTTONDOWN = $00A4; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户按下鼠标右键同时光标又在窗口的非客户区时发送此消息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCRBUTTONUP = $00A5; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户释放鼠标右键同时光标又在窗口的非客户区时发送此消息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCRBUTTONDBLCLK = $00A6; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户双击鼠标右键同时光标某个窗口在非客户区十发送此消息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCMBUTTONDOWN = $00A7; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户按下鼠标中键同时光标又在窗口的非客户区时发送此消息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCMBUTTONUP = $00A8; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户释放鼠标中键同时光标又在窗口的非客户区时发送此消息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCMBUTTONDBLCLK = $00A9; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户双击鼠标中键同时光标又在窗口的非客户区时发送此消息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_KEYFIRST = $0100; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_KEYDOWN = $0100; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//按下一个键 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_KEYUP = $0101; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//释放一个键 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CHAR = $0102; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//按下某键，并已发出WM_KEYDOWN， WM_KEYUP消息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DEADCHAR = $0103; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用translatemessage函数翻译WM_KEYUP消息时发送此消息给拥有焦点的窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SYSKEYDOWN = $0104; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户按住ALT键同时按下其它键时提交此消息给拥有焦点的窗口； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SYSKEYUP = $0105; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户释放一个键同时ALT 键还按着时提交此消息给拥有焦点的窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SYSCHAR = $0106; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当WM_SYSKEYDOWN消息被TRANSLATEMESSAGE函数翻译后提交此消息给拥有焦点的窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SYSDEADCHAR = $0107; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当WM_SYSKEYDOWN消息被TRANSLATEMESSAGE函数翻译后发送此消息给拥有焦点的窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_KEYLAST = $0108; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_INITDIALOG = $0110; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">在一个对话框程序被显示前发送此消息给它，通常用此消息初始化控件和执行其它任务 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_COMMAND = $0111; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户选择一条菜单命令项或当某个控件发送一条消息给它的父窗口，一个快捷键被翻译 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SYSCOMMAND = $0112; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户选择窗口菜单的一条命令或当用户选择最大化或最小化时那个窗口会收到此消息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_TIMER = $0113; //发生了定时器事件 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_HSCROLL = $0114; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个窗口标准水平滚动条产生一个滚动事件时发送此消息给那个窗口，也发送给拥有它的控件 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_VSCROLL = $0115; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个窗口标准垂直滚动条产生一个滚动事件时发送此消息给那个窗口也，发送给拥有它的控件 WM_INITMENU = $0116; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个菜单将要被激活时发送此消息，它发生在用户菜单条中的某项或按下某个菜单键，它允许程序在显示前更改菜单 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_INITMENUPOPUP = $0117; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个下拉菜单或子菜单将要被激活时发送此消息，它允许程序在它显示前更改菜单，而不要改变全部 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MENUSELECT = $011F; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户选择一条菜单项时发送此消息给菜单的所有者（一般是窗口） 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MENUCHAR = $0120; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当菜单已被激活用户按下了某个键（不同于加速键），发送此消息给菜单的所有者； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_ENTERIDLE = $0121; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个模态对话框或菜单进入空载状态时发送此消息给它的所有者，一个模态对话框或菜单进入空载状态就是在处理完一条或几条先前的消息后没有消息它的列队中等待 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MENURBUTTONUP = $0122; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MENUDRAG = $0123; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MENUGETOBJECT = $0124; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_UNINITMENUPOPUP = $0125; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MENUCOMMAND = $0126; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CHANGEUISTATE = $0127; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_UPDATEUISTATE = $0128; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_QUERYUISTATE = $0129; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CTLCOLORMSGBOX = $0132; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">在windows绘制消息框前发送此消息给消息框的所有者窗口，通过响应这条消息，所有者窗口可以通过使用给定的相关显示设备的句柄来设置消息框的文本和背景颜色 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CTLCOLOREDIT = $0133; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个编辑型控件将要被绘制时发送此消息给它的父窗口；通过响应这条消息，所有者窗口可以通过使用给定的相关显示设备的句柄来设置编辑框的文本和背景颜色 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CTLCOLORLISTBOX = $0134; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个列表框控件将要被绘制前发送此消息给它的父窗口；通过响应这条消息，所有者窗口可以通过使用给定的相关显示设备的句柄来设置列表框的文本和背景颜色 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CTLCOLORBTN = $0135; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个按钮控件将要被绘制时发送此消息给它的父窗口；通过响应这条消息，所有者窗口可以通过使用给定的相关显示设备的句柄来设置按纽的文本和背景颜色 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CTLCOLORDLG = $0136; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个对话框控件将要被绘制前发送此消息给它的父窗口；通过响应这条消息，所有者窗口可以通过使用给定的相关显示设备的句柄来设置对话框的文本背景颜色 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CTLCOLORSCROLLBAR= $0137; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个滚动条控件将要被绘制时发送此消息给它的父窗口；通过响应这条消息，所有者窗口可以通过使用给定的相关显示设备的句柄来设置滚动条的背景颜色 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CTLCOLORSTATIC = $0138; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个静态控件将要被绘制时发送此消息给它的父窗口；通过响应这条消息，所有者窗口可以通过使用给定的相关显示设备的句柄来设置静态控件的文本和背景颜色 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MOUSEFIRST = $0200; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MOUSEMOVE = $0200; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">// 移动鼠标 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_LBUTTONDOWN = $0201; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//按下鼠标左键 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_LBUTTONUP = $0202; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//释放鼠标左键 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_LBUTTONDBLCLK = $0203; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//双击鼠标左键 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_RBUTTONDOWN = $0204; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//按下鼠标右键 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_RBUTTONUP = $0205; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//释放鼠标右键 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_RBUTTONDBLCLK = $0206; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//双击鼠标右键 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MBUTTONDOWN = $0207; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//按下鼠标中键 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MBUTTONUP = $0208; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//释放鼠标中键 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MBUTTONDBLCLK = $0209; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//双击鼠标中键 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MOUSEWHEEL = $020A; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当鼠标轮子转动时发送此消息个当前有焦点的控件 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MOUSELAST = $020A; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PARENTNOTIFY = $0210; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当MDI子窗口被创建或被销毁，或用户按了一下鼠标键而光标在子窗口上时发送此消息给它的父窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_ENTERMENULOOP = $0211; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息通知应用程序的主窗口that已经进入了菜单循环模式 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_EXITMENULOOP = $0212; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息通知应用程序的主窗口that已退出了菜单循环模式 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NEXTMENU = $0213; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SIZING = 532; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户正在调整窗口大小时发送此消息给窗口；通过此消息应用程序可以监视窗口大小和位置也可以修改他们 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CAPTURECHANGED = 533; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息 给窗口当它失去捕获的鼠标时； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MOVING = 534; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户在移动窗口时发送此消息，通过此消息应用程序可以监视窗口大小和位置也可以修改他们； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_POWERBROADCAST = 536; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息发送给应用程序来通知它有关电源管理事件； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DEVICECHANGE = 537; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当设备的硬件配置改变时发送此消息给应用程序或设备驱动程序 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_STARTCOMPOSITION = $010D; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_ENDCOMPOSITION = $010E; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_COMPOSITION = $010F; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_KEYLAST = $010F; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_SETCONTEXT = $0281; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_NOTIFY = $0282; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_CONTROL = $0283; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_COMPOSITIONFULL = $0284; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_SELECT = $0285; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_CHAR = $0286; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_REQUEST = $0288; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_KEYDOWN = $0290; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_KEYUP = $0291; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDICREATE = $0220; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">应用程序发送此消息给多文档的客户窗口来创建一个MDI 子窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDIDESTROY = $0221; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">应用程序发送此消息给多文档的客户窗口来关闭一个MDI 子窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDIACTIVATE = $0222; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">应用程序发送此消息给多文档的客户窗口通知客户窗口激活另一个MDI子窗口，当客户窗口收到此消息后，它发出WM_MDIACTIVE消息给MDI子窗口（未激活）激活它； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDIRESTORE = $0223; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序 发送此消息给MDI客户窗口让子窗口从最大最小化恢复到原来大小 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDINEXT = $0224; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序 发送此消息给MDI客户窗口激活下一个或前一个窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDIMAXIMIZE = $0225; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序发送此消息给MDI客户窗口来最大化一个MDI子窗口； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDITILE = $0226; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序 发送此消息给MDI客户窗口以平铺方式重新排列所有MDI子窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDICASCADE = $0227; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序 发送此消息给MDI客户窗口以层叠方式重新排列所有MDI子窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDIICONARRANGE = $0228; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序 发送此消息给MDI客户窗口重新排列所有最小化的MDI子窗口 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDIGETACTIVE = $0229; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序 发送此消息给MDI客户窗口来找到激活的子窗口的句柄 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDISETMENU = $0230; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序 发送此消息给MDI客户窗口用MDI菜单代替子窗口的菜单 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_ENTERSIZEMOVE = $0231; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_EXITSIZEMOVE = $0232; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DROPFILES = $0233; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDIREFRESHMENU = $0234; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MOUSEHOVER = $02A1; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MOUSELEAVE = $02A3; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CUT = $0300; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序发送此消息给一个编辑框或combobox来删除当前选择的文本 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_COPY = $0301; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序发送此消息给一个编辑框或combobox来复制当前选择的文本到剪贴板 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PASTE = $0302; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序发送此消息给editcontrol或combobox从剪贴板中得到数据 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CLEAR = $0303; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序发送此消息给editcontrol或combobox清除当前选择的内容； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_UNDO = $0304; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序发送此消息给editcontrol或combobox撤消最后一次操作 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_RENDERFORMAT = $0305； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%"></p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_RENDERALLFORMATS = $0306; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DESTROYCLIPBOARD = $0307; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当调用ENPTYCLIPBOARD函数时 发送此消息给剪贴板的所有者 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DRAWCLIPBOARD = $0308; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当剪贴板的内容变化时发送此消息给剪贴板观察链的第一个窗口；它允许用剪贴板观察窗口来 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">显示剪贴板的新内容； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PAINTCLIPBOARD = $0309; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当剪贴板包含CF_OWNERDIPLAY格式的数据并且剪贴板观察窗口的客户区需要重画； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_VSCROLLCLIPBOARD = $030A; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SIZECLIPBOARD = $030B; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当剪贴板包含CF_OWNERDIPLAY格式的数据并且剪贴板观察窗口的客户区域的大小已经改变是此消息通过剪贴板观察窗口发送给剪贴板的所有者； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_ASKCBFORMATNAME = $030C; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">通过剪贴板观察窗口发送此消息给剪贴板的所有者来请求一个CF_OWNERDISPLAY格式的剪贴板的名字 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CHANGECBCHAIN = $030D; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个窗口从剪贴板观察链中移去时发送此消息给剪贴板观察链的第一个窗口； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_HSCROLLCLIPBOARD = $030E; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息通过一个剪贴板观察窗口发送给剪贴板的所有者 ；它发生在当剪贴板包含CFOWNERDISPALY格式的数据并且有个事件在剪贴板观察窗的水平滚动条上；所有者应滚动剪贴板图象并更新滚动条的值； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_QUERYNEWPALETTE = $030F; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息发送给将要收到焦点的窗口，此消息能使窗口在收到焦点时同时有机会实现他的逻辑调色板 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PALETTEISCHANGING= $0310; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个应用程序正要实现它的逻辑调色板时发此消息通知所有的应用程序 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PALETTECHANGED = $0311; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息在一个拥有焦点的窗口实现它的逻辑调色板后发送此消息给所有顶级并重叠的窗口，以此来改变系统调色板 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_HOTKEY = $0312; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户按下由REGISTERHOTKEY函数注册的热键时提交此消息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PRINT = 791; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">应用程序发送此消息仅当WINDOWS或其它应用程序发出一个请求要求绘制一个应用程序的一部分； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PRINTCLIENT = 792; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_HANDHELDFIRST = 856; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_HANDHELDLAST = 863; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PENWINFIRST = $0380; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PENWINLAST = $038F; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_COALESCE_FIRST = $0390; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_COALESCE_LAST = $039F; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_FIRST = $03E0; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_INITIATE = WM_DDE_FIRST + 0; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">一个DDE客户程序提交此消息开始一个与服务器程序的会话来响应那个指定的程序和主题名； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_TERMINATE = WM_DDE_FIRST + 1; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">一个DDE应用程序（无论是客户还是服务器）提交此消息来终止一个会话； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_ADVISE = WM_DDE_FIRST + 2; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">一个DDE客户程序提交此消息给一个DDE服务程序来请求服务器每当数据项改变时更新它 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_UNADVISE = WM_DDE_FIRST + 3; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">一个DDE客户程序通过此消息通知一个DDE服务程序不更新指定的项或一个特殊的剪贴板格式的项 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_ACK = WM_DDE_FIRST + 4; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息通知一个DDE（动态数据交换）程序已收到并正在处理WM_DDE_POKE, WM_DDE_EXECUTE, WM_DDE_DATA, WM_DDE_ADVISE, WM_DDE_UNADVISE, or WM_DDE_INITIAT消息 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_DATA = WM_DDE_FIRST + 5; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">一个DDE服务程序提交此消息给DDE客户程序来传递个一数据项给客户或通知客户的一条可用数据项 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_REQUEST = WM_DDE_FIRST + 6; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">一个DDE客户程序提交此消息给一个DDE服务程序来请求一个数据项的值； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_POKE = WM_DDE_FIRST + 7; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">一个DDE客户程序提交此消息给一个DDE服务程序，客户使用此消息来请求服务器接收一个未经同意的数据项；服务器通过答复WM_DDE_ACK消息提示是否它接收这个数据项； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_EXECUTE = WM_DDE_FIRST + 8; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">一个DDE客户程序提交此消息给一个DDE服务程序来发送一个字符串给服务器让它象串行命令一样被处理，服务器通过提交WM_DDE_ACK消息来作回应； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_LAST = WM_DDE_FIRST + 8; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_APP = $8000; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_USER = $0400; 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息能帮助应用程序自定义私有消息； 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">///////////////////////////////////////////////////////////////////// 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">通知消息(Notification message)是指这样一种消息，一个窗口内的子控件发生了一些事情，需要通知父窗口。通知消息只适用于标准的窗口控件如按钮、列表框、组合框、编辑框，以及Windows 95公共控件如树状视图、列表视图等。例如，单击或双击一个控件、在控件中选择部分文本、操作控件的滚动条都会产生通知消息。 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">按扭 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">B N _ C L I C K E D //用户单击了按钮 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">B N _ D I S A B L E //按钮被禁止 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">B N _ D O U B L E C L I C K E D //用户双击了按钮 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">B N _ H I L I T E //用户加亮了按钮 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">B N _ PA I N T按钮应当重画 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">B N _ U N H I L I T E加亮应当去掉 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">组合框 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ C L O S E U P组合框的列表框被关闭 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ D B L C L K用户双击了一个字符串 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ D R O P D O W N组合框的列表框被拉出 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ E D I T C H A N G E用户修改了编辑框中的文本 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ E D I T U P D AT E编辑框内的文本即将更新 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ E R R S PA C E组合框内存不足 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ K I L L F O C U S组合框失去输入焦点 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ S E L C H A N G E在组合框中选择了一项 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ S E L E N D C A N C E L用户的选择应当被取消 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ S E L E N D O K用户的选择是合法的 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ S E T F O C U S组合框获得输入焦点 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">编辑框 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">E N _ C H A N G E编辑框中的文本己更新 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">E N _ E R R S PA C E编辑框内存不足 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">E N _ H S C R O L L用户点击了水平滚动条 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">E N _ K I L L F O C U S编辑框正在失去输入焦点 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">E N _ M A X T E X T插入的内容被截断 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">E N _ S E T F O C U S编辑框获得输入焦点 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">E N _ U P D AT E编辑框中的文本将要更新 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">E N _ V S C R O L L用户点击了垂直滚动条消息含义 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">列表框 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">L B N _ D B L C L K用户双击了一项 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">L B N _ E R R S PA C E列表框内存不够 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">L B N _ K I L L F O C U S列表框正在失去输入焦点 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">L B N _ S E L C A N C E L选择被取消 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">L B N _ S E L C H A N G E选择了另一项 
</p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">L B N _ S E T F O C U S列表框获得输入焦点 </p><img src ="http://www.cppblog.com/mzty/aggbug/15618.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2006-11-24 13:00 <a href="http://www.cppblog.com/mzty/archive/2006/11/24/15618.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《windows核心编程》之精华</title><link>http://www.cppblog.com/mzty/archive/2006/09/25/12952.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Mon, 25 Sep 2006 10:23:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2006/09/25/12952.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/12952.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2006/09/25/12952.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/12952.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/12952.html</trackback:ping><description><![CDATA[
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">学习《</span>
				<span lang="EN-US">windows</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">核心编程》<br /><br /></span>
				<span lang="EN-US">
						<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?>
						<o:p>        －－如果发现有什么理解的不正确的，欢迎指出，共同学习，共同进步哦！</o:p>
				</span>
				<span lang="EN-US">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
				</span>
		</p>
		<span lang="EN-US">
				<o:p> </o:p>
		</span>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt">
				<span lang="EN-US" style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings">
						<span style="mso-list: Ignore">u<span style="FONT: 7pt 'Times New Roman'">       </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">字符集，一切软件的基础，单字集（用</span>
				<span lang="EN-US">1</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个字节表示一个字符），双字节字符集（</span>
				<span lang="EN-US">DBCS，</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">并不是用</span>
				<span lang="EN-US">2</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个字节表示一个字符哦，而是用</span>
				<span lang="EN-US">1</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个，</span>
				<span lang="EN-US">2</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个，或多个字节的混合来表示字符），宽字节字符集（</span>
				<span lang="EN-US">unicode</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用</span>
				<span lang="EN-US">2</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个字节来表示一个字符）。对</span>
				<span lang="EN-US">windows</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">操作系统来说，</span>
				<span lang="EN-US">windows 98</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内核用</span>
				<span lang="EN-US">ANSI</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</span>
				<span lang="EN-US">windows ME </span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用</span>
				<span lang="EN-US">unicode</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</span>
				<span lang="EN-US">windows 2000</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">以后的版本也用</span>
				<span lang="EN-US">unicode</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，对于我们在</span>
				<span lang="EN-US">windows</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">上开发，</span>
				<span lang="EN-US">windows2000</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">以后的版本，我们即可以开发</span>
				<span lang="EN-US">ANSI</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版本，也可以开发</span>
				<span lang="EN-US">unicode</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版本，他们都能够很好的运行，但是重效率和软件的国际化来看的化，最后使用</span>
				<span lang="EN-US">unicode</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进行编码。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt">
				<span lang="EN-US" style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings">
						<span style="mso-list: Ignore">u<span style="FONT: 7pt 'Times New Roman'">       </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内核对象，被系统和应用程序用来管理各种资源，我们可以使用</span>
				<span lang="EN-US">API</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来管理和使用内核对象，但是不能直接修改内核对象的数据结构，内核对象由内核所拥有，内核知道某个内核对象有没有被使用等，内核对象被广泛的使用在进程，线程。。。中用来管理。（内核即操作系统的本质，核心所在，进行系统的管理）</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt">
				<span lang="EN-US" style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings">
						<span style="mso-list: Ignore">u<span style="FONT: 7pt 'Times New Roman'">       </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进程，包含用来管理进程的内核对象和用来加载</span>
				<span lang="EN-US">exe</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和数据等的地址空间。当一个</span>
				<span lang="EN-US">exe</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">开始运行时，它即对应一个进程，</span>
				<span lang="EN-US">exe</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span>
				<span lang="EN-US">main</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（）也即是进程入口函数，但是在进入</span>
				<span lang="EN-US">main</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（）之前还有</span>
				<span lang="EN-US">c</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</span>
				<span lang="EN-US">c</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">＋＋运行库的初始化。当创建一个进程时，就产生了一个唯一的实例句柄，它就是</span>
				<span lang="EN-US">winmain</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（）函数中要传入的实例句柄，另外在主进程（可没有非主进程的啊，但也可以认为主进程的子进程是非主进程，因为系统不保存父子进程的关系，他们可以看作是相互独立的）中可以创建它的子进程，用来对多个需要共同管理的线程进行管理。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt">
				<span lang="EN-US" style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings">
						<span style="mso-list: Ignore">u<span style="FONT: 7pt 'Times New Roman'">       </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">作业，作业是进程的容器，可以统一地对一组进程增加一些额外的限制。有时候建立单个进程的作业也是有意义的，因为可以对单一进程施加一些进程本身所没有的属性。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt">
				<span lang="EN-US" style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings">
						<span style="mso-list: Ignore">u<span style="FONT: 7pt 'Times New Roman'">       </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">线程，线程在进程中被创建，在创建进程时，默认的主线程即被创建。操作系统是用线程来完成任务的，因为进程不直接获得操作系统的时间，线程可以认为是操作系统的最小的处理单位。在多线程编程中，首先要注意的就是线程的同步问题，还有线程池的使用。且最好不要使用全局或静态变量。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt">
				<span lang="EN-US" style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings">
						<span style="mso-list: Ignore">u<span style="FONT: 7pt 'Times New Roman'">       </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">纤程，比线程更小的单位，纤程是用户对线程进行分割，然后自定义算法实行对纤程的调用，系统的内核并不知道线程。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt">
				<span lang="EN-US" style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings">
						<span style="mso-list: Ignore">u<span style="FONT: 7pt 'Times New Roman'">       </span></span>
				</span>
				<span lang="EN-US">Windows</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内存结构，每个进程都有它自己的虚拟内存，</span>
				<span lang="EN-US">32</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">位机，虚拟内存位</span>
				<span lang="EN-US">4G</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，但是这</span>
				<span lang="EN-US">4G</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">并不都可以被用户使用，它包含</span>
				<span lang="EN-US">NULL</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">指针，</span>
				<span lang="EN-US">dos</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">兼容区，文件映射区，系统核心区，能被用户使用的只有</span>
				<span lang="EN-US">2G</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。当然现在</span>
				<span lang="EN-US">64</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">位的机子可不是</span>
				<span lang="EN-US">2G</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">哦。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt">
				<span lang="EN-US" style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings">
						<span style="mso-list: Ignore">u<span style="FONT: 7pt 'Times New Roman'">       </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">虚拟内存，</span>
				<span lang="EN-US">windows</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进行内存管理的方法之一，最适合用来管理大型对象和结构数组，也即相当于</span>
				<span lang="EN-US">RAM</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（即物理内存）的二级缓存，系统先到</span>
				<span lang="EN-US">RAM</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">找，如找不到就到虚拟内存（页文件）找，找到了就加载到</span>
				<span lang="EN-US">RAM</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，然后执行。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt">
				<span lang="EN-US" style="FONT-FAMILY: Wingdings; mso-bidi-font-size: 10.5pt; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings">
						<span style="mso-list: Ignore">u<span style="FONT: 7pt 'Times New Roman'">       </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内存映射文件，</span>
				<span lang="EN-US">windows</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的第二中内存管理方法，最适合用来管理大型数据流和单机上的数据共享。</span>
				<span style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: Arial">与虚拟内存一样，内存映射文件可以用来保留一个地址空间的区域，并将物理存储器提交给该区域。它们之间的差别是，物理存储器来自一个已经位于磁盘上的文件，而不是系统的页文件。一旦该文件被映射，就可以访问它，就像整个文件已经加载内存一样。系统还使用内存映射文件，以便加载和执行</span>
				<span lang="EN-US" style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">. e x e</span>
				<span style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: Arial">和</span>
				<span lang="EN-US" style="COLOR: black; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">D L L</span>
				<span style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: Arial">文件。</span>
				<span lang="EN-US" style="mso-bidi-font-size: 10.5pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt">
				<span lang="EN-US" style="FONT-FAMILY: Wingdings; mso-bidi-font-size: 10.5pt; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings">
						<span style="mso-list: Ignore">u<span style="FONT: 7pt 'Times New Roman'">       </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt">堆栈，</span>
				<span lang="EN-US" style="mso-bidi-font-size: 10.5pt">windows</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt">的第三中内存管理方法，最适合管理大量的小对象，例如链表等，线程，进程都有自己的堆栈，默认的大小位</span>
				<span lang="EN-US" style="mso-bidi-font-size: 10.5pt">1M</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt">，也可以修改。<br /><br /><br />最后是DLL高级和SEH的使用。<br /><br /></span>
				<span lang="EN-US" style="mso-bidi-font-size: 10.5pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">主要参考：</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-tab-count: 1">       </span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">《</span>
				<span lang="EN-US">windows</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">核心编程》</span>
				<span lang="EN-US">
						<span style="mso-spacerun: yes">  </span>
						<span style="mso-tab-count: 1">    </span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">机械工业出版社</span>
				<span lang="EN-US">
						<span style="mso-spacerun: yes">  </span>jeffrey richter</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">著</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-tab-count: 1">       </span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">《</span>
				<span lang="EN-US">windows</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">系统编程》</span>
				<span lang="EN-US">
						<span style="mso-tab-count: 1">       </span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">人民邮电出版社</span>
				<span lang="EN-US">
						<span style="mso-spacerun: yes">  </span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">求是科技</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-tab-count: 1">       </span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">《</span>
				<span lang="EN-US">windows2000</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">编程技术内幕》</span>
				<span lang="EN-US">
						<span style="mso-spacerun: yes">   </span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">机械工业出版社</span>
		</p>
<img src ="http://www.cppblog.com/mzty/aggbug/12952.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2006-09-25 18:23 <a href="http://www.cppblog.com/mzty/archive/2006/09/25/12952.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>windows核心编程－－SEH（结构异常处理）</title><link>http://www.cppblog.com/mzty/archive/2006/09/22/12824.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Fri, 22 Sep 2006 06:52:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2006/09/22/12824.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/12824.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2006/09/22/12824.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/12824.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/12824.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 主要参考：http://blog.csdn.net/hbrr224/archive/2006/05.aspxSEH 的工作原理。         Windows 程序设计中最重要的理念就是消息传递，事件驱动。当GUI应用程序触发一个消息时，系统将把该消息放入消息队列，然后去查找并调用窗体的消息处理函数(CALLBACK)，传递的参数当然就是这个消息。我们同样可以把异常也当作是一种消息，应用程序发生...&nbsp;&nbsp;<a href='http://www.cppblog.com/mzty/archive/2006/09/22/12824.html'>阅读全文</a><img src ="http://www.cppblog.com/mzty/aggbug/12824.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2006-09-22 14:52 <a href="http://www.cppblog.com/mzty/archive/2006/09/22/12824.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>windows核心编程－－DLL高级</title><link>http://www.cppblog.com/mzty/archive/2006/09/22/12823.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Fri, 22 Sep 2006 06:11:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2006/09/22/12823.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/12823.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2006/09/22/12823.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/12823.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/12823.html</trackback:ping><description><![CDATA[
		<p>
				<strong>
						<font face="Arial" color="#0000ff">DLL的进入点函数</font>
				</strong>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">一个D L L可以拥有单个进入点函数。系统在不同的时间调用这个进入点函数，这个问题将在下面加以介绍。这些调用可以用来提供一些信息，通常用于供D L L进行每个进程或线程的初始化和清除操作。如果你的D L L不需要这些通知信息，就不必在D L L源代码中实现这个函数。例如，如果你创建一个只包含资源的D L L，就不必实现该函数。如果确实需要在D L L中接受通知信息，可以实现类似下面的进入点函数：</font>
		</p>
		<p>
		</p>
		<div style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7">
				<pre>BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, PVOID fImpLoad)
{
   switch(fdwReason) 
   {
      case DLL_PROCESS_ATTACH:
         //The DLL is being mapped into the process's address space.
         break;

      case DLL_THREAD_ATTACH:
         //A thread is being created.
         break;

      case DLL_THREAD_DETACH:
         //A thread is exiting cleanly.
         break;

      case DLL_PROCESS_DETACH:
         //The DLL is being unmapped from the process's address space.
         break;
   }
   return(TRUE);  // Used only for DLL_PROCESS_ATTACH
}</pre>
		</div>
		<p>
				<font face="Arial" size="2">注意函数名D l l M a i n是区分大小写的。</font>
		</p>
		<p>
				<font size="2">
						<font face="Arial">
								<font style="LINE-HEIGHT: 25px" color="#000000">参数h i n s t D l l包含了D L L的实例句柄。与( w ) Wi n M a i n函数的h i n s t E x e参数一样，这个值用于标识D L L的文件映像被映射到进程的地址空间中的虚拟内存地址。通常应将这个参数保存在一个全局变量中，这样就可以在调用加载资源的函数（如D i a l o g B o x和L o a d S t r i n g）时使用它。最后一个参数是f I m p L o a d，如果D L L是隐含加载的，那么该参数将是个非0值，如果D L L是显式加载的，那么它的值是0。</font>
						</font>
				</font>
		</p>
		<p>
				<font size="2">
						<font face="Arial">
								<font style="LINE-HEIGHT: 25px" color="#000000">参数f d w R e a s o n用于指明系统为什么调用该函数。该参数可以使用4个值中的一个。这4个值是： D L L _ P R O C E S S _ AT TA C H、D L L _ P R O C E S S _ D E TA C H、D L L _ T H R E A D _ AT TA C H或D L L _ T H R E A D _ D E TA C H。这些值将在下面介绍。</font>
						</font>
				</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">注意必须记住，D L L使用D l l M a i n函数来对它们进行初始化。当你的D l l M a i n函数执行时，同一个地址空间中的其他D L L可能尚未执行它们的D l l M a i n函数。这意味着它们尚未初始化，因此你应该避免调用从其他D L L中输入的函数。此外，你应该避免从D l l M a i n内部调用L o a d L i b r a r y ( E x )和F r e e L i b r a r y函数，因为这些函数会形式一个依赖性循环。</font>
		</p>
		<p>
				<font size="2">
						<font face="Arial">
								<strong>
										<font color="#0000ff">DLL_PROCESS_ATTACH通知</font>
								</strong>
								<br />
						</font>
				</font>
				<font size="2">
						<font face="Arial">
								<font style="LINE-HEIGHT: 25px" color="#000000">当D L L被初次映射到进程的地址空间中时，系统将调用该D L L的D l l M a i n函数，给它传递参数f d w R e a s o n的值D L L _ P R O C E S S _ AT TA C H。只有当D L L的文件映像初次被映射时，才会出现这种情况。如果线程在后来为已经映射到进程的地址空间中的D L L调用L o a d L i b r a r y ( E x )函数，那么操作系统只是递增D L L的使用计数，它并不再次用D L L _ P R O C E S S _ AT TA C H的值来调用D L L的D l l M a i n函数。</font>
								<br />
						</font>
				</font>
				<font style="LINE-HEIGHT: 25px" color="#000000">
						<font face="Arial">当处理D L L _ P R O C E S S _ AT TA C H时，D L L应该执行D L L中的函数要求的任何与进程相关的初始化。例如， D L L可能包含需要使用它们自己的堆栈（在进程的地址空间中创建）的函数。<br /><br /><strong><font color="#0000ff">DLL_PROCESS_DETACH通知</font></strong><br /></font>
						<font style="LINE-HEIGHT: 25px" color="#000000">
								<font face="Arial">D L L从进程的地址空间中被卸载时，系统将调用D L L的D l l M a i n函数，给它传递f d w R e a s o n的值D L L _ P R O C E S S _ D E TA C H。当D L L处理这个值时，它应该执行任何与进程相关的清除操作。例如， D L L可以调用H e a p D e s t r o y函数来撤消它在D L L _ P R O C E S S _ D E TA C H通知期间创建的堆栈。<br /><br /><strong><font color="#0000ff">DLL_THREAD_ATTACH通知</font></strong><br /></font>
								<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000">当在一个进程中创建线程时，系统要查看当前映射到该进程的地址空间中的所有D L L文件映像，并调用每个文件映像的带有D L L _ T H R E A D _ AT TA C H值的D l l M a i n函数。这可以告诉所有的D L L执行每个线程的初始化操作。新创建的线程负责执行D L L的所有D l l M a i n函数中的代码。只有当所有的D L L都有机会处理该通知时，系统才允许新线程开始执行它的线程函数。<br /></font>
						</font>
				</font>
		</p>
		<p>
				<font face="Arial" size="2">
						<strong>
								<font color="#0000ff" size="3">DLL_THREAD_DETACH通知</font>
						</strong>
						<br />让线程终止运行的首选方法是使它的线程函数返回。这使得系统可以调用E x i t T h r e a d来撤消该线程。E x i t T h r e a d函数告诉系统，该线程想要终止运行，但是系统并不立即将它撤消。相反， 它要取出这个即将被撤消的线程， 并让它调用已经映射的D L L 的所有带有D L L _ T H R E A D _ D E TACH 值的D l l M a i n函数。这个通知告诉所有的D L L执行每个线程的清除操作。</font>
				<br />
				<br />
				<strong>
						<font face="Arial" color="#0000ff">DllMain与C/C++运行期库</font>
				</strong>
				<br />
				<font face="Arial" size="2">当编写一个D L L时，你需要得到C / C + +运行期库的某些初始帮助。例如，如果你创建的D L L包含一个全局变量，而这个全局变量是个C + +类的实例。在你顺利地在D l l M a i n函数中使用这个全局变量之前，该变量必须调用它的构造函数。这是由C / C + +运行期库的D L L启动代码来完成的。当你的D L L文件映像被映射到进程的地址空间中时，系统实际上是调用_ D l l M a i n C RTS t a r t u p函数，而不是调用D l l M a i n函数。<br /><br /><font size="3"><strong><font color="#0000ff">延迟加载DLL</font></strong><font face="Times New Roman"> （但是怎么延迟那？^_^）</font></font></font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">Microsoft Visual C++ 6.0提供了一个出色的新特性，它能够使D L L的操作变得更加容易。这个特性称为延迟加载D L L。延迟加载的D L L是个隐含链接的D L L，它实际上要等到你的代码试图引用D L L中包含的一个符号时才进行加载。延迟加载的D L L在下列情况下是非常有用的：</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">• 如果你的应用程序使用若干个D L L，那么它的初始化时间就比较长，因为加载程序要将所有需要的D L L映射到进程的地址空间中。解决这个问题的方法之一是在进程运行的时候分开加载各个D L L。延迟加载的D L L能够更容易地完成这样的加载。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">• 如果调用代码中的一个新函数，然后试图在老版本的系统上运行你的应用程序，而该系统中没有该函数，那么加载程序就会报告一个错误，并且不允许该应用程序运行。你需要一种方法让你的应用程序运行，然后，如果（在运行时）发现该应用程序在老的系统上运行，那么你将不调用遗漏的函数。<br /></font>
				<br />
				<strong>
						<font face="Arial" color="#0000ff">函数转发器</font>
				</strong>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">函数转发器是D L L的输出节中的一个项目，用于将对一个函数的调用转至另一个D L L中的另一个函数。<br /><strong><font color="#0000ff" size="3"> DLL转移</font></strong><br />M i c r o s o f t给Windows 2000增加了一个D L L转移特性。这个特性能够强制操作系统的加载程序首先从你的应用程序目录中加载文件模块。只有当加载程序无法在应用程序目录中找到该文件时，它才搜索其他目录。<font style="LINE-HEIGHT: 25px" color="#000000" size="2">为了强制加载程序总是首先查找应用程序的目录，要做的工作就是在应用程序的目录中放入一个文件。该文件的内容可以忽略，但是该文件必须称为A p p N a m e . l o c a l。</font><font style="LINE-HEIGHT: 25px" color="#000000" size="2">例如，如果有一个可执行文件的名字是S u p e r A p p . e x e ，那么转移文件必须称为S u p e r A p p . e x e . l o c a l。<font style="LINE-HEIGHT: 25px" color="#000000" size="2">在系统内部， L o a d L i b r a r y ( E x )已经被修改，以便查看是否存在该文件。如果应用程序的目录中存在该文件，该目录中的模块就已经被加载。如果应用程序的目录中不存在这个模块，L o a d L i b r a r y ( E x )将正常运行。</font><font style="LINE-HEIGHT: 25px" color="#000000" size="2">对于已经注册的C O M对象来说，这个特性是非常有用的。它使应用程序能够将它的C O M对象D L L放入自己的目录，这样，注册了相同C O M对象的其他应用程序就无法干扰你的操作。<br /></font></font></font>
		</p>
		<p>
				<br />
				<br />
				<br />zz</p>
<img src ="http://www.cppblog.com/mzty/aggbug/12823.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2006-09-22 14:11 <a href="http://www.cppblog.com/mzty/archive/2006/09/22/12823.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>windows核心编程－－DLL基本</title><link>http://www.cppblog.com/mzty/archive/2006/09/21/12801.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Thu, 21 Sep 2006 10:00:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2006/09/21/12801.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/12801.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2006/09/21/12801.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/12801.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/12801.html</trackback:ping><description><![CDATA[
		<font face="Arial" size="2">
				<br />Windows API 中的所有函数都包含在D L L中：<br /><br /> K e r n e l 3 2 . d l l，它包含用于管理内存、进程和线程的各个函数；<br /> U s e r 3 2 . d l l，它包含用于执行用户界面任务（如窗口的创建和消息的传送）的各个函数；<br /> G D I 3 2 . d l l，它包含用于画图和显示文本的各个函数。<br /> A d v A P I 3 2 . d l l包含用于实现对象安全性、注册表操作和事件记录的函数；<br /> C o m D l g 3 2 . d l l包含常用对话框（如File Open和File Save）；<br /> C o m C t l 3 2 . D L L则支持所有的常用窗口控件。<br /><br />使用DLL的优点：<br /><p><font style="LINE-HEIGHT: 25px" color="#000000" size="2">• 它们扩展了应用程序的特性。由于D L L能够动态地装入进程的地址空间，因此应用程序能够在运行时确定需要执行什么操作，然后装入相应的代码，以便根据需要执行这些操作。例如，当一家公司开发了一种产品，想要让其他公司改进或增强该产品的功能时，那么就可以使用D L L。</font></p><p><font style="LINE-HEIGHT: 25px" color="#000000" size="2">• 它们可以用许多种编程语言来编写。可以选择手头拥有的最好的语言来编写D L L。也许你的应用程序的用户界面使用Microsoft Visual Basic编写得最好，但是用C + +来处理它的商用逻辑更好。系统允许Visual Basic程序加载C++ DLL、Cobol DLL和Fortran DLL等。</font></p><p><font style="LINE-HEIGHT: 25px" color="#000000" size="2">• 它们简化了软件项目的管理。如果在软件开发过程中不同的工作小组在不同的模块上工作，那么这个项目管理起来比较容易。但是，应用程序在销售时附带的文件应该尽量少一些。我知道有一家公司销售的产品附带了1 0 0个D L L——每个程序员最多有5个D L L。这样，应用程序的初始化时间将会长得吓人，因为系统必须打开1 0 0个磁盘文件之后，程序才能执行它的操作。</font></p><p><font style="LINE-HEIGHT: 25px" color="#000000" size="2">• 它们有助于节省内存。如果两个或多个应用程序使用同一个D L L，那么该D L L的页面只要放入R A M一次，所有的应用程序都可以共享它的各个页面。C / C + +运行期库就是个极好的例子。许多应用程序都使用这个库。如果所有的应用程序都链接到这个静态库，那么s p r i n t f、s t r c p y和m a l l o c等函数的代码就要多次存在于内存中。但是，如果所有这些应用程序链接到DLL C/C++运行期库，那么这些函数的代码就只需要放入内存一次，这意味着内存的使用将更加有效。</font></p><p><font style="LINE-HEIGHT: 25px" color="#000000" size="2">• 它们有助于资源的共享。D L L可以包含对话框模板、字符串、图标和位图等资源。多个应用程序能够使用D L L来共享这些资源。</font></p><p><font style="LINE-HEIGHT: 25px" color="#000000" size="2">• 它们有助于应用程序的本地化。应用程序常常使用D L L对自己进行本地化。例如，只包含代码而不包含用户界面组件的应用程序可以加载包含本地化用户界面组件的D L L。</font></p><p><font style="LINE-HEIGHT: 25px" color="#000000" size="2">• 它们有助于解决平台差异。不同版本的Wi d n o w s配有不同的函数。开发人员常常想要调用新的函数（如果它们存在于主机的Wi n d o w s版本上的话）。但是，如果你的源代码包含了对一个新函数的调用，而你的应用程序将要在不能提供该函数的Wi n d o w s版本上运行，那么操作系统的加载程序将拒绝运行你的进程。即使你实际上从不调用该函数，情况也是这样。如果将这些新函数保存在D L L中，那么应用程序就能够将它们加载到Wi n d o w s的老版本上。当然，你仍然可以成功地调用该函数。</font></p><p><font style="LINE-HEIGHT: 25px" color="#000000" size="2">• 它们可以用于一些特殊的目的。Wi n d o w s使得某些特性只能为D L L所用。例如，只有当D L L中包含某个挂钩通知函数的时候，才能安装某些挂钩（使用S e t Wi n d o w s H o o k E x和S e t Wi n E v e n t H o o k来进行安装）。可以通过创建必须在D L L中生存的C O M对象来扩展Windows Explorer的外壳程序。对于可以由We b浏览器加载的、用于创建内容丰富的We b页的A c t i v e X控件来说,情况也是一样.<br /><br /><a class="" title="DLL的显示和隐试的使用方法" href="/mzty/archive/2006/07/24/10419.html" target="">DLL的显示和隐试的使用方法</a> <br /><br /><br /><br />一些经验：<br />一般使用<font color="#f70938">extern "C" _declspec(dllexport)导出变量，函数等，一般不导出类，为了何其他的兼容。。。。。。。。。</font><br /></font></p></font>
		<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">
				<p>
						<font style="LINE-HEIGHT: 25px" color="#000000" size="2">e x t e r n“C”用于c＋＋编译为能够让c兼容的，即保证函数名不被修改。<br />若要使用与其他编译器供应商的工具链接的M i c r o s o f t的工具创建一个可执行模块，必须告诉M i c r o s o f t的编译器输出没有经过改变的函数名。可以用两种方法来进行这项操作。第一种方法是为编程项目建立一个. d e f文件，并在该. d e f文件中加上类似下面的E X P O RT S节：</font>
				</p>
				<p>
				</p>
				<div style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7">
						<pre>EXPORTS
   MyFunc</pre>
				</div>
				<p>
						<br />如果想避免使用. d e f文件，可以使用第二种方法输出未截断的函数版本。在D L L的源代码模块中，可以添加下面这行代码：</p>
		</font>
		<p>
		</p>
		<div style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7">
				<pre>#pragma comment(linker, "/export:MyFunc=_MyFunc@8")</pre>
		</div>（MyFunc wei函数名字）<br /><br /><img src ="http://www.cppblog.com/mzty/aggbug/12801.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2006-09-21 18:00 <a href="http://www.cppblog.com/mzty/archive/2006/09/21/12801.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>windows核心编程－－内存堆栈</title><link>http://www.cppblog.com/mzty/archive/2006/09/21/12798.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Thu, 21 Sep 2006 08:24:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2006/09/21/12798.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/12798.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2006/09/21/12798.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/12798.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/12798.html</trackback:ping><description><![CDATA[
		<p>
				<font face="Arial" size="2">对内存进行操作的第三个机制是使用堆栈。堆栈可以用来分配许多较小的数据块。例如，若要对链接表和链接树进行管理，最好的方法是使用堆栈，堆栈的优点是，可以不考虑分配粒度和页面边界之类的问题，集中精力处理手头的任务。堆栈的缺点是，分配和释放内存块的速度比其他机制要慢，并且无法直接控制物理存储器的提交和回收。</font>
				<br />
				<font face="Arial" size="2">从内部来讲，堆栈是保留的地址空间的一个区域。开始时，保留区域中的大多数页面没有被提交物理存储器。当从堆栈中进行越来越多的内存分配时，堆栈管理器将把更多的物理存储器提交给堆栈。物理存储器总是从系统的页文件中分配的，当释放堆栈中的内存块时，堆栈管理器将收回这些物理存储器。</font>
				<br />
				<br />
				<font style="BACKGROUND-COLOR: #ff1493">线程的堆栈：</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">每当创建一个线程时，系统就会为线程的堆栈（每个线程有它自己的堆栈）保留一个堆栈空间区域，并将一些物理存储器提交给这个已保留的区域。按照默认设置，系统保留1 MB的地址空间并提交两个页面的内存。但是，这些默认值是可以修改的，方法是在你链接应用程序时设定M i c r o s o f t的链接程序的/ S TA C K选项：</font>
		</p>
		<p>
		</p>
		<div style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7">
				<pre>/STACK:reserve[,commit]</pre>
		</div>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">当创建一个线程的堆栈时，系统将会保留一个链接程序的/ S TA C K开关指明的地址空间区域。<br /><font size="3"><strong><font color="#0000ff">进程的默认堆栈</font></strong><font face="Times New Roman"></font></font></font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">当进程初始化时，系统在进程的地址空间中创建一个堆栈。该堆栈称为进程的默认堆栈。按照默认设置，该堆栈的地址空间区域的大小是1 MB。但是，系统可以扩大进程的默认堆栈，使它大于其默认值。当创建应用程序时，可以使用/ H E A P链接开关，改变堆栈的1 M B默认区域大小。由于D L L没有与其相关的堆栈，所以当链接D L L时，不应该使用/ H E A P链接开关。/ H E A P链接开关的句法如下：</font>
		</p>
		<p>
		</p>
		<div style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7">
				<pre>/HEAP:reserve[,commit]</pre>
		</div>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">许多Wi n d o w s函数要求进程使用其默认堆栈。特别是widows提供的API。对默认堆栈的访问是顺序进行的。换句话说，系统必须保证在规定的时间内，每次只有一个线程能够分配和释放默认堆栈中的内存块。如果两个线程试图同时分配默认堆栈中的内存块，那么只有一个线程能够分配内存块，另一个线程必须等待第一个线程的内存块分配之后，才能分配它的内存块。一旦第一个线程的内存块分配完，堆栈函数将允许第二个线程分配内存块。这种顺序访问方法对速度有一定的影响。如果你的应用程序只有一个线程，并且你想要以最快的速度访问堆栈，那么应该创建你自己的独立的堆栈，不要使用进程的默认堆栈。</font>
				<br />
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">单个进程可以同时拥有若干个堆栈。这些堆栈可以在进程的寿命期中创建和撤消。但是，默认堆栈是在进程开始执行之前创建的，并且在进程终止运行时自动被撤消。不能撤消进程的默认堆栈。每个堆栈均用它自己的堆栈句柄来标识，用于分配和释放堆栈中的内存块的所有堆栈函数都需要这个堆栈句柄作为其参数。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">可以通过调用G e t P r o c e s s H e a p函数获取你的进程默认堆栈的句柄：</font>
		</p>
		<p>
		</p>
		<div style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7">
				<pre>HANDLE GetProcessHeap();</pre>
		</div>
		<p>
				<strong>
						<font color="#0000ff">为什么要创建辅助堆栈</font>
				</strong>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">除了进程的默认堆栈外，可以在进程的地址空间中创建一些辅助堆栈。由于下列原因，你可能想要在自己的应用程序中创建一些辅助堆栈：</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">• 保护组件。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">• 更加有效地进行内存管理。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">• 进行本地访问。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">• 减少线程同步的开销。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">• 迅速释放。</font>
		</p>
		<p>
				<strong>
						<font color="#0000ff">保护组件<br /></font>
				</strong>通过创建多个独立的堆栈，是数据隔离，且相互独立的操作。<br /><strong><font color="#0000ff">更有效的内存管理</font></strong></p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">通过在堆栈中分配同样大小的对象，就可以更加有效地管理堆栈。就是把大小相同的对象放在一个堆栈中进行分配。<br /></font>
				<strong>
						<font color="#0000ff">进行本地访问</font>
				</strong>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">每当系统必须在R A M与系统的页文件之间进行R A M页面的交换时，系统的运行性能就会受到很大的影响。如果经常访问局限于一个小范围地址的内存，那么系统就不太可能需要在R A M与磁盘之间进行页面的交换。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">所以，在设计应用程序的时候，如果有些数据将被同时访问，那么最好把它们分配在互相靠近的位置上。<br /><strong><font color="#0000ff">减少线程同步的开销</font></strong></font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">正如下面就要介绍的那样，按照默认设置，堆栈是顺序运行的，这样，如果多个线程试图同时访问堆栈，就不会使数据受到破坏。但是，堆栈函数必须执行额外的代码，以保证堆栈对线程的安全性。如果要进行大量的堆栈分配操作，那么执行这些额外的代码会增加很大的负担，从而降低你的应用程序的运行性能。当你创建一个新堆栈时，可以告诉系统，只有一个线程将访问该堆栈，因此额外的代码将不执行。（就是用多个堆栈来减少同步的性能消耗）<br /><strong><font color="#0000ff">迅速释放堆栈</font></strong></font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">最后要说明的是，将专用堆栈用于某些数据结构后，就可以释放整个堆栈，而不必显式释放堆栈中的每个内存块。例如，当Windows Explorer遍历硬盘驱动器的目录层次结构时，它必须在内存中建立一个树状结构。如果你告诉Windows Explorer刷新它的显示器，它只需要撤消包含这个树状结构的堆栈并且重新运行即可（当然，假定它将专用堆栈用于存放目录树信息）。对于许多应用程序来说，这是非常方便的，并且它们也能更快地运行。</font>
		</p>
		<p>
				<strong>
						<font face="Arial" color="#0000ff">如何创建辅助堆栈</font>
				</strong>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">你可以在进程中创建辅助堆栈，方法是让线程调用H e a p C r e a t e函数：</font>
		</p>
		<p>
		</p>
		<div style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7">
				<pre>HANDLE HeapCreate(
   DWORD fdwOptions,
   SIZE_T dwInitialSize,
   SIZE_T dwMaximumSize);</pre>
		</div>
		<p>
				<font face="Arial" size="2">当试图从堆栈分配一个内存块时， H e a p A l l o c函数（下面将要介绍）必须执行下列操作：</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">1) 遍历分配的和释放的内存块的链接表。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">2) 寻找一个空闲内存块的地址。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">3) 通过将空闲内存块标记为“已分配”分配新内存块。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">4) 将新内存块添加给内存块链接表。</font>
		</p>
		<p>
				<strong>
						<font face="Arial" color="#0000ff">从堆栈中分配内存块</font>
				</strong>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">若要从堆栈中分配内存块，只需要调用H e a p A l l o c函数：</font>
		</p>
		<p>
		</p>
		<div style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7">
				<pre>PVOID HeapAlloc(
   HANDLE hHeap,
   DWORD fdwFlags,
   SIZE_T dwBytes);</pre>
		</div>
		<p>
				<strong>
						<font face="Arial" color="#0000ff">改变内存块的大小</font>
				</strong>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">常常需要改变内存块的大小。有些应用程序开始时分配的内存块比较大，然后，当所有数据放入内存块后，再缩小内存块的大小。有些应用程序开始时分配的内存块比较小，后来需要将更多的数据拷贝到内存块中去时，再设法扩大它的大小。如果要改变内存块的大小，可以调用H e a p R e A l l o c函数：</font>
		</p>
		<p>
		</p>
		<div style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7">
				<pre>PVOID HeapReAlloc(
   HANDLE hHeap,
   DWORD fdwFlags,
   PVOID pvMem,
   SIZE_T dwBytes);</pre>
		</div>
		<p>
				<strong>
						<font face="Arial" color="#0000ff">了解内存块的大小</font>
				</strong>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">当内存块分配后，可以调用H e a p S i z e函数来检索内存块的实际大小：</font>
		</p>
		<p>
		</p>
		<div style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7">
				<pre>SIZE_T HeapSize(
   HANDLE hHeap,
   DWORD fdwFlags,
   LPCVOID pvMem);</pre>
		</div>
		<p>
				<strong>
						<font face="Arial" color="#0000ff">释放内存块</font>
				</strong>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">当不再需要内存块时，可以调用H e a p F r e e函数将它释放：</font>
		</p>
		<p>
		</p>
		<div style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7">
				<pre>BOOL HeapFree(
   HANDLE hHeap,
   DWORD fdwFlags,
   PVOID pvMem);</pre>
		</div>
		<p>
				<strong>
						<font face="Arial" color="#0000ff">撤消堆栈</font>
				</strong>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">如果应用程序不再需要它创建的堆栈，可以通过调用H e a p D e s t r o y函数将它撤消：</font>
		</p>
		<p>
		</p>
		<div style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7">
				<pre>BOOL HeapDestroy(HANDLE hHeap);</pre>
		</div>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">调用H e a p D e s t r o y函数可以释放堆栈中包含的所有内存块，也可以将堆栈占用的物理存储器和保留的地址空间区域重新返回给系统。如果该函数运行成功， H e a p D e s t r o y返回T R U E。如果在进程终止运行之前没有显式撤消堆栈，那么系统将为你将它撤消。但是，只有当进程终止运行时，堆栈才能被撤消。如果线程创建了一个堆栈，当线程终止运行时，该堆栈将不会被撤消。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">在进程完全终止运行之前，系统不允许进程的默认堆栈被撤消。如果将进程的默认堆栈的句柄传递给H e a p D e s t r o y函数，系统将忽略对该函数的调用。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">由于进程的地址空间中可以存在多个堆栈，因此可以使用G e t P r o c e s s H e a p s函数来获取现有堆栈的句柄：</font>
		</p>
		<p>
		</p>
		<div style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7">
				<pre>DWORD GetProcessHeaps(
   DWORD dwNumHeaps,
   PHANDLE pHeaps);</pre>
		</div>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">若要调用G e t P r o c e s s H e a p s函数，必须首先分配一个H A N D L E数组，然后调用下面的函数：</font>
		</p>
		<p>
		</p>
		<div style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7">
				<pre>HANDLE hHeaps[25];
DWORD dwHeaps = GetProcessHeaps(25, hHeaps);
if(dwHeaps &gt; 5) 
{
   //More heaps are in this process than we expected.
} 
else
{
   //hHeaps[0] through hHeap[dwHeaps - 1]
   //identify the existing heaps.
}</pre>
		</div>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">注意，当该函数返回时，你的进程的默认堆栈的句柄也包含在堆栈句柄的数组中。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">H e a p Va l i d a t e函数用于验证堆栈的完整性：</font>
		</p>
		<p>
		</p>
		<div style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7">
				<pre>BOOL HeapValidate(
   HANDLE hHeap,
   DWORD fdwFlags,
   LPCVOID pvMem);</pre>
		</div>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">调用该函数时，通常要传递一个堆栈句柄，一个值为0的标志（唯一的另一个合法标志是H E A P _ N O _ S E R I A L I Z E），并且为p v M e m传递N U L L。然后，该函数将遍历堆栈中的内存块以确保所有内存块都完好无损。为了使该函数运行得更快，可以为参数p v M e m传递一个特定的内存块的地址。这样做可使该函数只检查单个内存块的有效性。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">若要合并地址中的空闲内存块并收回不包含已经分配的地址内存块的存储器页面，可以调用下面的函数：</font>
		</p>
		<p>
		</p>
		<div style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7">
				<pre>UINT HeapCompact(
   HANDLE hHeap,
   DWORD fdwFlags);
</pre>
		</div>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">通常情况下，可以为参数f d w F l a g s传递0，但是也可以传递H E A P _ N O _ S E R I A L I Z E。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">下面两个函数H e a p L o c k和H e a p U n l o c k是结合在一起使用的：</font>
		</p>
		<p>
		</p>
		<div style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7">
				<pre>BOOL HeapLock(HANDLE hHeap);
BOOL HeapUnlock(HANDLE hHeap);</pre>
		</div>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">这些函数是用于线程同步的。当调用H e a p L o c k函数时，调用线程将成为特定堆栈的所有者。如果其他任何线程调用堆栈函数（设定相同的堆栈句柄），系统将暂停调用线程的运行，并且在堆栈被H e a p U n l o c k函数解锁之前不允许它醒来。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">H e a p A l l o c、H e a p S i z e和H e a p F r e e等函数在内部调用H e a p L o c k和H e a p U n l o c k函数来确保对堆栈的访问能够顺序进行。自己调用H e a p L o c k或H e a p U n l o c k这种情况是不常见的。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">最后一个堆栈函数是H e a p Wa l k：</font>
		</p>
		<p>
		</p>
		<div style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7">
				<pre>BOOL HeapWalk(
   HANDLE hHeap,
   PPROCESS_HEAP_ENTRY pHeapEntry);</pre>
		</div>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">该函数只用于调试目的。它使你能够遍历堆栈的内容。可以多次调用该函数。</font>
				<br />
				<br />zz<br /><br /><br /></p>
<img src ="http://www.cppblog.com/mzty/aggbug/12798.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2006-09-21 16:24 <a href="http://www.cppblog.com/mzty/archive/2006/09/21/12798.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>windows核心编程－－内存映射文件</title><link>http://www.cppblog.com/mzty/archive/2006/09/21/12790.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Thu, 21 Sep 2006 05:26:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2006/09/21/12790.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/12790.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2006/09/21/12790.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/12790.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/12790.html</trackback:ping><description><![CDATA[
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">与虚拟内存一样，内存映射文件可以用来保留一个地址空间的区域，并将物理存储器提交给该区域。它们之间的差别是，物理存储器来自一个已经位于磁盘上的文件，而不是系统的页文件。一旦该文件被映射，就可以访问它，就像整个文件已经加载内存一样。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">内存映射文件可以用于3个不同的目的：</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">• 系统使用内存映射文件，以便加载和执行. e x e和D L L文件。这可以大大节省页文件空间和应用程序启动运行所需的时间。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">• 可以使用内存映射文件来访问磁盘上的数据文件。这使你可以不必对文件执行I / O操作，并且可以不必对文件内容进行缓存。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" face="Arial" color="#000000" size="2">• 可以使用内存映射文件，使同一台计算机上运行的多个进程能够相互之间共享数据。Wi n d o w s确实提供了其他一些方法，以便在进程之间进行数据通信，但是这些方法都是使用内存映射文件来实现的，这使得内存映射文件成为单个计算机上的多个进程互相进行通信的最有效的方法。<br /><br /><font size="3"><strong><font color="#0000ff">内存映射的可执行文件和DLL文件</font></strong><font face="Times New Roman"></font></font></font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">当线程调用C r e a t e P r o c e s s时，系统将执行下列操作步骤：</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">1) 系统找出在调用C r e a t e P r o c e s s时设定的. e x e文件。如果找不到这个. e x e文件，进程将无法创建，C r e a t e P r o c e s s将返回FA L S E。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">2) 系统创建一个新进程内核对象。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">3) 系统为这个新进程创建一个私有地址空间。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">4) 系统保留一个足够大的地址空间区域，用于存放该. e x e文件。该区域需要的位置在. e x e文件本身中设定。按照默认设置， . e x e文件的基地址是0 x 0 0 4 0 0 0 0 0（这个地址可能不同于在6 4位Windows 2000上运行的6 4位应用程序的地址），但是，可以在创建应用程序的. e x e文件时重载这个地址，方法是在链接应用程序时使用链接程序的/ B A S E选项。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">5) 系统注意到支持已保留区域的物理存储器是在磁盘上的. e x e文件中，而不是在系统的页文件中。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">当. e x e文件被映射到进程的地址空间中之后，系统将访问. e x e文件的一个部分，该部分列出了包含. e x e文件中的代码要调用的函数的D L L文件。然后，系统为每个D L L文件调用L o a d L i b r a r y函数，如果任何一个D L L需要更多的D L L，那么系统将调用L o a d L i b r a r y函数，以便加载这些D L L。每当调用L o a d L i b r a r y来加载一个D L L时，系统将执行下列操作步骤，它们均类似上面的第4和第5个步骤：</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">1) 系统保留一个足够大的地址空间区域，用于存放该D L L文件。该区域需要的位置在D L L文件本身中设定。按照默认设置， M i c r o s o f t的Visual C++ 建立的D L L文件基地址是0 x 1 0 0 0 0 0 0 0（这个地址可能不同于在6 4位Windows 2000上运行的6 4位D L L的地址）但是，你可以在创建D L L文件时重载这个地址，方法是使用链接程序的/ B A S E选项。Wi n d o w s提供的所有标准系统D L L都拥有不同的基地址，这样，如果加载到单个地址空间，它们就不会重叠。 </font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">2) 如果系统无法在该D L L的首选基地址上保留一个区域，其原因可能是该区域已经被另一个D L L或. e x e占用，也可能是因为该区域不够大，此时系统将设法寻找另一个地址空间的区域来保留该D L L。</font>
		</p>
		<p>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">3) 系统会注意到支持已保留区域的物理存储器位于磁盘上的D L L文件中，而不是在系统的页文件中。<br /><br /></font>
				<font style="LINE-HEIGHT: 25px" color="#000000" size="2">如果由于某个原因系统无法映射. e x e和所有必要的D L L文件，那么系统就会向用户显示一个消息框，并且释放进程的地址空间和进程对象。<br />当所有的. e x e和D L L文件都被映射到进程的地址空间之后，系统就可以开始执行. e x e文件的启动代码。当. e x e文件被映射后，系统将负责所有的分页、缓冲和高速缓存的处理。<br /><strong><font color="#0000ff">在可执行文件或DLL的多个实例之间共享静态数据</font></strong> （通过定义共享的节） 
<p><font style="LINE-HEIGHT: 25px" color="#000000" size="2">全局数据和静态数据不能被同一个. e x e或D L L文件的多个映像共享，这是个安全的默认设置。但是，在某些情况下，让一个. e x e文件的多个映像共享一个变量的实例是非常有用和方便的。例如，Wi n d o w s没有提供任何简便的方法来确定用户是否在运行应用程序的多个实例。但是，如果能够让所有实例共享单个全局变量，那么这个全局变量就能够反映正在运行的实例的