﻿<?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++博客-梦中乐园-文章分类-Windows相关</title><link>http://www.cppblog.com/Dream5/category/18262.html</link><description>C/C++程序员之梦</description><language>zh-cn</language><lastBuildDate>Sat, 31 Mar 2012 04:51:44 GMT</lastBuildDate><pubDate>Sat, 31 Mar 2012 04:51:44 GMT</pubDate><ttl>60</ttl><item><title>windows xp 下 删除.svn 文件夹</title><link>http://www.cppblog.com/Dream5/articles/169550.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Fri, 30 Mar 2012 11:17:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/169550.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/169550.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/169550.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/169550.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/169550.html</trackback:ping><description><![CDATA[可以通过将&#8220;Delete SVN Folders&#8221;操作添加到右击菜单中，然后在要删除.svn文件夹中右键点击&#8220;Delete SVN Folders&#8221;这个选项，即可删除这个文件夹下的所有.svn文件夹<br />方法如下：<br />建立一个文本文件，输入如下内容：<br />Windows Registry Editor Version 5.00<br />[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN] <br />@="Delete SVN Folders"<br />[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN\command] <br />@="cmd.exe /c \"TITLE Removing SVN Folders in %1 &amp;&amp; COLOR 9A &amp;&amp; FOR /r \"%1\" %%f IN (.svn) DO RD /s /q \"%%f\" \""<br />保存为后缀名为 .reg 的文件，名称自定。<br />双击运行 .reg 文件即可在右键菜单中添加&#8220;Delete SVN Folders&#8221; 选项。<img src ="http://www.cppblog.com/Dream5/aggbug/169550.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2012-03-30 19:17 <a href="http://www.cppblog.com/Dream5/articles/169550.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC6.0  设置 UNICODE 编译环境</title><link>http://www.cppblog.com/Dream5/articles/167333.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Wed, 07 Mar 2012 09:54:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/167333.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/167333.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/167333.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/167333.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/167333.html</trackback:ping><description><![CDATA[转自：<a href="http://www.cnblogs.com/mars9/archive/2011/09/21/2184158.html">http://www.cnblogs.com/mars9/archive/2011/09/21/2184158.html</a><br />VC++ 6.0支持Unicode编程，但默认的是ANSI，所以开发人员只需要稍微改变一下编写代码的习惯便可以轻松编写支持UNICODE的应用程序。 　<br />　　 1. 安装完成后：需要把VC98\MFC\LIB下的<strong>MFC42U*.*</strong>手动拷贝到对应的安装目录下<br /><br />　　 2. 为工程添加UNICODE和_UNICODE预处理选项：打开[工程]-&gt;[设置&#8230;]对话框，在C/C++标签对话框的&#8220;预处理程序定义&#8221;中去除_MBCS，加上_UNICODE,UNICODE。（注意中间用逗号隔开）.在没有定义UNICODE和_UNICODE前，所有函数和类型都默认使用ANSI的版本；在定义了UNICODE和_UNICODE之后，所有的MFC类和Windows API都变成了宽字节版本了。<br /><br />　　 3. 设置程序入口点：因为MFC应用程序有针对Unicode专用的程序入口点，我们要设置entry point。否则就会出现连接错误。设置entry point的方法是：打开[工程]-&gt;[设置&#8230;]对话框，在Link页的Output类别的Entry Point里填上wWinMainCRTStartup。<br /><br />　　 4. 使用ANSI/Unicode通用数据类型：微软提供了一些ANSI和Unicode兼容的通用数据类型，我们最常用的数据类型有_T ，TCHAR，LPTSTR,LPCTSTR。顺便说一下，LPCTSTR和const TCHAR*是完全等同的。其中L表示long指针，这是为了兼容Windows 3.1等16位操作系统遗留下来的，在Win32 中以及其它的32位操作系统中，long指针和near指针及far修饰符都是为了兼容的作用，没有实际意义。P（pointer）表示这是一个指针；C （const）表示是一个常量；T(_T宏)表示兼容ANSI和Unicode，STR（string）表示这个变量是一个字符串。综上可以看出， LPCTSTR表示一个指向常固定地址的可以根据一些宏定义改变语义的字符串。比如：TCHAR* szText=_T(&#8220;Hello!&#8221;);TCHAR szText[]=_T(&#8220;I Love You&#8221;);LPCTSTR lpszText=_T(&#8220;大家好！&#8221;);使用函数中的参数最好也要有变化，比如：MessageBox(_T(&#8220;你好&#8221;));　　其实，在上面的语句中，即使您不加_T宏，MessageBox函数也会自动把&#8220;你好&#8221;字符串进行强制转换。但我还是推荐您使用_T宏，以表示您有Unicode编码意识。<br /><br />　　 5. 修改字符串运算问题　　一些字符串操作函数需要获取字符串的字符数(sizeof(szBuffer)/sizeof(TCHAR))，而另一些函数可能需要获取字符串的字节数sizeof(szBuffer)。您应该注意该问题并仔细分析字符串操作函数，以确定能够得到正确的结果。ANSI 操作函数以str开头，如strcpy()，strcat()，strlen()；Unicode操作函数以wcs开头，如wcscpy，wcscpy ()，wcslen()；ANSI/Unicode操作函数以_tcs开头 _tcscpy(C运行期库)；ANSI/Unicode操作函数以lstr开头 lstrcpy(Windows函数)；考虑ANSI和Unicode的兼容，我们需要使用以_tcs开头或lstr开头的通用字符串操作函数。<br /><img src ="http://www.cppblog.com/Dream5/aggbug/167333.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2012-03-07 17:54 <a href="http://www.cppblog.com/Dream5/articles/167333.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>PeekMessage 函数</title><link>http://www.cppblog.com/Dream5/articles/163744.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Fri, 06 Jan 2012 13:43:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/163744.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/163744.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/163744.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/163744.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/163744.html</trackback:ping><description><![CDATA[<div>PeekMessage 调用的一个例子：
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">PeekMessage(</span><span style="color: #000000">&amp;</span><span style="color: #000000">msg,NULL,</span><span style="color: #000000">0</span><span style="color: #000000">,</span><span style="color: #000000">0</span><span style="color: #000000">,PM_REMOVE);</span></div>前面的4个参数（一个指向 MSG 结构的指针、一个窗口的句柄、两个值指示消息范围）与 GetMessage 的参数相同。<br />将第二、三、四个参数设置为 NULL 或 0时，表明我们想让 PeekMessage 返回程序中所有窗口的所有消息。<br /><strong><br />如果要将消息从消息队列中删除，则将 PeekMessage 的最后一个参数设置为</strong> <strong>PM_REMOVE。<br />如果不希望删除消息，则将最后一个参数设置为 PM_NOREMOVE，这使得程序可以检查程序的消息队列中的下一个消息，而不实际删除它。<br /></strong><br />GetMessage 不将控制返回给程序，直到从程序的消息队列中获取消息，但是 PeekMessage 总是立刻返回，而不论一个消息是否出现。<br />当（应用程序的）消息队列中有一个消息时，PeekMessage 的返回值为 TRUE(非0)，并且将按通常方式处理消息。当队列中没有消息时，PeekMessage 返回 FALSE(0)。<br />考虑如下例子：<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000">//</span><span style="color: #008000">&nbsp;普通的消息循环&nbsp;</span><span style="color: #008000"><br /></span><span style="color: #0000ff">while</span><span style="color: #000000">(&nbsp;GetMessage(</span><span style="color: #000000">&amp;</span><span style="color: #000000">msg,NULL,</span><span style="color: #000000">0</span><span style="color: #000000">,</span><span style="color: #000000">0</span><span style="color: #000000">)&nbsp;)<br />{<br />&nbsp;&nbsp;TranslateMessage(</span><span style="color: #000000">&amp;</span><span style="color: #000000">msg);<br />&nbsp;&nbsp;DispatchMessage&nbsp;(</span><span style="color: #000000">&amp;</span><span style="color: #000000">msg);<br />}<br /></span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;msg.wParam;<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;等价于</span><span style="color: #008000"><br /></span><span style="color: #0000ff">while</span><span style="color: #000000">(&nbsp;TRUE&nbsp;)<br />{<br />&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;PeekMessage(</span><span style="color: #000000">&amp;</span><span style="color: #000000">msg,NULL,</span><span style="color: #000000">0</span><span style="color: #000000">,</span><span style="color: #000000">0</span><span style="color: #000000">,PM_REMOVE)&nbsp;)<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(msg.message&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;WM_QUIT)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">break</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;TranslateMessage(</span><span style="color: #000000">&amp;</span><span style="color: #000000">msg);<br />&nbsp;&nbsp;&nbsp;&nbsp;DispatchMessage(</span><span style="color: #000000">&amp;</span><span style="color: #000000">msg);<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000"><br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;Other&nbsp;program&nbsp;lines&nbsp;to&nbsp;do&nbsp;some&nbsp;work</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;}<br />}<br /></span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;msg.wParam;</span></div><em>如果 PeekMessage 的返回值为 TRUE,则消息按通常方式进行处理。如果返回值为 FALSE,则在将控制返回给Windows（操作系统） 之前，还可以做一点工作（如显示另一个随机矩形）。<br /></em><br /><strong>PeekMessage 不能从消息队列中删除 WM_PAINT 消息。<br /></strong>从队列中删除 WM_PAINT 消息的唯一方法是令窗口客户区的失效区域变得有效，这可以用 ValidateRect 和 ValidateRgn 或者 BeginPaint 和 EndPaint 对来完成。<br /><br /><strong>不能使用如下所示的代码来清除消息队列中的所有消息：<br /></strong>while( PeekMessage(&amp;msg,NULL,0,0,PM_REMOVE) );<br />这条语句从消息队列中删除 WM_PAINT 之外的所有消息。如果队列中有一个 WM_PAINT 消息，程序就会永远地陷在 while 循环中。<br /></div><img src ="http://www.cppblog.com/Dream5/aggbug/163744.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2012-01-06 21:43 <a href="http://www.cppblog.com/Dream5/articles/163744.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>矩形、区域和剪裁</title><link>http://www.cppblog.com/Dream5/articles/163743.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Fri, 06 Jan 2012 13:09:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/163743.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/163743.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/163743.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/163743.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/163743.html</trackback:ping><description><![CDATA[Windows 包含了几种使用 RECT(矩形)结构和&#8220;区域&#8221;的绘图函数。<br />区域就是屏幕上的一块地方，它是矩形、多边形和椭圆的结合。<br /><br /><strong>矩形函数：<br /></strong>&nbsp; 
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 416px; padding-right: 5.4pt; height: 34px; border-top: black 1pt solid; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">函数</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: black 1pt solid; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">功能</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">FillRect(hdc,&amp;rect,hBrush);</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">用指定画刷来填充矩形（直到但不包含 right 和 bottom 坐标），该函数不需要先将画刷选进设备描述表。</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">FrameRect(hdc,&amp;rect,hBrush);</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">使用画刷画矩形框，但是不填充矩形。</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">InvertRect(hdc,&amp;rect);</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">将矩形中所有像素反转，1转换成0，0转换成1。</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">SetRect(&amp;rect,xLeft,yTop,</span><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">xRight,yBottom);</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">将 RECT 结构的4个字段设置为特定值。</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">OffsetRect(&amp;rect,x,y);</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">将矩形沿x轴和y轴移动几个单元。</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">InflateRect(&amp;rect,x,y);</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">增减矩形的尺寸。</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">SetRectEmpty(&amp;rect);</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">将矩形各字段设置为0。</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">CopyRect(&amp;DestRect,&amp;SrcRect);</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">将矩形复制给另一个矩形。</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">IntersectRect(&amp;DestRect,&amp;SrcRect1,</span><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">&amp;SrcRect2);</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">获取两个矩形的交集。</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">UnionRect(&amp;DestRect,&amp;SrcRect1,</span><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">&amp;SrcRect2);</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">获取两个矩形的并集。</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">bEmpty = IsRectEmpty(&amp;rect);</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 682px; padding-right: 5.4pt; height: 18px; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">确定矩形是否为空。</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">bInRect = PtInRect(&amp;rect,point);</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; height: 47px; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">确定点是否在矩形内。</span></p></td></tr></tbody></table><br /><strong>创建和绘制区域<br /></strong>区域是对显示器上一个范围的描述，这个范围是矩形、多边形和椭圆的组合。区域可以用于绘制和剪裁，<strong>通过将区域选进设备描述表</strong>，就可以用区域来进行剪裁（就是说，就可以将绘图的范围限制为客户区的一部分）。<br />与画笔、画刷和位图一样，区域是 GDI 对象，应该调用 DeleteObject 来删除创建的区域。<br /><br />当创建一个区域时，Windows 返回一个该区域的句柄，类型为 HRGN。<br /><strong>最简单的区域是矩形，创建矩形区域的方法：<br /></strong>hRgn = CreateRectRgn(xLeft,yTop,xRight,yBottom);<br />或<br />hRgn = CreateRectRgnIndirect(&amp;rect);<br /><br /><strong>创建椭圆区域的方法：<br /></strong>hRgn = CreateEllipticRgn(xLeft,yTop,xRight,yBottom);<br />或<br />hRgn = CreateEllipticRgnIndirect(&amp;rect);<br /><br /><strong>创建圆角的矩形区域：CreateRoundRectRgn;<br /></strong><br /><strong>创建多边形区域的方法：<br /></strong>hRgn = CreatePolygonRgn(&amp;point,iCount,iPolyFillMode);<br />创建多个多边形区域：CreatePolyPolygonRgn;<br /><br /><strong>合成区域：<br /></strong>iRgnType = CombineRgn(hDestRgn,hSrcRgn1,hSrcRgn2,iCombine);<br />这一函数将两个源区域（hSrcRgn1 和 hSrcRgn2）组合起来并用句柄 hDestRgn 指向合成的目标区域。这三个区域句柄必须是有效的，但是 hDestRgn 所指向的原来的区域被破坏掉了（当你使用这个函数时，可能要让 hDestRgn 在初始时指向一个小的矩形区域）。<br /><strong>iCombine 参数说明 hSrcRgn1 和 hSrcRgn2 如何组合：</strong>&nbsp; 
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: black 1pt solid; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">iCombine </span><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">值</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: black 1pt solid; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">新区域</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">RGN_AND</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">两个源区域的公共部分</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">RGN_OR</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">两个源区域的全部</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">RGN_XOR</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">两个源区域的全部除去公共部分</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">RGN_DIEF</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">hSrcRgn1 </span><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">不在 hSrcRgn2 中的部分</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">RGN_COPY</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">hSrcRgn1 </span><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">的全部（忽略hSrcRgn2）</span></p></td></tr></tbody></table><br /><strong>从 CombineRgn 返回的 iRgnType 值是下列之一：<br /></strong>NULLREGION，表示得到一个空区域；<br />SIMPLEREGION，表示得到一个简单的矩形、椭圆或者多边形；<br />COMPLEXREGION，表示多个矩形、椭圆或多边形的组合；<br />ERROR，表示出错了。<br /><br /><strong>删除区域：<br /></strong>DeleteObject(hRgn); <br /><br /><strong>矩形与区域的剪裁：<br /></strong>区域也在剪裁中扮演了一个角色。InvalidateRect 函数使显示的一个矩形区域失效，并产生一个 WM_PAINT 消息。<br />InvalidateRect(hwnd,NULL,TRUE);<br /><em>清空客户区，并产生一个 WM_PAINT 消息（在应用程序的消息队列中，最终由 Windows 调用应用程序的窗口过程函数来处理。）<br /><br /></em>可以通过调用 GetUpdateRect 来获取失效矩形的坐标，并且可以使用 ValidateRect 函数使客户区的矩形有效。<br />当接收到一个 WM_PAINT 消息时，无效矩形的坐标可以从 PAINTSTRUCT 结构中得到，该结构是用 BeginPaint 函数填充的。这个无效矩形还定义了一个&#8220;剪裁区域&#8221;，不能在剪裁区域外绘图。<br /><br />Windows 有两个作用于区域而不是矩形的函数，它们类似于InvalidateRect 和 ValidateRect:<br />InvalidateRgn(hwnd,hRgn,bErase);<br />和<br />ValidateRgn(hwnd,hRgn);<br /><br />当接收到一个由无效矩形引起的 WM_PAINT 消息时，剪裁区域不一定是矩形。<br /><br />可以使用以下两个函数把区域选进设备描述表：<br />SelectObject(hdc,hRgn);<br />或<br />SelectClipRgn(hdc,hRgn);<br />通过将一个区域选进设备描述表来创建自己的剪裁区域，这个剪裁区域使用设备坐标。<br /><br /><strong>GDI(图形设备接口)为剪裁区域建立一份副本，所以在将它选进设备描述表之后，用户可以删除它</strong>。<br /><br /><strong>几个对剪裁区域进行操作的函数：<br /></strong>ExcludeClipRect 用于将一个矩形从剪裁区域里排除掉。<br />IntersectClipRect 用于创建一个新的剪裁区域，它是前一个剪裁区域与一个矩形的交集。<br />OffsetClipRgn 用于将剪裁区域移动到客户区的另一部分。<img src ="http://www.cppblog.com/Dream5/aggbug/163743.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2012-01-06 21:09 <a href="http://www.cppblog.com/Dream5/articles/163743.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>窗口和视口</title><link>http://www.cppblog.com/Dream5/articles/163704.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Fri, 06 Jan 2012 07:48:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/163704.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/163704.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/163704.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/163704.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/163704.html</trackback:ping><description><![CDATA[<em>&#8220;窗口&#8221;和&#8220;视口&#8221;这两个词用得并不恰当。在其他图形界面语言中，视口通常包含有剪裁区域的意思，并且，我们以及用窗口来指程序在屏幕上占据的区域。<br />在这里的讨论中，我们必须把关于这些词的先入之见抛到一边。<br /><br /></em>映射方式用于定义从&#8220;窗口&#8221;（逻辑坐标）到&#8220;视口&#8221;（设备坐标）的映射。<br /><br />&#8220;视口&#8221;是基于设备坐标（像素）的。<br />通常，视口和客户区相同，但是，如果你已经用 GetWindowDC 或 CreateDC 获取了一个设备描述表，则视口也可以是整窗口坐标或者屏幕坐标。<br />点(0,0)是客户区（或者整个窗口或屏幕）的左上角，x的值向右增加，y的值向下增加。<br /><br />&#8220;窗口&#8221;是基于逻辑坐标的，逻辑坐标可以是像素、mm、英寸，或者你想要的任何其他单位。您在 GDI 绘图函数中指定逻辑窗口坐标。<br /><br />对于所有的映射方式，Windows 都用下面两个公式来将窗口（逻辑）坐标转化为视口（设备）坐标：<br />xViewport = (xWindow - xWinOrg) *(xViewExt/xWinExt) + xViewOrg<br /><br />yViewPort = (yWindow - yWinOrg) * (yViewExt/yWinExt) + yViewOrg<br />其中，(xWindow,yWindow)是带转换的逻辑点，(xViewport,yViewport)是转换后的设备坐标点，更像客户区坐标。(xWinOrg,yWinOrg)是逻辑坐标的窗口原点；(xViewOrg,yViewOrg)是设备坐标的视口原点。在默认的设备描述表中，这两个点均被设置为(0,0)，但是他们可以改变。 <br /><br />设备点与逻辑点相互转换的函数： 
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000">//</span><span style="color: #008000">&nbsp;设备点转换为逻辑点</span><span style="color: #008000"><br /></span><span style="color: #000000">DPtoLP(hdc,pPoints,iNumber);<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;将逻辑点转换为设备点</span><span style="color: #008000"><br /></span><span style="color: #000000">LPtoDP(hdc,pPoints,iNumber);<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;pPoints是一个指向&nbsp;POINT&nbsp;结构数组的指针，而&nbsp;iNumber&nbsp;是要转换的点的个数。<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;将&nbsp;GetClientRect(它总是使用设备单位)获取的客户区大小转换为逻辑坐标</span><span style="color: #008000"><br /></span><span style="color: #000000">GetClientRect(hwnd,</span><span style="color: #000000">&amp;</span><span style="color: #000000">rect);<br />DPtoLP(hdc,(POINT)</span><span style="color: #000000">&amp;</span><span style="color: #000000">rect,</span><span style="color: #000000">2</span><span style="color: #000000">);</span></div><br />Windows 提供了函数 SetViewportOrgEx 和 SetWindowOrgEx，用来改变视口和窗口的原点。 <br /><br />可以使用下面两个函数来获取当前视口和窗口的原点：<br />GetViewportOrgEx(hdc,&amp;pt);<br />GetWindowOrgEx (hdc,&amp;pt);<img src ="http://www.cppblog.com/Dream5/aggbug/163704.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2012-01-06 15:48 <a href="http://www.cppblog.com/Dream5/articles/163704.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设备坐标和逻辑坐标</title><link>http://www.cppblog.com/Dream5/articles/163701.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Fri, 06 Jan 2012 03:15:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/163701.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/163701.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/163701.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/163701.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/163701.html</trackback:ping><description><![CDATA[<div>Windows 对所有消息（如 WM_MOVE,WM_SIZE 和 WM_MOUSEMOVE），对所有非 GDI 函数，甚至对一些 GDI 函数，永远使用设备坐标。<br /><br />由于映射方式是一种设备描述表属性，所以，只有对需要设备描述表句柄作参数的 GDI 函数，映射方式才会起作用。<br /><br />Windows 将 GDI 函数中指定的逻辑坐标映射为设备坐标。<br /><br /><strong>所有设备坐标系都以像素为单位，水平轴（即x轴）上的值从左到右递增，垂直轴（即y轴）上的值从上到下递增。 
<hr />
</strong>设备坐标系包括：&#8220;屏幕坐标&#8221;、&#8220;整窗口坐标&#8221;和&#8220;客户区坐标&#8221;。<br />
<hr />
屏幕坐标：<br />当我们使用整个屏幕时，就根据&#8220;屏幕坐标&#8221;进行操作。屏幕的左上角为(0,0)点，屏幕坐标用在 WM_MOVE 消息（对于非子窗口）以及下列 Windows 函数中：CreateWindow 和 MoveWindow（都是对于非子窗口）、GetMessagePos,GetCursorPos,SetCursorPos,GetWindowRect，以及 WindowFromPoint(这不是全部函数的列表)。<br />如果以 DISPLAY 为参数调用 CreateDC ，以获取整个屏幕的设备描述表，则默认情况下 GDI 调用中指定的逻辑坐标将被映射为屏幕坐标。<br />
<hr />
</div>整窗口坐标：<br />&#8220;整窗口坐标&#8221;以程序的整个窗口为基准，如标题栏、菜单、滚动条和窗口框都包括在内。而对于普通窗口，点(0,0)是缩放边框的左上角。<br />整窗口坐标在 Windows 中极少使用，但是如果用 GetWindowDC 获取设备描述表，GDI&nbsp;函数中的逻辑坐标就会转换为客户区坐标。<br />
<hr />
客户区坐标系：<br />点(0,0)是客户区的左上角。当使用 GetDC 或 BeginPaint 获取设备描述表时，GDI&nbsp;函数中的逻辑坐标就会默认地转换为客户区坐标。<br /><br />设备坐标系之间的转换：<br />用函数 ClientToScreen 和 ScreenToClient 可以将客户区坐标转换为屏幕坐标，或者反过来，将屏幕坐标转换为客户区坐标。<br />可以使用 GetWindowRect 函数获取屏幕坐标下的整个窗口的位置和大小。<br />
<hr /><img src ="http://www.cppblog.com/Dream5/aggbug/163701.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2012-01-06 11:15 <a href="http://www.cppblog.com/Dream5/articles/163701.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>GDI 映射方式</title><link>http://www.cppblog.com/Dream5/articles/163670.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Thu, 05 Jan 2012 16:23:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/163670.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/163670.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/163670.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/163670.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/163670.html</trackback:ping><description><![CDATA[在默认情况下，程序都是相对于客户区的左上角，以像素为单位绘图的。<br /><br />&#8220;映射方式&#8221;是一种几乎影响任何客户区绘图的设备描述表属性。<br />另外有4种设备描述表属性&#8212;&#8212;窗口原点、视口原点、窗口范围和视口范围&#8212;&#8212;与映射方式密切相关。<br /><br />GDI 绘图函数中需要的传入的坐标值使用的都是一种&#8220;逻辑单位&#8221;。Windows 必须将逻辑单位转换为&#8220;设备单位&#8221;，即像素。这种转换方式由映射方式、窗口和视口原点，以及窗口和视口的范围所控制的。<br /><br />Windows 定义了8种映射方式：&nbsp;
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 118.8pt; padding-right: 5.4pt; border-top: black 1pt solid; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="158">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">&nbsp;</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 106.35pt; padding-right: 5.4pt; border-top: black 1pt solid; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="142">
<p>&nbsp;</p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 191.35pt; padding-right: 5.4pt; border-top: black 1pt solid; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="255" colspan="2">
<p align="center"><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">增加值</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 118.8pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="158">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">映射方式</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 106.35pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="142">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">逻辑单位 </span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 92.1pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="123">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">X</span><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">值</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 99.25pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="132">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">Y</span><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">值</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 118.8pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="158">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">MM_TEXT</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 106.35pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="142">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">像素</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 92.1pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="123">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">右</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 99.25pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="132">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">下</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 118.8pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="158">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">MM_LOMETRIC</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 106.35pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="142">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">0.1 mm</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 92.1pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="123">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">右</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 99.25pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="132">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">上</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 118.8pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="158">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">MM_HIMETRIC</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 106.35pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="142">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">0.01 mm</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 92.1pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="123">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">右</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 99.25pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="132">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">上</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 118.8pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="158">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">MM_LOENGLISH</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 106.35pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="142">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">0.01 in.</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 92.1pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="123">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">右</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 99.25pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="132">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">上</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 118.8pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="158">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">MM_HIENGLISH</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 106.35pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="142">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">0.001 in.</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 92.1pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="123">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">右</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 99.25pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="132">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">上</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 118.8pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="158">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">MM_TWIPS</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 106.35pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="142">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">1/1440 in.</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 92.1pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="123">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">右</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 99.25pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="132">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">上</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 118.8pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="158">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">MM_ISOTROPIC</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 106.35pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="142">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">任意(x = y)</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 92.1pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="123">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">可选</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 99.25pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="132">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">可选</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 118.8pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="158">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">MM_ANISOTROPIC</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 106.35pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="142">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">任意(x != y)</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 92.1pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="123">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">可选</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 99.25pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="132">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">可选</span></p></td></tr></tbody></table><br />设置映射方式：<br />SetMapMode(hdc,iMapMode);<br />iMapMode 是8个映射方式标识符之一。<br /><br />获取当前的映射方式：<br />iMapMode = GetMapMode(hdc);<br /><br />默认映射方式为 MM_TEXT。在这种方式下，逻辑单位与物理单位（也叫设备单位）相同，这样就可以直接以像素为单位进行操作。<br />示例：<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000">//</span><span style="color: #008000">&nbsp;MM_TEXT&nbsp;映射方式下：</span><span style="color: #008000"><br /></span><span style="color: #000000">TextOut(hdc,</span><span style="color: #000000">8</span><span style="color: #000000">,</span><span style="color: #000000">16</span><span style="color: #000000">,TEXT(</span><span style="color: #000000">"</span><span style="color: #000000">Hello</span><span style="color: #000000">"</span><span style="color: #000000">),</span><span style="color: #000000">5</span><span style="color: #000000">);<br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;文本从距离客户区左端8像素、上端16像素的位置处开始。<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;MM_LOENGLISH&nbsp;映射方式下：</span><span style="color: #008000"><br /></span><span style="color: #000000">TextOut(hdc,</span><span style="color: #000000">50</span><span style="color: #000000">,</span><span style="color: #000000">-</span><span style="color: #000000">100</span><span style="color: #000000">,TEXT(</span><span style="color: #000000">"</span><span style="color: #000000">Hello</span><span style="color: #000000">"</span><span style="color: #000000">),</span><span style="color: #000000">5</span><span style="color: #000000">);<br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;文本从距离客户区左端0.5英寸、上端1英寸的位置处开始。</span></div><img src ="http://www.cppblog.com/Dream5/aggbug/163670.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2012-01-06 00:23 <a href="http://www.cppblog.com/Dream5/articles/163670.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>绘制填充区域</title><link>http://www.cppblog.com/Dream5/articles/163634.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Thu, 05 Jan 2012 08:57:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/163634.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/163634.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/163634.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/163634.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/163634.html</trackback:ping><description><![CDATA[<div><strong>Windows 中7个用来画带边缘的填充图形的函数如下表所示：</strong>&nbsp; 
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: black 1pt solid; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">函数</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: black 1pt solid; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">图形</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">Rectangle</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">直角矩形</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">Ellipse</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">椭圆</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">RoundRect</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">圆角矩形</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">Chord</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">椭圆周上的弧，两端以弦连接</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">Pie</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">椭圆上的饼图</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">Polygon</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">多边形</span></p></td></tr>
<tr>
<td style="border-bottom: black 1pt solid; border-left: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">PolyPolygon</span></p></td>
<td style="border-bottom: black 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 213.05pt; padding-right: 5.4pt; border-top: medium none; border-right: black 1pt solid; padding-top: 0cm" valign="top" width="284">
<p><span style="font-family: 'YaHei Consolas Hybrid','sans-serif'">多个多边形</span></p></td></tr></tbody></table></div><em>Windows 用设备描述表中选择的当前画笔来画图形的边界框，边界框还使用当前背景方式、背景色彩和绘图方式，这跟 Windows 画线时一样。<br />图形以当前设备描述表中选择的刷子来填充。默认情况下，使用现有对象，这意味着图形内部将画为白色。<br /><br /></em><strong>Windows 定义了6种现有刷子：<br /></strong>WHITE_BRUSH,LTGRAY_BRUSH,GRAY_BRUSH,DKGRAY_BRUSH,BLACK_BRUSH 和 NULL_BRUSH(也叫 HELLOW_BRUSH).<br />可以将任何一种现有画刷选入设备描述表中，就和选择画笔一样。<br /><br /><strong>Windows 将 HBRUSH 定义为刷子的句柄。<br /><br />刷子的获取和选入：<br /></strong>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000">//</span><span style="color: #008000">&nbsp;定义一个刷子句柄变量</span><span style="color: #008000"><br /></span><span style="color: #000000">HBRUSH&nbsp;hBrush;<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;获取&nbsp;GRAY_BRUSH&nbsp;的句柄</span><span style="color: #008000"><br /></span><span style="color: #000000">hBrush&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;GetStockObject(GRAY_BRUSH);<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;选进设备描述表</span><span style="color: #008000"><br /></span><span style="color: #000000">SelectObject(hdc,hBrush);<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;现在如果要画上表中的任一个图形，则其内部为灰色。</span><span style="color: #008000"><br /></span><span style="color: #000000"><br /></span><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;------------------------------------------</span><span style="color: #008000">*/</span><span style="color: #000000"><br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;如果想画一个没有边界框的图形，可以将&nbsp;NULL_PEN&nbsp;选进设备描述表：</span><span style="color: #008000"><br /></span><span style="color: #000000">SelectObject(hdc,GetStockObject(NULL_PEN));<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;如果想画出图形的边界框，但不填充内部，则将&nbsp;NULL_BRUSH&nbsp;选进设备描述表：</span><span style="color: #008000"><br /></span><span style="color: #000000">SelectObject(hdc,GetStockObject(NULL_BRUSH));</span></div><br />对于 Polygon 和 PolyPolygon 函数，Windows 使用定义在设备描述表中的当前画刷来填充这个带边界的区域。至于填充内部的方式，则取决于多边形填充方式，可以用SetPolyFillMode 函数来设置：<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">SetPolyFillMode(hdc,iMode);</span></div><em>默认情况下，多边形填充方式是 ALTERNATE，但是可以将它设置为 WINDING。<br /></em><br /><strong>用画刷填充内部：<br /></strong>Rectangle,RoundRect,Ellipse,Chord,Pie,Polygon 和 PolyPolygon 图形的内部是用选进设备描述表的当前画刷（也成为&#8220;模式&#8221;）来填充的。<br />画刷是一个 8 * 8 的位图，它水平和垂直地重复使用来填充内部区域。<br /><br /><strong>逻辑画刷：<br /></strong>与逻辑画笔一样，逻辑画刷也是 GDI 对象。创建的所有画刷都必须被删除，但是当它还在设备描述表中时不能将其删除。<br /><br />Windows 有5个函数可以用来创建逻辑画刷，然后就可使用 SelectObject 将画刷选进设备描述表。<br />创建逻辑画刷的<strong>第一个函数</strong>：<br />hBrush = CreateSolidBrush(crColor);<br />函数中的 Solid 并不是指画刷为纯色。在将画刷选入设备描述表中时，Windows 创建一个抖动色的位图，并为画刷使用该位图。<br /><br />可以使用由水平、垂直或者倾斜的线组成的&#8220;影线标记(hatch marks)&#8221;来创建画刷，<strong>第二个函数</strong>为创建影线画刷的函数：<br />hBrush = CreateHatchBrush(iHatchStyle,crColor);<br />iHatchStyle 参数描述影线标记的外观，有6种可用的影线标记风格：HS_HORIZONTAL,HS_BDIAGONAL,HS_VERTICAL,HS_CROSS,HS_FDIAGONAL,HS_DIAGCROSS;<br />crColor 参数是影线的色彩，在将画刷选进设备描述表时，Windows 将这种色彩转换为与之最相近的纯色。影线之间的区域根据设备描述表中定义的背景方式和背景色来着色。如果背景方式为 OPAQUE，则用背景色（它也被转换为纯色）来填充线之间的空间。在这种情况下，影线和填充线都不能是抖动色。如果背景方式为 TRANSPARENT，则 Windows 只画出影线，不填充它们之间的区域。<br /><br /><strong>第三、第四个函数</strong>：<br />CreatePatternBrush 和 CreateDIBPatternBrushPt<br />创建基于位图的画刷。<br /><br /><strong>第5个函数：<br /></strong>hBrush = CreateBrushIndirect(&amp;logbrush);<br />变量 logbrush 是一个类型为 LOGBRUSH（&#8220;逻辑画刷&#8221;）的结构。<br /><br />和画笔一样，用 SelectObject 将画刷选进设备描述表，用 DeleteObject 删除画刷，用GetObject 来获取逻辑画刷的信息：<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000">//</span><span style="color: #008000">&nbsp;将画刷选进设备描述表</span><span style="color: #008000"><br /></span><span style="color: #000000">SelectObject(hdc,hBrush);<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;删除所创建的画刷</span><span style="color: #008000"><br /></span><span style="color: #000000">DeleteObject(hBrush);<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;获取画刷的信息</span><span style="color: #008000"><br /></span><span style="color: #000000">GetObject(hBrush,</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(LOGBRUSH),(LPVOID)</span><span style="color: #000000">&amp;</span><span style="color: #000000">logbrush);</span></div><strong>注意：不要删除当前选进设备描述表的画刷。</strong><img src ="http://www.cppblog.com/Dream5/aggbug/163634.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2012-01-05 16:57 <a href="http://www.cppblog.com/Dream5/articles/163634.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>绘图方式</title><link>http://www.cppblog.com/Dream5/articles/163632.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Thu, 05 Jan 2012 08:34:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/163632.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/163632.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/163632.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/163632.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/163632.html</trackback:ping><description><![CDATA[设备描述表中定义的绘图方式也影响显示器上所画线的外观。<br /><br /><strong>当 Windows 使用画笔来画线时，它实际上执行画笔像素与目标位置处原来像素之间的某种按位布尔运算</strong>。像素间的按位布尔运算叫做&#8220;光栅运算&#8221;，简记为&#8220;ROP&#8221;。由于画一条直线只涉及两种像素（画笔和目标），因此这种运算又称为&#8220;二元光栅运算&#8221;，简记为&#8220;ROP2&#8221;。<br /><br />Windows 定义了16种 ROP2 代码，表示 Windows 组合画笔像素和目标像素的方式。在默认设备描述表中，绘图方式定义为 R2_COPYPEN，这意味着 Windows 只是将画笔像素复制到目标像素。<br /><br />可以通过以下调用在设备描述表中设置新的绘图模式：
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000">//</span><span style="color: #008000">&nbsp;iDrawMode&nbsp;参数是预定义的绘图模式的值之一</span><span style="color: #008000"><br /></span><span style="color: #000000">SetROP2(hdc,iDrawMode);<br /></span></div><br />可以用 GetROP2 函数来获取设备描述表中当前绘图方式：<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">iDrawMode&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;GetROP2(hdc);</span></div><br /><img src ="http://www.cppblog.com/Dream5/aggbug/163632.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2012-01-05 16:34 <a href="http://www.cppblog.com/Dream5/articles/163632.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>画笔</title><link>http://www.cppblog.com/Dream5/articles/163556.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Wed, 04 Jan 2012 08:22:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/163556.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/163556.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/163556.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/163556.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/163556.html</trackback:ping><description><![CDATA[<div>1. 当调用画线函数时，Windows 使用设备描述表中当前选中的&#8220;画笔&#8221;来画线。<br /><br />2. 画笔决定线的色彩、宽度和线型，线型可以是实线、点划线或者虚线，默认设备描述表中画笔为&nbsp; BLACK_PEN。不管映射方式什么，这种画笔都画出一个象素宽的黑色实线来。<br /><br />3. Windows 提供的三种现有画笔：BLACK_PEN,WHITE_PEN 和 NULL_PEN.NULL_PEN 什么都不画。可以自己定制画笔。<br /><br />4. Windows 程序使用句柄来引用画笔。画笔句柄的类型为&nbsp;HPEN类型。<br /><br />5. 调用 GetStockObject 函数可以获得现有画笔的句柄；调用 SelectObject 函数将画笔选进设备描述表，SelectObject 的返回值是此调用前设备描述表中的画笔句柄，即，SelectObject 将返回设备描述表中上一次选择的画笔句柄。 
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000">//</span><span style="color: #008000">&nbsp;假设想使用名为&nbsp;WHITE_PEN&nbsp;的现有画笔，可以如下获取画笔的句柄</span><span style="color: #008000"><br /></span><span style="color: #000000"><br />HPEN&nbsp;hPen;<br /><br />hPen&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;GetStockObject(WHITE_PEN);<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;将画笔选进设备描述表</span><span style="color: #008000"><br /></span><span style="color: #000000">SelectObject(hdc,hPen);<br /></span></div>当前的画笔是白色，在这个调用后，你画的线将使用 WHITE_PEN，直到i你将另外一个画笔选进设备描述表或者释放设备描述表句柄为止。<br /><br />6. 创建自己的画笔，通常是：<br />使用函数 CreatePen 或 CreatePenIndirect 创建一个&#8220;逻辑画笔&#8221;（这仅仅是对画笔的描述），这些函数返回逻辑画笔的句柄；然后，调用 SelectObject 将画笔选进设备描述表，现在可以使用新的画笔来画线了。<br />在任何时候，都只能有一种画笔选进设备描述表。在释放设备描述表（或者选择了另一种画笔到设备描述表中）之后，就可以调用 DeleteObject 来删除所创建的逻辑画笔了。在删除后，该画笔的句柄就不再有效了。<br /><br />7. 逻辑画笔是一种&#8220;GDI（图形设备接口）&#8221;对象；程序员可以创建六种的 GDI 对象：画笔、刷子、位图、区域、字体和调色板。<br />&nbsp;&nbsp;&nbsp; 除了调色板之外，这些对象都是通过 SelectObject 选进设备描述表的。<br /><br />8. 使用 GDI 对象应该遵守的三条规则：<br />&nbsp;&nbsp;&nbsp; <em>最后要删除自己创建的所有 GDI 对象；<br />&nbsp;&nbsp;&nbsp; 当 GDI 对象正在一个有效的设备描述表中时，不要删除它；<br />&nbsp;&nbsp;&nbsp; 不要删除现有对象。<br /></em><br />9. 如果有一个画笔的句柄，就可以通过调用 GetObject 获取 LOGPEN 结构各个成员的值：<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #000000">GetObject(hPen,</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(LOGPEN),(LPVOID)</span><span style="color: #000000">&amp;</span><span style="color: #000000">logpen);</span></div><br />10. 如果需要当前选进设备描述表的画笔句柄，可以调用：<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">hPen&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;GetCurrentObject(hdc,OBJ_PEN);</span></div></div><br />11.&nbsp;使用点式画笔和虚线画笔时，点和虚线之间的空隙问题。<br /><em>空隙的着色取决于设备描述表的两个属性&#8212;&#8212;背景模式和背景颜色。<br />默认的背景模式为 OPAQUE，在这种方式下，Windows 使用背景色来填充空隙，默认的背景色为白色。<br />可以通过调用 SetBkColor(hdc,crColor); 来改变 Windows 用来填充空隙的背景色。<br />通过调用 GetBkColor 来获取设备描述表中定义的当前背景色。<br />通过将背景模式转换为 TRANSPARENT，可以阻止 Windows 填充空隙：SetBkMode(hdc,TRANSPARENT); 此后，Windows 将忽略背景色，并且不填充空隙，可以通过 GetBkMode&nbsp;来获取当前背景模式（TRANSPARENT 或者 O</em>PAQUE）。&nbsp; <br /><img src ="http://www.cppblog.com/Dream5/aggbug/163556.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2012-01-04 16:22 <a href="http://www.cppblog.com/Dream5/articles/163556.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设备描述表（二）</title><link>http://www.cppblog.com/Dream5/articles/163262.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Sat, 31 Dec 2011 07:01:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/163262.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/163262.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/163262.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/163262.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/163262.html</trackback:ping><description><![CDATA[Windows 使用设备描述表来保存控制 GDI 函数在显示器上如何操作的&#8220;属性&#8221;。例如，在使用 TextOut 函数显示文本时，程序员不必指定文本的色彩和字体，Windows 从设备描述表获取这个信息。<br /><br />程序获取一个设备描述表句柄时，Windows 用默认值设置所有的属性。<br /><br />1. Windows 98 支持的设备描述表属性，程序可以改变或者获取任何一种属性。<br />&nbsp; 
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tbody>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175">
<p><span style="font-family: 宋体">设备描述表属性</span></p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168">
<p><span style="font-family: 宋体">默认值</span></p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p><span style="font-family: 宋体">修改该值的函数</span></p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228">
<p><span style="font-family: 宋体">获取该值的函数</span></p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175">
<p>Mapping Mode</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168">
<p>MM_TEXT</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SetMapMode</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228">
<p>GetMapMode</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175" rowspan="2">
<p>Window Orign</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168" rowspan="2">
<p>(0,0)</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SetWindowOrgEx</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228" rowspan="2">
<p>GetWindowOrgEx</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>OffsetWindowOrgEx</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175" rowspan="2">
<p>Viewport Orign</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168" rowspan="2">
<p>(0,0)</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SetViewportOrgEx</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228" rowspan="2">
<p>GetViewportOrgEx</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>OffsetViewportOrgEx</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175" rowspan="3">
<p>Window Extents</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168" rowspan="3">
<p>(1,1)</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SetWindowExtEx</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228" rowspan="3">
<p>GetWindowExtEx</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SetMapMode</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>ScaleWindowExtEx</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175" rowspan="3">
<p>Viewport Extents</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168" rowspan="3">
<p>(1,1)</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SetViewportExtEx</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228" rowspan="3">
<p>GetViewportExtEx</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SetMapMode</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>ScaleViewportExtEx</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175">
<p>Pen</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168">
<p>BLACK_PEN</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SelectObject</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228">
<p>SelectObject</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175">
<p>Brush</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168">
<p>WHITE_BRUSH</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SelectObject</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228">
<p>SelectObject</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175">
<p>Font</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168">
<p>SYSEMT_FONT</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SelectObject</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228">
<p>SelectObject</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175">
<p>Bitmap</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168">
<p>None</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SelectObject</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228">
<p>SelectObject</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175" rowspan="4">
<p>Current Position</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168" rowspan="4">
<p>(0,0)</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>MoveToEx</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228" rowspan="4">
<p>GetCurrentPositionEx</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>LineTo</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>PolylineTo</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>PolyBezierTo</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175">
<p>Background Mode</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168">
<p>OPAQUE</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SetBkMode</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228">
<p>GetBkMode</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175">
<p>Background Color</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168">
<p>White</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SetBkColor</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228">
<p>GetBkColor</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175">
<p>TextColor</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168">
<p>Black</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SetTextColor</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228">
<p>GetTextColor</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175">
<p>Drawing Mode</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168">
<p>R2_COPYPEN</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SetROP2</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228">
<p>GetROP2</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175">
<p>Stretching Mode</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168">
<p>BLACKONWHITE</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SetStretchBltMode</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228">
<p>SetStretchBltMode</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175">
<p>Polygon Fill Mode</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168">
<p>ALTERNATE</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SetPolyFillMode</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228">
<p>GetPolyFillMode</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175">
<p>Intercharacter</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168">
<p>0</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SetTextCharacterExtra</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228">
<p>GetTextCharacterExtra</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175">
<p>Spacing</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168">
<p>&nbsp;</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>&nbsp;</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228">
<p>&nbsp;</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175">
<p>Brush Origin</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168">
<p>(0,0)</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SetBrushOrgEx</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228">
<p>GetBrushOrgEx</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 131.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="175" rowspan="6">
<p>Clipping Region</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 126pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="168" rowspan="6">
<p>None</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SelectObject</p></td>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 171pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="228" rowspan="6">
<p>GetClipBox</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SelectClipRgn</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>IntersectClipRgn</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>OffsetClipRgn</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>ExcludeClipRect</p></td></tr>
<tr>
<td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 162pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="216">
<p>SelectClipPath</p></td></tr></tbody></table><br />2. 保存设备描述表<br />通常，在您调用 GetDC 或 BeginPaint 时，Windows 用默认值创建一个新的设备描述表句柄，您对属性所做的一切改变在设备描述表用 ReleaseDC 或 EndPaint 调用释放时，都会丢失。<br />如果您的程序需要使用非默认的设备描述表属性，则您必须在每次获取设备描述表句柄时初始化设备描述表：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000ff">case</span><span style="color: #000000">&nbsp;WM_PAINT:<br />&nbsp;&nbsp;hdc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;BeginPaint(hwnd,</span><span style="color: #000000">&amp;</span><span style="color: #000000">ps);<br />&nbsp;&nbsp;[initialize&nbsp;device&nbsp;context&nbsp;attributes]<br />&nbsp;&nbsp;[paint&nbsp;client&nbsp;area&nbsp;of&nbsp;window]<br />&nbsp;&nbsp;EndPaint(hwnd,</span><span style="color: #000000">&amp;</span><span style="color: #000000">ps);<br />&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;</span></div>虽然通常情况下这种方法已经很令人满意了，但是您还可能想要在释放设备描述表之后，仍然保存程序中对设备描述表属性所做的改变，以便在下一次调用 GetDC 和 BeginPaint 时，它们仍然能够起作用。<br />为此，可在登陆（注册）窗口类时，将 CS_OWNDC 标志包含为窗口类的一部分：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">wndclass.style&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;CS_HREDRAW&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;CS_VREDRAW&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;CS_OWNDC;</span></div>现在基于这个窗口类所创建的每个窗口都将拥有自己的设备描述表，它一直存在，直到窗口被删除。如果使用了 CS_OWNDC 风格，就只需初始化设备描述表一次，可以在处理 WM_CREATE 消息期间完成这一操作：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000ff">case</span><span style="color: #000000">&nbsp;WM_CREATE:<br />&nbsp;&nbsp;hdc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;GetDC(hwnd);<br />&nbsp;&nbsp;[initialize&nbsp;device&nbsp;context&nbsp;attributes]<br />&nbsp;&nbsp;ReleaseDC(hwnd,hdc);</span></div>这些属性在改变之前一直有效。<br />CS_OWNDC 风格只影响 GetDC 和 BeginPaint 获得的设备描述表，不影响其他函数（如 GetWindowDC）获得的设备描述表。<br />即使使用了 CS_OWNDC，您仍然应该在退出窗口过程之前释放设备描述表。<br /><br />在某些情况下，您可能想改变某些设备描述表属性，用改变后的属性进行绘图，然后恢复原来的设备描述表。要简化这一过程可以像下面这样做：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000">//</span><span style="color: #008000">&nbsp;保存设备描述表的状态</span><span style="color: #008000"><br /></span><span style="color: #000000">idSaved&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;SaveDC(hdc);<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;now,可以改变一些属性，在想要回到调用&nbsp;SaveDC&nbsp;前存在的设备描述表时，调用：</span><span style="color: #008000"><br /></span><span style="color: #000000">RestoreDC(hdc,idSaved);<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;可以在调用&nbsp;RestoreDC&nbsp;之前调用&nbsp;SaveDC&nbsp;数次&nbsp;</span></div><br />RestoreDC 和 SaveDC 的另一种使用方式：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #008000">//</span><span style="color: #008000">&nbsp;调用&nbsp;SaveDC&nbsp;时，不需要保存返回值：</span><span style="color: #008000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">SaveDC(hdc);<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;然后，您可以更改某些属性并再次调用&nbsp;SaveDC,要将设备描述表恢复到一个已经保存的状态，调用：</span><span style="color: #008000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">RestoreDC(hdc,</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">);<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;这就将设备描述表恢复到最近由&nbsp;SaveDC&nbsp;函数保存的状态中</span></div><img src ="http://www.cppblog.com/Dream5/aggbug/163262.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2011-12-31 15:01 <a href="http://www.cppblog.com/Dream5/articles/163262.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>锁的使用：一些有用的窍门和技巧</title><link>http://www.cppblog.com/Dream5/articles/163158.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Thu, 29 Dec 2011 16:50:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/163158.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/163158.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/163158.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/163158.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/163158.html</trackback:ping><description><![CDATA[<div><strong>1. 以原子方式操作一组对象时使用一个锁。<br /></strong><br /><strong>2. 同时访问多个逻辑资源。<br /></strong>必须在代码中的任何地方以完全相同的顺序来获得资源的锁。<br /><br /><strong>3. 不要长时间占用锁。<br /></strong>如果一个锁被长时间占用，那么其他线程可能会进入等待状态，这会影响到应用程序的性能。<br />我们可以用下面这个技巧来把花在关键段中的时间降至最低。 
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000">//</span><span style="color: #008000">&nbsp;下面的代码会在&nbsp;WM_SOMEMSG&nbsp;消息被发送到另一个窗口之前阻止其他线程修改&nbsp;g_s&nbsp;的值</span><span style="color: #008000"><br /></span><span style="color: #000000"><br />SOMESTRUCT&nbsp;g_s;<br />CRITICAL_SECTION&nbsp;g_cs;<br /><br />DWORD&nbsp;WINAPI&nbsp;SomeThread(PVOID&nbsp;pvParam)<br />{<br />&nbsp;&nbsp;EnterCriticalSection(</span><span style="color: #000000">&amp;</span><span style="color: #000000">g_cs);<br /><br />&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;Send&nbsp;a&nbsp;message&nbsp;to&nbsp;a&nbsp;window</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;SendMessage(hWndSomeWnd,WM_SOMEMSG,</span><span style="color: #000000">&amp;</span><span style="color: #000000">g_s,</span><span style="color: #000000">0</span><span style="color: #000000">);<br /><br />&nbsp;&nbsp;LeaveCriticalSection(</span><span style="color: #000000">&amp;</span><span style="color: #000000">g_cs);<br />&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />}</span></div><br /><em>我们不可能知道窗口过程(Window procedure)需要多长时间来处理 WM_SOMEMSG 消息，可能只需要几微妙，也可能需要几年。在这段时间内，其他线程都无法得到 g_s 的访问权。把前述代码写成下面这种形式会更好。<br /><br /></em>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">SOMESTRUCT&nbsp;g_s;<br />CRITICAL_SECTION&nbsp;g_cs;<br /><br />DWORD&nbsp;WINAPI&nbsp;SomeThread(PVOID&nbsp;pvParam)<br />{<br />&nbsp;&nbsp;EnterCriticalSection(</span><span style="color: #000000">&amp;</span><span style="color: #000000">g_cs);<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;SOMESTRUCT&nbsp;sTemp&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;g_s;<br /><br />&nbsp;&nbsp;LeaveCriticalSection(</span><span style="color: #000000">&amp;</span><span style="color: #000000">g_cs);<br /><br />&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;Send&nbsp;a&nbsp;message&nbsp;to&nbsp;a&nbsp;window</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;SendMessage(hWndSomeWnd,WM_SOMEMSG,</span><span style="color: #000000">&amp;</span><span style="color: #000000">sTemp,</span><span style="color: #000000">0</span><span style="color: #000000">);<br /><br />&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000"><em>;<br />}</em></span></div><br /><em>这个技巧假设窗口过程只需读取结构的&#8220;快照&#8221;就已经足够了，它同时还假设窗口过程不需要修改结构中的成员。<br /></em><br /></div><img src ="http://www.cppblog.com/Dream5/aggbug/163158.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2011-12-30 00:50 <a href="http://www.cppblog.com/Dream5/articles/163158.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用户模式下的线程同步（三）—— 高级线程同步</title><link>http://www.cppblog.com/Dream5/articles/162922.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Wed, 28 Dec 2011 07:49:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/162922.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/162922.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/162922.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/162922.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/162922.html</trackback:ping><description><![CDATA[<div><strong>2. 旋转锁</strong> 
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000">//</span><span style="color: #008000">&nbsp;旋转锁伪代码<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;Global&nbsp;variable&nbsp;indicating&nbsp;whether&nbsp;a&nbsp;shared&nbsp;resource&nbsp;is&nbsp;in&nbsp;use&nbsp;or&nbsp;not&nbsp;</span><span style="color: #008000"><br /></span><span style="color: #000000">BOOL&nbsp;g_fResourceInUse&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;FALSE;&nbsp;<br /><img alt="" src="http://www.cppblog.com/Images/dot.gif" /><br /></span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;Func1(){<br />&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;Wait&nbsp;to&nbsp;access&nbsp;the&nbsp;resource.</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(&nbsp;InterlockedExchange(</span><span style="color: #000000">&amp;</span><span style="color: #000000">g_fResourceInUse,TRUE)&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;TRUE&nbsp;)<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;sleep(</span><span style="color: #000000">0</span><span style="color: #000000">);<br />&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;Access&nbsp;the&nbsp;resource</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;<img alt="" src="http://www.cppblog.com/Images/dot.gif" /><br /><br />&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;We&nbsp;no&nbsp;longer&nbsp;need&nbsp;to&nbsp;access&nbsp;the&nbsp;resource.</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;InterlockedExchange(</span><span style="color: #000000">&amp;</span><span style="color: #000000">g_fResourceInUse,FALSE)<em>;<br />}</em></span></div><em>while 循环不停地运行，把 g_fResourceInUse 的值设为 TRUE 并检查原来的值是否为 TRUE。如果原来的值为 FALSE，那说明资源尚未被使用，于是调用线程立刻就能将它设为&#8220;使用中&#8221;，然后退出循环。如果原来的值是 TRUE，那说明有其他的线程正在使用该资源，于是 while 循环会继续执行。<br /></em><br />对那些用到旋转锁的线程来说，我们可能想要（调用 SetProcessPriorityBoost 或 SetThreadPriorityBoost 来）禁用线程优先级提升（thread priority boosting）。<br />在单 CPU 的机器上应该避免使用旋转锁<span>。如果一个线程不停地循环，那么这不仅会浪费宝贵的 CPU 时间，而且会阻止其</span><span>他线程改变锁的值。</span><br /><span>旋转锁假定被保护的资源始终只会被占用一小段时间。与切换到内</span><span>核模式然后等待相比，在这种情况下以循环的方式进行等</span><span>待的效率</span><span style="color: red">会更高。</span><br />&nbsp;<br /><span style="color: #ff0000">当线程试图进入一个关键段，但这个关键段正被另一个线程占用的时候，函数会立即把调用线程切换到等待状态。这意味着线程必须从用户</span><span style="color: #ff0000">模</span>式切换到内核模式（大约1000个ＣＰＵ周期），这个切换的开销非常大。<br /><br /><strong>3. 关键段和旋转锁<br /></strong>为了提高关键段的性能，Microsoft 把旋转锁合并到了关键段中。因此，当调用 EnterCriticalSection 的时候，它会用一个旋转锁不断地循环，尝试在<strong>一段时间内</strong>获得对资源的访问权。只有当尝试失败的时候，线程才会切换到内核模式并进入等待状态。<br /><br /><strong>为了在使用关键段的时候同时使用旋转锁，我们必须调用下面的函数来初始化关键段：</strong> 
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">BOOL&nbsp;InitializeCriticalSectionAndSpinCount(PCRITICAL_SECTION&nbsp;pcs,DWORD&nbsp;dwSpinCount);<br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;pcs,关键段结构的地址<br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;dwSpinCount,旋转锁循环的次数</span></div><em>在把线程切换到等待状态之前，函数会先尝试用旋转锁来获得对资源的访问权。这个值可以是从0到0x00FFFFFF之间的任何一个值。<br />如果我们在单处理器的机器上调用这个函数，那么函数会忽略 dwSpinCount 参数，因此次数总是为0。<br /></em><br /><strong>我们可以调用下面的函数来改变关键段的旋转次数：<br /></strong>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">DWORD&nbsp;SetCriticalSectionSpinCount(PCRITICAL_SECTION&nbsp;pcs,DWORD&nbsp;dwSpinCount);<br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;如果主机只有一个单处理器，函数会忽略&nbsp;dwSpinCount　参数</span></div></div><br /><strong>我们应该总是在使用关键段的时候同时使用旋转锁，因为这样做不会损失任何东西。<br /></strong>用来保护进程堆的关键段所使用的旋转次数大约是4000。<br /><br /><strong>4. Slim 读/写锁<br /></strong>SRWLock 的目的和关键段相同：对一个资源进行保护，不让其他线程访问它。但是，与关键段不同的是，SRWLock 允许我们区分那些想要读取资源的线程（读取者线程）和想要更新资源的值的线程（写入者线程）。<br /><br /><strong>提供的功能：<br /></strong>让所有的读取者线程在同一时刻访问共享资源应该是可行的，这是因为仅仅读取资源的值并不存在破坏数据的风险。<br />只有当写入者线程想要对资源进行更新的时候才需要进行同步。在这种情况下，写入者线程应该独占对资源的访问权：任何其他线程，无论是读取者线程还是写入者线程，都不允许访问资源。<br /><br />使用 SRWLock：<br />首先，分配一个 SRWLOCK 结构并用 InitializeSRWLock 函数对它进行初始化：<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">VOID&nbsp;InitializeSRWLock(PSRWLOCK&nbsp;SRWLock);</span></div><br />一旦 SRWLock<span style="color: #ff0000"> </span><span style="color: #000000">的初始化</span>完成之后，写入者线程就可以调用 AcquireSRWLockExclusive,将 SRWLock 对象的地址作为参数传入，以尝试获得对被保护的资源的<strong>独占访问权</strong>。<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">VOID&nbsp;AequireSRWLockExclusive(PSRWLOCK&nbsp;SRWLock);</span></div>完成对资源的更新之后，应该调用 ReleaseSRWLockExclusive，并将　SRWLOCK 对象的地址作为参数传入，这样就解除了对资源的锁定。<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">VOID&nbsp;ReleaseSRWLockExclusive(PSRWLOCK&nbsp;SRWLock);</span></div><br />对于读取者线程来说同样有两个类似的步骤：<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">VOID&nbsp;AcquireSRWLockShared(PSRWLOCK&nbsp;SRWLock);<br /><br />VOID&nbsp;ReleaseSRWLockShared(PSRWLOCK&nbsp;SRWLock);</span></div><br /><strong>如果锁已经被占用，那么调用 AcquireSRWLock(Shared/Exclusive) 会阻塞调用线程。<br />不能递归地获得 SRWLOCK。即，一个线程不能为了多次写入资源而多次锁定资源，然后再多次调用 ReleaseSRWLock* 来释放对资源的锁定。<br /></strong>不存在用来删除或销毁 SRWLOCK 的函数，系统会自动执行清理工作。<br /><br /><strong>5. 条件变量<br /></strong>有时我们想让<strong>线程以原子方式把锁释放并将自己阻塞，直到某一个条件成立为止</strong>。要实现这样的线程同步是比较复杂的。<br />Windows 通过 SleepConditionVariableCS 或 SleepConditionVariableSRW 函数，通过了一种<strong>条件变量</strong>，来帮助我们简化这种情形下所需的工作。<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">BOOL&nbsp;SleepConditionVariableCS(PCONDITION_VARIABLE&nbsp;pConditionVariable,PCRITICAL_SECTION&nbsp;pCriticalSection,DWORD&nbsp;dwMilliseconds);<br /><br /><br />BOOL&nbsp;SleepConditionVariableSRW(PCONDITION_VARIABLE&nbsp;pConditionVariable,PSRWLOCK&nbsp;pSRWLock,DWORD&nbsp;dwMilliseconds,ULONG&nbsp;Flags);</span></div><em>参数 pConditionVariable 指向一个已初始化的条件变量，调用线程正在等待该条件变量。<br /><br />第二个参数是一个指向关键段或者 SRWLock 的指针，该关键段或 SRWLock 用来同步对共享资源的访问。<br /><br />参数 dwMilliseconds 表示我们希望线程花多少时间（可以设成INFINITE）来等待条件变量被触发。<br /><br />第二个函数中的 Flags 参数用来指定一旦条件变量被触发，我们希望线程以何种方式来得到锁：对写入者线程来说，应该传入0，表示希望独占对资源的访问；对读取者线程来说，应该传入 CONDITION_VARIABLE_LOCKMODE_SH<strong>ARED，表示希望共享对资源的访问。<br /></strong></em><br /><strong>当指定的时间用完的时候，如果条件变量尚未被触发，函数会返回 FALSE，否则函数会返回 TRUE。注意，当函数返回FALSE的</strong>时候，线程显然并没有得到锁或关键段。<br /><br />当另一个线程检测到相应的条件已经满足的时候，比如存在一个元素可以让读取者线程读取，或者有足够的空间让写入者线程插入新的元素，它会调用 WakeConditionVariable 或 WakeAllConditionVariable，这样<strong>阻塞</strong>在 Sleep* 函数中的线程就会被唤醒。<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">VOID&nbsp;WakeConditionVariable(PCONDITION_VARIABLE&nbsp;ConditionVariable);</span></div><em>当我们调用 WakeConditionVariable 的时候，会使一个在　SleepConditionVariable* 函数中等待同一个条件变量被触发的线程得到锁并返回。当这个线程释放同一个锁的时候，不<em>会唤醒其他正在等待同一个条件变量的线程。</em><br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">VOID&nbsp;WakeAllConditionVariable(PCONDITION_VARIABLE&nbsp;ConditionVariable);</span></div>当调用 WakeAllConditionVariable 的时候，会使一个或几个在 SleepConditionVariable* 函数中等待这个条件变量被触发的线程得到对资源的访问权并返回。<br />唤醒多个线程是可以的，因为我们确信如果我们请求独占对资源的访问，那么同一时刻必定只有一个写入者线程得到锁，如果我们传给 Flag 参数的是 CONDITION_VARIABLE_LOCKMODE_SHARED，那么在同一时刻可以允许多个读取者线程得到锁。</em><br /><br /><strong>总结：<br /></strong><em>如果希望应用程序中得到最佳性能，那么首先应该尝试不要共享数据，然后依次使用 volatile 读取，volatile 写入，Interlocked API，SRWLock 以及关键段。当且仅当所有这些都不能满足要求的时候，再使用内核对象。</em> <img src ="http://www.cppblog.com/Dream5/aggbug/162922.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2011-12-28 15:49 <a href="http://www.cppblog.com/Dream5/articles/162922.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用户模式下的线程同步（二）—— 高级线程同步</title><link>http://www.cppblog.com/Dream5/articles/162877.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Mon, 26 Dec 2011 16:30:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/162877.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/162877.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/162877.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/162877.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/162877.html</trackback:ping><description><![CDATA[<strong>概述：</strong>浪费CPU时间是件非常糟糕的事情，所以在实现用户模式下的线程同步时，我们需要一种机制，它既能让线程等待共享资源的访问权，又不会浪费CPU时间。<br /><br /><strong>实现原理：<br /></strong>当线程想要访问一个共享资源或者想要得到一些&#8220;特殊事件&#8221;的通知时，线程必须调用操作系统的一个函数，并将线程正在等待的东西作为参数传入。如果<strong style="font-size: 12pt">操作系统</strong>检测到资源已经可供使用了，或者特殊事件已经发生了，那么这个函数会立即返回，这样线程将仍然保持可调度状态。（线程可能并不会立即运行，它是可调度的，系统会根据一定的规则来给它分配CPU时间。）<br /><br />如果无法取得对资源的访问权，或者特殊事件尚未发生，那么<strong style="font-size: 12pt">系统</strong>会将线程切换到等待状态，使线程变得不可调度，从而避免了让线程浪费CPU时间。当线程在等待的时候，系统会充当它的代理。系统会记住线程想要访问什么资源，当资源可供使用的时候，它会自动将线程唤醒&#8212;&#8212;线程的执行与特殊事件是同步的。 <br /><br /><strong>1. 关键段<br /></strong>关键段（critical section）是一小段代码，它在执行之前需要独占对一些共享资源的访问权。这种方式可以让多行代码以&#8220;原子方式&#8221;来对资源进行操控。<br />这里的<strong>原子方式</strong>，指的是代码知道除了当前线程之外，没有其他任何线程会同时访问该资源。<br />当然，系统仍然可以暂停当前线程去调度其他线程。但是，在当前线程离开关键段之前，系统是不会去调度任何想要访问同一资源的其他线程的。<br /><br />定义关键段类型的变量： 
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000">//</span><span style="color: #008000">&nbsp;定义一个&nbsp;CRITICAL_SECTION&nbsp;类型的变量</span><span style="color: #008000"><br /></span><span style="color: #000000">CRITICAL_SECTION&nbsp;cs;</span></div><br />当我们有一个资源要让多个线程访问的时候，应该创建一个 CRITICAL_SECTION 结构。<br /><em>一个比喻：一个 CRITICAL_SECTION 结构就像是飞机上的一个卫生间，而马桶则是我们想要保护的数据。由于卫生间很小，因此在同一时刻只允许一个人（线程）在卫生间（关键段）内使用马桶（被保护的资源）。<br /></em><br /><strong>关键段的最大缺点在于它们无法用来在多个进程之间对线程进行同步。<br /><br />关键段细节：<br /></strong>使用 CRITICAL_SECTION 结构的两个必要条件<em>：<br />第一个条件是所有想要访问共享资源的线程必须知道用来保护资源的 CRITICAL_SECTION 结构的地址。<br />第二个条件是在任何线程试图访问被保护的资源之前，必须对 CRITICAL_SECTION 结构的内部成员进行初</em>始化。<br /><br /><strong>下面的函数用来对结构进行初始化：<br /></strong>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">VOID&nbsp;InitializeCriticalSection(PCRITICAL_SECTION&nbsp;pcs);</span></div>在调用 EnterCriticalSection 之前必须调用这个函数。<br /><br /><strong>当知道线程将不再需要访问共享资源的时候，我们应该调用下面的函数来清理 CRITICAL_SECTION结构：<br /></strong>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">VOID&nbsp;DeleteCriticalSection(PCRITICAL_SECTION&nbsp;pcs);</span></div><br /><strong>在对共享资源进行访问之前，必须在代码中先调用下面的函数：</strong> 
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">VOID&nbsp;EnterCriticalSection(PCRITICAL_SECTION&nbsp;pcs);</span></div>EnterCriticalSection 会检查（CRITICAL_SECTION）结构中的成员变量，这些变量表示是否有线程正在访问资源，以及那个线程正在访问资源。<br /><strong>EnterCriticalSection 会执行下面的测试：<br /></strong><em>如果没有线程正在访问资源，那么 EnterCriticalSection 会更新成员变量，以表示调用线程已经获准对资源的访问，并立即返回，这样线程就可以继续执行（访问资源）。<br /><br />如果成员变量表示调用线程已经获准访问资源，那么 EnterCriticalSection 会更新变量，以表示调用线程被获准访问的次数，并立即返回，这样线程就可以继续执行。这种情况非常少见，只有当线程在调用 LeaveCriticalSection 之前连续调用 EnterCriticalSection 两次以上才会发生。<br /><br />如果成员变量表示有一个（调用线程之外的其他）线程已经获准访问资源，那么 EnterCriticalSection 会使用一个<strong>事件内核对象</strong>来把调用线程切换到等待状态。系统会记住这个线程想要访问这个资源，一旦当前正在访问资源的线程调用了 LeaveCriticalSection，系统会自动更新 CRITICAL_SECTION 的成员变量并将等待中的线程切换到可调度状态。<br /><br /></em>EnterCriticalSection 的内部并不怎么复杂，它只不过是执行了一些简单的测试。这个函数的价值在于它能够以原子方式执行所有这些测试。<br /><br /><strong>TryEnterCriticalSection 函数：<br /></strong>TryEnterCriticalSection 从来不会让调用线程进入等待状态。它会通过返回值来表示调用线程是否获准访问资源。因此，如果 TryEnterCriticalSection 发现资源正在被其他线程访问，那么它会返回 FALSE。其他情况下，它会返回 TRUE。<br /><br />通过使用这个函数，线程可以快速地检查它是否能够访问某个共享资源。如果不能访问共享资源，那么它可以继续做些其他的事情，而不用等待。如果 TryEnterCriticalSection 返回 TRUE，那么 CRITICAL_SECTION 的成员变量已经更新过了，以表示该线程正在访问资源。因此，每个返回值为 TRUE 的 TryEnterCriticalSection 调用必须有一个对应的 LeaveCriticalSection。<br /><br />可以使用 TryEnterCriticalSection 函数来代替 EnterCriticalSection。<br /><br /><strong>在代码完成对共享资源的访问后，应该调用下面的函数：<br /></strong>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">VOID&nbsp;LeaveCriticalSection(PCRITICAL_SECTION&nbsp;pcs);</span></div>LeaveCriticalSection 会检查结构内部的成员变量并将计数器减1，该计数器用来表示调用线程获准访问共享资源的次数。如果计数器大于0，LeaveCriticalSection 会直接返回，不执行任何其他操作。<br />如果计数器变成了0，LeaveCriticalSection 会更新成员变量，以表示没有任何线程正在访问被保护的资源。它同时会检查有没有其他线程由于调用了 EnterCriticalSection 而处于等待状态。如果至少有一个线程处于等待状态，那么函数会更新成员变量，把其中一个处于等待状态的线程切换回可调度状态。<br />与 EnterCriticalSection 相似，LeaveCriticalSection&nbsp;会以原子方式执行所有的测试和更新操作。但是，LeaveCriticalSection 从来不会把线程切换到等待状态，它总是立即返回。 <img src ="http://www.cppblog.com/Dream5/aggbug/162877.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2011-12-27 00:30 <a href="http://www.cppblog.com/Dream5/articles/162877.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>volatile 关键字</title><link>http://www.cppblog.com/Dream5/articles/162878.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Mon, 26 Dec 2011 14:58:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/162878.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/162878.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/162878.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/162878.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/162878.html</trackback:ping><description><![CDATA[<div>volatile 类型限定符告诉编译器被它修饰的变量可能会被应用程序之外的其他东西修改，比如操作系统、硬件或者一个并发执行的线程。<br /><strong>确切地说，volatile 限定符告诉编译器不要对这个变量（被 volatile 修饰的变量）进行任何形式的优化，而是始终从变量在内存中的位置读取变量的值。<br /><br /></strong>如果不给变量加上 volatile 限定符，编译器可能会对 C++ 代码进行优化。在这个优化中，编译器把变量的值载入到 CPU 寄存器中，这个操作只需要进行一次。然后它只对 CPU 寄存器中的值进行引用，与每次都从变量所在的内存地址取得变量的值并进行使用相比，优化操作能够得到更好的性能。<br /><br />给一个结构加 volatile 限定符等于给结构中所有的成员都加 volatile 限定符，这样可以确保任何一个成员始终都是从内存中读取的。<br /><br />如果传一个变量的地址给函数，那么函数必须从内存中读取它的值，编译器的优化程序不会对此产生影响。<br /><br />备注：<br />volatile: 易变的（英文注释）。</div><img src ="http://www.cppblog.com/Dream5/aggbug/162878.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2011-12-26 22:58 <a href="http://www.cppblog.com/Dream5/articles/162878.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>图形设备接口</title><link>http://www.cppblog.com/Dream5/articles/162453.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Tue, 20 Dec 2011 03:34:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/162453.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/162453.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/162453.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/162453.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/162453.html</trackback:ping><description><![CDATA[图形设备接口（GDI:Graphics Device Interface）是 Windows 的子系统，负责在视频显示器和打印机上显示图形。<br /><br />GDI 的主要目的之一是支持与设备无关的图形。<br /><br />图形输出设备分为两大类：光栅设备和矢量设备。<br />光栅设备以点模式来表示图像，这类设备包括视频显示适配器，点阵打印机和激光打印机。<br />矢量设备使用线来绘制图像，通常局限于绘图仪。<img src ="http://www.cppblog.com/Dream5/aggbug/162453.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2011-12-20 11:34 <a href="http://www.cppblog.com/Dream5/articles/162453.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>“进队消息” 与 “不进队消息”</title><link>http://www.cppblog.com/Dream5/articles/162451.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Tue, 20 Dec 2011 03:14:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/162451.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/162451.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/162451.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/162451.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/162451.html</trackback:ping><description><![CDATA[<div>Windows 给窗口发送消息，意味着 Windows 调用窗口过程。但是，Windows程序也有一个消息循环，它调用 GetMessage 从消息队列中取出消息，并且调用 DiapatchMessage 将消息发送给窗口过程。<br /><br />消息能够被分为&#8220;进队的&#8221; 和 &#8220;不进队的&#8221;。<br />进队的消息是由 Windows 放入程序消息队列中。在程序的消息循环中，重新返回并分配给窗口过程。<br />不进队的消息在 Windows 调用窗口时直接送给窗口过程。<br />即，进队的消息被&#8220;发送&#8221;给消息队列，而不进队的消息则&#8220;发送&#8221;给窗口过程。<br /><br /><strong>在任何情况下，窗口过程都将获得窗口所有的消息&#8212;&#8212;包括进队的和不进队的。窗口过程是窗口的&#8220;消息中心&#8221;。<br /></strong><br />进队消息基本上是用户输入的结果，以击键（如 WM_KEYDOWN 和 WM_KEYUP 消息）、击键产生的字符（WM_CHAR）、鼠标移动（WM_MOUSEMOVE）和鼠标键（WM_LBUTTONDOWN）的形式给出。进队消息还包括时钟消息（WM_TIMER）、刷新消息（WM_PAINT）和退出消息（WM_QUIT）。<br />&nbsp;<br />不进队消息则是其他消息。在许多情况下，不进队消息来自调用特定的 Windows 函数。例如，当 WinMain 调用 CreateWindow 时，Windows 将给窗口过程发送一个 WM_CREATE 消息。当 WinMain 调用 ShowWindow 时，Windows 将给窗口过程发送 WM_SIZE 和 WM_SHOWWINDOW 消息。当 WinMain 调用 UpdateWindow 时，Windows 将给窗口过程发送 WM_PAINT 消息。<br />键盘或鼠标输入时发出的进队消息信息，也能在不进队消息中出现。</div><img src ="http://www.cppblog.com/Dream5/aggbug/162451.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2011-12-20 11:14 <a href="http://www.cppblog.com/Dream5/articles/162451.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Scroll Bar（滚动条）</title><link>http://www.cppblog.com/Dream5/articles/162311.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Sat, 17 Dec 2011 13:39:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/162311.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/162311.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/162311.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/162311.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/162311.html</trackback:ping><description><![CDATA[<div><strong>Windows（操作系统）对滚动条的处理：<br /></strong><span style="color: #993300; font-size: 10pt">处理所有滚动条鼠标事件；</span><br /><span style="color: #993300; font-size: 10pt">当用户在滚动条内单击鼠标时，提供一种&#8220;反相视频&#8221;闪烁；</span><br /><span style="color: #993300; font-size: 10pt">当用户在滚动条内拖动滚动框时，移动滚动框；</span><br /><span style="color: #993300; font-size: 10pt">为包含滚动条窗口的窗口过程发送滚动条消息。</span><br /><br /><strong>程序员对于滚动条应该完成的工作：<br /></strong><span style="color: #993300; font-size: 10pt">初始化滚动条的范围和位置；</span><br /><span style="color: #993300; font-size: 10pt">处理窗口过程的滚动条消息；</span><br /><span style="color: #993300; font-size: 10pt">更新滚动条内滚动框的位置；</span><br /><span style="color: #993300; font-size: 10pt">更改客户区的内容以响应对滚动条的更改。</span><br /><br /><strong>滚动条消息（WM_VSCROLL 和 WM_HSCROLL）：<br /></strong>在用鼠标单击滚动条或者拖动滚动框时，Windows 给窗口过程发送 WM_VSCROLL（供上下移动）和 WM_HSCROLL（供左右移动）消息。<br />在滚动条上的每个鼠标动作都至少产生两个消息，一个在按下鼠标键时产生，一个在释放键时产生。<br /><br /><strong>wParam 和 lParam 消息参数：<br /></strong>与所有的消息一样，WM_VSCROLL 和 WM_HSCROLL 也带有 wParam 和 lParam 消息参数。对于来自作为窗口的一部分而创建的滚动条消息，可以忽略 lParam；它只用于作为子窗口而创建的滚动条（通常在对话框内）。<br /><br /><strong>wParam 消息参数：<br /></strong>wParam 消息参数被分为一个低位字和一个高位字。低位字是一个数值，它指出了鼠标对滚动条进行的操作。这个数值被看作一个&#8220;通知码&#8221;。<br />通知码的值由以SB（代表"scroll bar"（滚动条））开头的标识符定义。<br /><br /><strong>通知码：<br /></strong>SB_LINEUP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;// 按下垂直滚动条的顶部按钮<br />SB_LINEDOWN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 按下垂直滚动条的底部按钮<br />SB_LINELEFT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 按下水平滚动条的左部按钮<br />SB_LINERIGHT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 按下水平滚动条的右部按钮<br />SB_ENDSCROLL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 释放滚动条上的鼠标光标<br />SB_PAGEUP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 按下垂直滚动条上滚动框与顶部按钮之间的空白位置<br />SB_PAGEDOWN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 按下垂直滚动条上滚动框与底部按钮之间的空白位置<br />SB_PAGELEFT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 按下水平滚动条上滚动框与左部按钮之间的空白位置<br />SB_PAGERIGHT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 按下水平滚动条上滚动框与右部按钮之间的空白位置<br />SB_THUMBTRACK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 按下滚动条上的滚动框<br />SB_THUMBPOSITION&nbsp; // 释放滚动框上的鼠标按钮<br /><br /><strong>其他通知码（对于作为应用程序窗口一部分而创建的滚动条来说，以下这些通知码永远不会接收到）：<br /></strong>SB_TOP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 滚动框被移到了最顶部 <br />SB_BOTTOM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 滚动框被移到了最底部<br />SB_LEFT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; // 滚动框被移到了最左部<br />SB_RIGHT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 滚动框被移动了最右部<br /><br /><strong>SB_THUMBTRACK 和 SB_THUMBPOSITION：<br /></strong>当 wParam 的低位字是 SB_THUMBTRACK 时，wParam的高位字是用户在拖动滚动框时的当前位置。该位置位于滚动条范围的最小值和最大值之间。<br />当 wParam 的低位字是 SB_THUMBPOSITION 时，wParam的高位字是用户释放鼠标键后滚动框的最终位置。<br />对于其他的滚动条操作，wParam 的高位字应该被忽略。<br /></div><img src ="http://www.cppblog.com/Dream5/aggbug/162311.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2011-12-17 21:39 <a href="http://www.cppblog.com/Dream5/articles/162311.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设备描述表（一） </title><link>http://www.cppblog.com/Dream5/articles/162216.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Fri, 16 Dec 2011 03:25:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/162216.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/162216.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/162216.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/162216.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/162216.html</trackback:ping><description><![CDATA[设备描述表（简称为&#8220;DC&#8221;）实际上是 GDI（图形设备接口）内部保存的数据结构。设备描述表与特定的显示设备（如视频显示器或打印机）相关。<br /><br />在窗口的客户区域显示文本和图形需要设备描述表句柄。 <br />当您想在一个图像输出设备（诸如屏幕或者打印机）上绘图时，您首先必须获得一个设备描述表（或者DC）的句柄。将句柄返回给程序时，Windows 就给了您使用设备的权限。然后您在 GDI 中将这个句柄作为一个参数，向 Windows 标识您想在其上进行绘图的设备。<br /><br />设备描述表中的有些值是图形化的&#8220;属性&#8221;，这些属性定义了一些GDI绘图函数工作情况的特殊内容。例如，对于 TextOut(hdc,x,y,psText,iLength),设备描述表的属性确定了文本的颜色、文本的背景色、TextOut函数的 x 坐标和 y 坐标映射到窗口的客户区的方式，以及显示文本时 Windows 使用的字体。<br /><br />当程序需要绘图时，它必须先获取设备描述表句柄。在获取了该句柄后，Windows 用默认的属性值填充内部设备描述表结构。<br />可以通过调用不同的 GDI 函数改变这些默认值。<br />利用其它的 GDI 函数可以获取这些属性的当前值。<br />还有其它的 GDI 函数能够在窗口的客户区真正地绘图。<br /><br />当程序在客户区绘图完毕后，它必须释放设备描述表句柄。句柄被释放后就不再有效，且不能再被使用。<br /><br />程序必须在处理单个消息期间获取和释放句柄。<br /><br />除了调用 CreateDC 函数创建的设备描述表之外，程序不能在两个消息之间保存其它设备描述表句柄。<br /><br />Windows 应用程序一般使用两种方法来<strong>获取窗口客户区中的设备描述表句柄</strong>，以备在屏幕上绘图。<br />方法一： <br />在处理 WM_PAINT 消息时，使用这种方法。它涉及 BeginPaint 和 EndPaint两个函数。 
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #000000">hdc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;BeginPaint(hwnd,</span><span style="color: #000000">&amp;</span><span style="color: #000000">ps);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />[other&nbsp;program&nbsp;lines]<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />EndPaint(hwnd,</span><span style="color: #000000">&amp;</span><span style="color: #000000">ps);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span></div>BeginPaint 函数包含一个类型为 PAINTSTRUCT 结构的变量ps,该结构的hdc字段是 BeginPaint 返回的设备描述表句柄。PAINTSTRUCT 结构又包含一个名为 rcPaint 的 RECT （矩形）结构，rcPaint 定义一个包围窗口客户区无效范围的矩形。使用从 BeginPaint 获得的设备描述表句柄，只能在这个区域内绘图。BeginPaint 调用使该区域有效。<br /><br />方法二：<br />调用 GetDC 来获取句柄，ReleaseDC 来释放句柄。 <br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #000000">hdc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;GetDC(hwnd);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />[other&nbsp;program&nbsp;lines]<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />ReleaseDC(hwnd,hdc);</span></div>这个设备描述表句柄适用于窗口句柄为 hwnd 的客户区。<br />GetDC 和 ReleaseDC 不使客户区中任何可能的无效区域变成有效。<br /><br />Windows 程序还可以<strong>获取适用于整个窗口（而不仅限于窗口的客户区）的设备描述表句柄：<br /></strong>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">hdc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;GetWindowDC(hwnd);<br />[other&nbsp;program&nbsp;lines]<br />ReleaseDC(hwnd,hdc);</span></div>这个设备描述表除了客户区之外，还包括窗口的标题栏、菜单、滚动条和框架（frame）。GetWindowDC 函数很少使用，如果想尝试用一用它，则必须捕获 WM_NCPAINT（&#8220;非客户区绘制&#8221;）消息，Windows 使用该消息在窗口的非客户区上绘图。<br /><br /><strong>获取设备描述表句柄更通用的函数调用。<br /></strong>BeginPaint、GetDC 和 GetWindowDC 获得的设备描述表都与视频显示器上的某个特定窗口相关。获取设备描述表句柄的另一个更通用的函数是 CreateDC:<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">hdc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;CreateDC(pszDirver,pszDevice,pszOutput,pData);<br />[other&nbsp;program&nbsp;lines]<br />DeleteDC(hdc);</span></div>例如，可以通过下面的调用来获取整个屏幕的设备描述表句柄：<br />hdc = CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL);<br /><br /><strong>获取一个&#8220;信息描述表&#8221;的句柄：<br /></strong>有时候只是需要获取关于某设备描述表的一些信息而并不进行任何绘画，在这种情况下，可以使用 CreateIC 来获取一个&#8220;信息描述表&#8221;的句柄，其参数与 CreateDC 函数相同：<br />hdc = CreateIC(TEXT("DISPLAY"),NULL,NULL,NULL);<br />不能用这个信息环境句柄往设备上写东西。<br /><br />当使用位图时，<strong>获取一个&#8220;<strong>内存设备描述表&#8221;</strong>有时是有用的：<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #000000">hdcMem&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;CreateCompatibleDC(hdc);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />[other&nbsp;program&nbsp;lines]<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />DeleteDC(hdcMem);</span></div></strong>可以将位图选进内存设备描述表，然后使用GDI函数在位图上绘画。<br /><br />元文件是以二进制形式存储的 GDI 命令的集合。元文件主要用于通过剪切板传输矢量图形表示。<br />可以通过<strong>获取元文件设备描述表</strong>来创建元文件：<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #000000">hdcMeta&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;CreateMetaFile(pszFilename);&nbsp;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />[other&nbsp;program&nbsp;lines]<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />hmf&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;CloseMetaFile(hdcMeta);</span></div>在元文件设备描述表有效期间，任何用 hdcMeta 所做的 GDI 调用都变成元文件的一部分而不会显示。在调用 CloseMetaFile 之后，设备描述表句柄变为无效，函数返回一个指向元文件(hmf)的句柄。<br /><br />窗口的设备描述表定义了一个剪取区域。<br />对于从 GetDC 获取的设备描述表句柄，默认的剪取区域是整个窗口客户区；而对于从 BeginPaint 获取的设备描述表句柄，默认的剪取区域则为窗口客户区中的无效区域。<br />Windows 不会在剪取区域之外的任何位置显示字符串。 <br /><br />获取设备描述表信息：<br />一个设备描述表通常是指一个物理显示设备，如视频显示器和打印机。通常需要获取有关该设备的信息，其中包括显示器的显示尺寸（单位为像素或者物理度量）和色彩范围。<br />可以通过调用 GetDeviceCaps（&#8220;获取设备能力&#8221;）函数来获取这些信息：<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">iValue&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;GetDeviceCaps(hdc,iIndex);</span></div> <img src ="http://www.cppblog.com/Dream5/aggbug/162216.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2011-12-16 11:25 <a href="http://www.cppblog.com/Dream5/articles/162216.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WM_PAINT 消息</title><link>http://www.cppblog.com/Dream5/articles/162212.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Fri, 16 Dec 2011 02:54:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/162212.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/162212.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/162212.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/162212.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/162212.html</trackback:ping><description><![CDATA[<span style="font-size: 12pt">第一个 WM_PAINT 消息：</span><br /><span style="font-size: 12pt">大多数 Windows 程序在 WinMain 中进入消息循环之前的初始化期间都要调用函数 UpdateWindow。Windows（操作系统） 利用这个机会给窗口过程发送第一个WM_PAINT消息。这个消息通知窗口过程：必须绘制客户区。</span><br /><br /><strong style="font-size: 12pt">在发生下面几种事件之一时，窗口过程会接收到一个WM_PAINT消息：</strong><strong><br /></strong><span style="color: #993300; font-size: 10pt">在用户移动窗口或显示窗口时，窗口中先前被隐藏的区域重新可见；</span><br /><span style="color: #993300; font-size: 10pt">用户改变窗口的大小（如果窗口类风格具有　CS_HREDRAW 和　CS_VERDRAW 位设置）；</span><br /><span style="color: #993300; font-size: 10pt">程序使用 ScrollWindow 或 ScrollDC 函数滚动客户区的一部分；</span><br /><span style="color: #993300; font-size: 10pt">程序使用 InvalidateRect 或 InvalidateRgn 函数显示产生　WM_PAINT 消息。</span><br /><br /><strong style="font-size: 12pt">在某些情况下，客户区的一部分被临时覆盖，Windows 试图保存一个显示区域，并在以后恢复它，但这并不总是能成功的。下面的情况下，Windows 可能会发送 WM_PAINT 消息：</strong><strong><br /></strong><span style="color: #993300; font-size: 10pt">Windows 擦除覆盖了部分窗口的对话框或消息框；</span><br /><span style="color: #993300; font-size: 10pt">菜单下拉出来，然后被释放；</span><br /><span style="color: #993300; font-size: 10pt">显示工具提示。</span><span style="color: #993300; font-size: 10pt"><br /></span><span style="font-size: 10pt"><br /></span><span style="font-size: 12pt"><strong>在某些情况下，Windows 总是保存它所覆盖的显示区域，然后恢复它。这些情况是：</strong></span><span style="font-size: 12pt"><strong><br /></strong></span><span style="color: #993300; font-size: 10pt">鼠标光标穿越客户区；<br /></span><span style="color: #993300; font-size: 10pt">图标拖过客户区。<br /></span><span style="color: #993300; font-size: 10pt"><br /><br /><br /></span><img src ="http://www.cppblog.com/Dream5/aggbug/162212.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2011-12-16 10:54 <a href="http://www.cppblog.com/Dream5/articles/162212.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>消息循环</title><link>http://www.cppblog.com/Dream5/articles/162175.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Thu, 15 Dec 2011 08:06:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/162175.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/162175.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/162175.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/162175.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/162175.html</trackback:ping><description><![CDATA[<div>1. Windows（操作系统）为当前运行的每个Windows程序维护一个&#8220;消息队列&#8221;。在发生输入事件（用户用鼠标和键盘向窗口输入数据）之后，Windows（操作系统）将事件转换为一个&#8220;消息&#8221;，并将消息放入程序的消息队列中。<br /><br />2. 程序通过执行一块被称为&#8220;消息循环&#8221;的代码从消息队列中取出消息： 
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">while</span><span style="color: #000000">(&nbsp;GetMessage(</span><span style="color: #000000">&amp;</span><span style="color: #000000">msg,NULL,</span><span style="color: #000000">0</span><span style="color: #000000">,</span><span style="color: #000000">0</span><span style="color: #000000">)&nbsp;)<br /><img id="Codehighlighter1_35_88_Open_Image" onclick="this.style.display='none'; Codehighlighter1_35_88_Open_Text.style.display='none'; Codehighlighter1_35_88_Closed_Image.style.display='inline'; Codehighlighter1_35_88_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img id="Codehighlighter1_35_88_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_35_88_Closed_Text.style.display='none'; Codehighlighter1_35_88_Open_Image.style.display='inline'; Codehighlighter1_35_88_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top"></span><span id="Codehighlighter1_35_88_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_35_88_Open_Text"><span style="color: #000000">{<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;TranslateMessage(</span><span style="color: #000000">&amp;</span><span style="color: #000000">msg);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;DispatchMessage(</span><span style="color: #000000">&amp;</span><span style="color: #000000">msg);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div>msg变量是类型为MSG的结构，类型MSG在WINUSER.H中定义如下：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">typedef&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;tagMSG<br />{<br />&nbsp;&nbsp;HWND&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hwnd;<br />&nbsp;&nbsp;UINT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;message;<br />&nbsp;&nbsp;WPARAM&nbsp;&nbsp;&nbsp;wParam;<br />&nbsp;&nbsp;LPARAM&nbsp;&nbsp;&nbsp;lParam;<br />&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;&nbsp;time;<br />&nbsp;&nbsp;POINT&nbsp;&nbsp;&nbsp;&nbsp;pt;<br />}MSG,</span><span style="color: #000000">*</span><span style="color: #000000">PMSG;</span></div>POINT数据类型也是一个结构，在WINDEF.H中定义如下：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">typedef&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;tagPOINT<br />{<br />&nbsp;&nbsp;LONG&nbsp;x;<br />&nbsp;&nbsp;LONG&nbsp;y;<br />}POINT,</span><span style="color: #000000">*</span><span style="color: #000000">PPOINT;</span></div></div><br />3. 消息循环以GetMessage调用开始，它从消息队列中取出一个消息：GetMessage(&amp;msg,NULL,0,0);<br />这一调用传给Windows（操作系统）一个指向名为msg的MSG结构的指针。第二、第三和第四个参数设置为NULL或者0，表示程序接收它自己创建的所有窗口的所有消息。<br />Windows 用从消息队列中取出的下一个消息来填充消息结构的各个域，结构的各个域包括： 
<hr />
hwnd&nbsp;&nbsp;&nbsp; 消息发向的窗口的句柄。<br />message&nbsp;&nbsp;&nbsp; 消息标识符。这是一个数值，用以标识消息。<br />wParam&nbsp;&nbsp;&nbsp; 一个32位的"message parameter（消息参数）"，其含义和数值根据消息的不同而不同。<br />lParam&nbsp;&nbsp;&nbsp; 一个32位的消息参数，其值与消息有关。<br />time&nbsp;&nbsp;&nbsp; 消息放入消息队列中的时间。<br />pt&nbsp;&nbsp;&nbsp; 消息放入消息队列时的鼠标坐标。<br />
<hr />
只要从消息队列中取出消息的message域不为WM_QUIT（其值为0x0012）,GetMessage就返回一个非零值。WM_QUIT消息将导致GetMessage返回0。<br /><br />4. 语句TranslateMessage(&amp;msg);将msg结构传给Windows（操作系统），进行一些键盘转换。<br /><br />5. 语<span>句DispatchMessage(&amp;msg);又将msg结构回传给Windows</span><span>。然后，Windows 将该消</span>息发送给适当的窗口过程，让它进行处理。这也就是说，<strong>Windows将调用窗口过程。<br /></strong>处理完消息后，窗口过程返回到Windows（操作系统）。此时Windows还停留在DispatchMessage调用中。在结束DispatchMessage调用的处理后，Windows回到程序，并且接着从下一个GetMessage调用开始消息循环。 <img src ="http://www.cppblog.com/Dream5/aggbug/162175.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2011-12-15 16:06 <a href="http://www.cppblog.com/Dream5/articles/162175.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows 窗口</title><link>http://www.cppblog.com/Dream5/articles/162170.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Thu, 15 Dec 2011 07:32:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/162170.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/162170.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/162170.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/162170.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/162170.html</trackback:ping><description><![CDATA[<div>在Windows中，&#8220;窗口&#8221;一词有确切的含义。一个窗口就是屏幕上的一个矩形区域，它接受用户的输入，并以文本或图形的格式显示输出内容。<br /><br />窗口以&#8220;消息&#8221;的形式接收窗口的输入，窗口也用消息与其他窗口通讯。<br /><br />当用户改变窗口的大小时，<strong style="color: red">Windows(操作系统)给程序发送一条消息指出新窗口的大小</strong><span style="color: red">。</span>然后程序就可以调整窗口中的内容，以反映大小的变化。<br /><br />所谓&#8220;Windows给程序发送消息&#8221;，是指Windows调用程序中的一个函数，该函数的参数描述了这个特定消息。这种位于Windows程序中的函数被称为&#8220;窗口过程&#8221;。<br /><br />程序创建的每一个窗口都有相关的窗口过程。这个窗口过程是一个函数，既可以在程序中，也可以在动态连接库中。Windows通过调用窗口过程来给窗口发送消息。窗口过程根据此消息进行处理，然后将控制返回给Windows。<br /><br />窗口通常是在&#8220;窗口类&#8221;的基础上创建的。窗口类标识了处理窗口消息的窗口过程。<br />可以在单个窗口类的基础上创建多个窗口。<br />窗口类定义了窗口过程和基于此类创建的窗口的其他一些特征。在创建窗口时，要定义一些窗口所独有的特征。<br /><br />Windows程序开始执行后，Windows（操作系统）为该程序创建一个&#8220;消息队列&#8221;。这个消息队列用来存放该程序可能创建的各种不同窗口的消息。程序中有一小段代码，叫做&#8220;消息循环&#8221;，用来从消息队列中取出消息，并且将它们发送给相应的窗口过程。有些消息直接发送给窗口过程，不用放入消息队列中。<br /><br />Windows 中的每个窗口都有一个句柄，程序用句柄来引用窗口。<br /><br />关键字：窗口，窗口类，窗口过程，消息队列，消息循环和窗口消息。</div><img src ="http://www.cppblog.com/Dream5/aggbug/162170.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2011-12-15 15:32 <a href="http://www.cppblog.com/Dream5/articles/162170.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows句柄</title><link>http://www.cppblog.com/Dream5/articles/162154.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Thu, 15 Dec 2011 02:45:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/162154.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/162154.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/162154.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/162154.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/162154.html</trackback:ping><description><![CDATA[句柄是一个数（通常为32位），它代表一个对象。<br />程序几乎总是通过调用Windows函数获取句柄。程序在其他Windows函数中使用这个句柄，以引用它代表的对象。<br />句柄的实际值对程序来说是无关紧要的。但是，向您的程序提供句柄的Windows模块知道如何使用它来引用相应的对象。<br /><br />标识符&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 含义
<hr />
HINSTANCE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 实例（程序自身）句柄<br />HWND&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;窗口句柄<br />HDC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 设备描述表句柄<br />HICON&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 图标句柄<br />HCURSOR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 鼠标指针句柄<br />HBRUSH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 图形刷句柄<br />
<hr />
<br /><img src ="http://www.cppblog.com/Dream5/aggbug/162154.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2011-12-15 10:45 <a href="http://www.cppblog.com/Dream5/articles/162154.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows标识符前缀</title><link>http://www.cppblog.com/Dream5/articles/162150.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Thu, 15 Dec 2011 02:31:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/162150.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/162150.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/162150.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/162150.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/162150.html</trackback:ping><description><![CDATA[<div>前缀&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;类别 
<hr />
CS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 类风格选项<br />CW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 创建窗口选项<br />DT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 绘制文本选项<br />IDI&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 图标ID号<br />IDC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;光标ID号<br />MB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 消息框选项<br />SND&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 声音选项<br />WM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 窗口消息<br />WS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;窗口风格<br />
<hr />
<br /></div><img src ="http://www.cppblog.com/Dream5/aggbug/162150.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2011-12-15 10:31 <a href="http://www.cppblog.com/Dream5/articles/162150.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows函数简明描述</title><link>http://www.cppblog.com/Dream5/articles/162148.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Thu, 15 Dec 2011 02:20:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/162148.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/162148.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/162148.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/162148.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/162148.html</trackback:ping><description><![CDATA[LoadIcon&nbsp; 加载图标供程序使用<br />LoadCursor&nbsp; 加载鼠标指针供程序使用<br />GetStockObject&nbsp; 获取一个图象对象，如获取绘制窗口背景的刷子<br />RegisterClass&nbsp; 为程序窗口注册窗口类<br />MessageBox&nbsp; 显示消息框<br />CreateWindow&nbsp; 根据窗口类创建一个窗口<br />ShowWindow&nbsp; 在屏幕上显示窗口<br />UpdateWindow&nbsp; 指示窗口刷新自身<br />GetMessage&nbsp; 从消息队列中获取消息<br />TranslateMessage&nbsp; 转换某些键盘消息<br />DispatchMessage&nbsp; 将消息发送给窗口过程<br />PlaySound&nbsp; 播放一个声音文件<br />BeginPaint&nbsp; 开始窗口绘制<br />GetClientRect&nbsp; 获取窗口客户区的尺寸<br />DrawText&nbsp; 显示文本串<br />EndPaint&nbsp; 结束窗口绘制<br />PostQuitMessage&nbsp; 在消息队列中插入一条&#8220;退出&#8221;消息<br />DefWindowProc&nbsp; 执行默认的消息处理<br /><img src ="http://www.cppblog.com/Dream5/aggbug/162148.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2011-12-15 10:20 <a href="http://www.cppblog.com/Dream5/articles/162148.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WINDOWS头文件</title><link>http://www.cppblog.com/Dream5/articles/162011.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Tue, 13 Dec 2011 03:27:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/162011.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/162011.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/162011.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/162011.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/162011.html</trackback:ping><description><![CDATA[<div>WINDEF.H&nbsp; 基本类型定义；<br />WINNT.H&nbsp; 支持Unicode的类型定义；<br />WINBASE.H&nbsp; 内核函数；<br />WINUSER.H&nbsp; 用户接口函数；<br />WINGDI.H&nbsp; 图形设备接口函数。</div><img src ="http://www.cppblog.com/Dream5/aggbug/162011.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2011-12-13 11:27 <a href="http://www.cppblog.com/Dream5/articles/162011.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>术语</title><link>http://www.cppblog.com/Dream5/articles/162010.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Tue, 13 Dec 2011 03:22:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/162010.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/162010.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/162010.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/162010.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/162010.html</trackback:ping><description><![CDATA[<div>API：应用程序编程接口<br />EMS：扩充内存<br />DLL：动态链接库<br />GDI：图形设备接口<br />GUI：图形用户界面<br />MFC：Microsoft基础类库<br /></div><img src ="http://www.cppblog.com/Dream5/aggbug/162010.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2011-12-13 11:22 <a href="http://www.cppblog.com/Dream5/articles/162010.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用户模式下的线程同步（一）——Interlocked系列函数</title><link>http://www.cppblog.com/Dream5/articles/161954.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Mon, 12 Dec 2011 02:10:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/161954.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/161954.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/161954.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/161954.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/161954.html</trackback:ping><description><![CDATA[<div><strong>1. 原子访问：Interlocked系列函数&#8212;&#8212;Interlocked系列函数会以原子方式来操控一个值。</strong> 
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #008000">//</span><span style="color: #008000">&nbsp;传一个长整形变量的地址和另一个增量值，函数就会保证递增操作是以原子方式进行的。</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #000000">LONG&nbsp;InterlockedExchangeAdd(PLONG&nbsp;</span><span style="color: #0000ff">volatile</span><span style="color: #000000">&nbsp;plAddend,LONG&nbsp;lIncrement);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />LONGLONG&nbsp;InterlockedExchangeAdd64(PLONGLONG&nbsp;</span><span style="color: #0000ff">volatile</span><span style="color: #000000">&nbsp;pllAddend,LONGLONG&nbsp;llIncrement);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #008000">//</span><span style="color: #008000">InterlockedIncrement函数以原子方式给一个值加1。</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #000000">LONG&nbsp;InterlockedIncrement(IN&nbsp;PLONG&nbsp;Addend);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #008000">//</span><span style="color: #008000">InterlockedExchange和InterlockedExchangePointer会把第一个参数所指向的内存地址的当前值，以原子方式替换为第二个参数指定的值。</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #000000">LONG&nbsp;InterlockedExchange(OUT&nbsp;PLONG&nbsp;Target,IN&nbsp;LONG&nbsp;Value);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />LONGLONG&nbsp;InterlockedExchange64(PLONGLONG&nbsp;</span><span style="color: #0000ff">volatile</span><span style="color: #000000">&nbsp;plTarget,LONGLONG&nbsp;lValue);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />PVOID&nbsp;InterlockedExchangePointer(PVOID</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">volatile</span><span style="color: #000000">&nbsp;ppvTarget,PVOID&nbsp;pvValue);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #008000">//</span><span style="color: #008000">这两个函数都会返回原来的值。<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;InterlockedCompareExchange和InterlockedCompareExchangePointer函数以原子方式执行一个测试和设置操作。</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #000000">PVOID&nbsp;InterlockedCompareExchange(PLONG&nbsp;plDestination,LONG&nbsp;lExchange,LONG&nbsp;lComparand);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />PVOID&nbsp;InterlockedCompareExchangePointer(PVOID</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;ppvDestination,PVOID&nbsp;pvExchange,PVOID&nbsp;pvComparand);<br /></span></div><strong style="color: #ff0000">注意：我们必须确保传给这些函数的变量地址是经过对齐的，否则这些函数可能会失败。</strong><strong><br /></strong>C运行库提供了一个_aligned_malloc函数，我们可以使用这个函数来分配一块对齐过的内存：<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;_aligned_malloc(size_t&nbsp;size,size_t&nbsp;alignment);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;size表示要分配的字节数。<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;alignment表示要对齐到的字节边界，传给alignment参数的值必须是２的整数幂次方</span></div><br /><strong>Interlocked单向链表函数&#8212;&#8212;对Interlocked单向链表的栈进行操作，栈中的每个操作，比如入栈或出栈，必定是以原子方式进行的。</strong> <br />InitializeSListHead&nbsp;&nbsp;&nbsp; // 创建一个空栈 <br />InterlockedPushEntrySList&nbsp; // 在栈顶添加一个元素<br />InterlockedPopEntrySList&nbsp;&nbsp;&nbsp; // 移除位于栈顶的元素并将它返回<br />InterlockedFlushSList&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;清空栈<br />QueryDepthSList&nbsp;&nbsp;&nbsp; // 返回栈中元素的数量<br /></div><img src ="http://www.cppblog.com/Dream5/aggbug/161954.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2011-12-12 10:10 <a href="http://www.cppblog.com/Dream5/articles/161954.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>进程优先级 and 线程相对优先级 </title><link>http://www.cppblog.com/Dream5/articles/161103.html</link><dc:creator>梦五</dc:creator><author>梦五</author><pubDate>Tue, 29 Nov 2011 02:06:00 GMT</pubDate><guid>http://www.cppblog.com/Dream5/articles/161103.html</guid><wfw:comment>http://www.cppblog.com/Dream5/comments/161103.html</wfw:comment><comments>http://www.cppblog.com/Dream5/articles/161103.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Dream5/comments/commentRss/161103.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Dream5/services/trackbacks/161103.html</trackback:ping><description><![CDATA[进程都属于某个优先级类，另外可以指定进程中线程的相对线程优先级。<br />Windows支持6个优先级类（priority class）:idle,below normal,normal,above normal,high 和 real-time.<br /><br />进程优先级类解释：<br />real-time(实时)：此进程中的线程必须立即响应事件，执行实时任务。此进程中的线程还会抢占操作系统的组件的CPU时间。使用该优先级类需要极为小心。<br /><br />high(高)：此进程中的线程必须立即响应事件，执行实时任务。任务管理器运行在这一级，因此用户可以通过它结束失控的进程。<br /><br />above normal(高于标准)：此进程中的线程运行在 normal 和 high 优先级类之间。<br /><br />normal(标准)：此进程中的线程无需特殊的调度。<br /><br />below normal(低于标准)：此进程中的线程运行在 normal　和　idle　优先级类之间。<br /><br />idle(低)：此进程中的线程在系统空闲时运行。屏幕保护程序、后台实用程序和统计数据收集软件通常使用该进程。<br /><br /><span style="color: #ff0000">normal是最常用的优先级类，为99%的应用程序所使用。</span><br /><br />Windows支持7个相对线程优先级：idle,lowest,below normal,normal,above normal,highest 和 time-critical.<br />这些优先级是相对于进程优先级的。<br /><br />相对线程优先级解释：<br />time-critical：对于real-time优先级类，线程运行在31上；所有其他优先级运行在15.<br /><br />highest：线程运行在高于normal之上两个级别.<br /><br />above normal：线程运行在高于normal之上一个级别.<br /><br />normal：线程运行在进程normal级别上.<br /><br />below normal：线程运行在低于normal之下一个级别.<br /><br />lowest：线程运行在低于normal之下两个级别.<br /><br />idle：对于real-time优先级类，线程运行在16;所有其他优先级运行在1.<br /><br /><span style="color: #ff0000">大多数线程使用normal线程优先级。</span><br /><br /><strong style="color: #ff0000"><em><u>线程优先级是相对于进程优先级的。如果改变进程优先级，线程的相对优先级不变，但是优先级值将变化。<br /><br />进程永远无法调度，能调度的是线程。进程优先级是　Microsoft　提出的一个抽象概念，有助于用户无需了解调度程序的内部工作机理。</u></em></strong><strong><em><u><br /></u></em></strong>  <img src ="http://www.cppblog.com/Dream5/aggbug/161103.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Dream5/" target="_blank">梦五</a> 2011-11-29 10:06 <a href="http://www.cppblog.com/Dream5/articles/161103.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>