﻿<?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++博客-blindcoder</title><link>http://www.cppblog.com/blindcoder/</link><description /><language>zh-cn</language><lastBuildDate>Thu, 23 Apr 2026 10:15:22 GMT</lastBuildDate><pubDate>Thu, 23 Apr 2026 10:15:22 GMT</pubDate><ttl>60</ttl><item><title>追赶法解矩阵方程（c++实现）</title><link>http://www.cppblog.com/blindcoder/archive/2010/03/23/110348.html</link><dc:creator>The cpper</dc:creator><author>The cpper</author><pubDate>Tue, 23 Mar 2010 06:01:00 GMT</pubDate><guid>http://www.cppblog.com/blindcoder/archive/2010/03/23/110348.html</guid><wfw:comment>http://www.cppblog.com/blindcoder/comments/110348.html</wfw:comment><comments>http://www.cppblog.com/blindcoder/archive/2010/03/23/110348.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/blindcoder/comments/commentRss/110348.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/blindcoder/services/trackbacks/110348.html</trackback:ping><description><![CDATA[<div class="csharpcode"><pre class="alt"><span class="lnum">   1:  </span>#ifndef CHASEMETHORD_H</pre><pre><span class="lnum">   2:  </span><span class="preproc">#define</span> CHASEMETHORD_H</pre><pre class="alt"><span class="lnum">   3:  </span>#include &lt;assert.h&gt;</pre><pre><span class="lnum">   4:  </span><span class="preproc">#define</span> NULL 0</pre><pre class="alt"><span class="lnum">   5:  </span><span class="rem">/************************************************************************/</span></pre><pre><span class="lnum">   6:  </span><span class="rem">/* 功 能：追赶法接矩阵方程：Ax = y.</span></pre><pre class="alt"><span class="lnum">   7:  </span><span class="rem">/*        其中A必须是三对角矩阵，即非零元素分布在主对角线及其相邻两条次对角</span></pre><pre><span class="lnum">   8:  </span><span class="rem">/*        线上。</span></pre><pre class="alt"><span class="lnum">   9:  </span><span class="rem">/* 参 数：size_t n,    矩阵对角线元素个数[in]</span></pre><pre><span class="lnum">  10:  </span><span class="rem">/*        T*     a,    主对角线以下元素[in]</span></pre><pre class="alt"><span class="lnum">  11:  </span><span class="rem">/*        T*     b,    主对角线以上元素[in]</span></pre><pre><span class="lnum">  12:  </span><span class="rem">/*        T*     c,    主对角线元素[in]</span></pre><pre class="alt"><span class="lnum">  13:  </span><span class="rem">/*        T*     x,    矩阵的解集[out]</span></pre><pre><span class="lnum">  14:  </span><span class="rem">/*        T*     y,    y集[in]      </span></pre><pre class="alt"><span class="lnum">  15:  </span><span class="rem">/************************************************************************/</span></pre><pre><span class="lnum">  16:  </span>template &lt;typename T&gt;</pre><pre class="alt"><span class="lnum">  17:  </span><span class="kwrd">void</span> ChaseMethord(size_t n, T* a, T *b, T* c, T* x, T* f)</pre><pre><span class="lnum">  18:  </span>{</pre><pre class="alt"><span class="lnum">  19:  </span>    assert(a != NULL &amp;&amp; b != NULL &amp;&amp; c != NULL &amp;&amp; x != NULL &amp;&amp; f !=  NULL);</pre><pre><span class="lnum">  20:  </span>    </pre><pre class="alt"><span class="lnum">  21:  </span>    <span class="rem">//Ax = f =&gt; A = LU,即L(Ux) = f,又：令y = Ux,所以Ly = f;</span></pre><pre><span class="lnum">  22:  </span>    <span class="rem">//其中，L是下二对角矩阵，U是单位上二对角矩阵</span></pre><pre class="alt"><span class="lnum">  23:  </span>    T *l = <span class="kwrd">new</span> T[n];</pre><pre><span class="lnum">  24:  </span>    T *u = <span class="kwrd">new</span> T[n];</pre><pre class="alt"><span class="lnum">  25:  </span>    T *y = <span class="kwrd">new</span> T[n];</pre><pre><span class="lnum">  26:  </span>    </pre><pre class="alt"><span class="lnum">  27:  </span>    assert(l != NULL);</pre><pre><span class="lnum">  28:  </span>    assert(u != NULL);</pre><pre class="alt"><span class="lnum">  29:  </span>    assert(y != NULL);</pre><pre><span class="lnum">  30:  </span>    </pre><pre class="alt"><span class="lnum">  31:  </span>    l[0] = b[0]; </pre><pre><span class="lnum">  32:  </span>    <span class="kwrd">if</span> (l[0] == 0)</pre><pre class="alt"><span class="lnum">  33:  </span>    {</pre><pre><span class="lnum">  34:  </span>        <span class="kwrd">return</span>;</pre><pre class="alt"><span class="lnum">  35:  </span>    }</pre><pre><span class="lnum">  36:  </span>    y[0] = f[0] / l[0];</pre><pre class="alt"><span class="lnum">  37:  </span>    </pre><pre><span class="lnum">  38:  </span>    size_t i;</pre><pre class="alt"><span class="lnum">  39:  </span>    </pre><pre><span class="lnum">  40:  </span>    <span class="rem">//依次求出l[0]-&gt;u[0]-&gt;l[1]-&gt;u[1]-&gt;...-&gt;l[n-1],y[i]</span></pre><pre class="alt"><span class="lnum">  41:  </span>    <span class="kwrd">for</span> (i = 1; i &lt; n; i++)</pre><pre><span class="lnum">  42:  </span>    {</pre><pre class="alt"><span class="lnum">  43:  </span>        <span class="kwrd">if</span> (l[i] == 0)</pre><pre><span class="lnum">  44:  </span>        {</pre><pre class="alt"><span class="lnum">  45:  </span>            <span class="kwrd">return</span>;</pre><pre><span class="lnum">  46:  </span>        }</pre><pre class="alt"><span class="lnum">  47:  </span>        </pre><pre><span class="lnum">  48:  </span>        u[i - 1] = c[i - 1] / l[i - 1];</pre><pre class="alt"><span class="lnum">  49:  </span>        l[i] = b[i] - a[i - 1] * u[i - 1];</pre><pre><span class="lnum">  50:  </span>        y[i] = (f[i] - a[i - 1] * y[i - 1]) / l[i];</pre><pre class="alt"><span class="lnum">  51:  </span>    }</pre><pre><span class="lnum">  52:  </span>    </pre><pre class="alt"><span class="lnum">  53:  </span>    <span class="rem">//逆序求x[i]</span></pre><pre><span class="lnum">  54:  </span>    x[i-1] = y[i-1];</pre><pre class="alt"><span class="lnum">  55:  </span>    <span class="kwrd">for</span> (<span class="kwrd">int</span> k = i - 2; k &gt;= 0; k--)</pre><pre><span class="lnum">  56:  </span>    {</pre><pre class="alt"><span class="lnum">  57:  </span>        x[k] = y[k] - u[k] * x[k + 1];</pre><pre><span class="lnum">  58:  </span>    }</pre><pre class="alt"><span class="lnum">  59:  </span>    </pre><pre><span class="lnum">  60:  </span>    <span class="kwrd">if</span> (l != NULL)</pre><pre class="alt"><span class="lnum">  61:  </span>    {</pre><pre><span class="lnum">  62:  </span>        delete [] l;</pre><pre class="alt"><span class="lnum">  63:  </span>        l = NULL;</pre><pre><span class="lnum">  64:  </span>    }</pre><pre class="alt"><span class="lnum">  65:  </span>    </pre><pre><span class="lnum">  66:  </span>    <span class="kwrd">if</span> (u != NULL)</pre><pre class="alt"><span class="lnum">  67:  </span>    {</pre><pre><span class="lnum">  68:  </span>        delete [] u;</pre><pre class="alt"><span class="lnum">  69:  </span>        u = NULL;</pre><pre><span class="lnum">  70:  </span>    }</pre><pre class="alt"><span class="lnum">  71:  </span>    </pre><pre><span class="lnum">  72:  </span>    <span class="kwrd">if</span> (y != NULL)</pre><pre class="alt"><span class="lnum">  73:  </span>    {</pre><pre><span class="lnum">  74:  </span>        delete [] y;</pre><pre class="alt"><span class="lnum">  75:  </span>        y = NULL;</pre><pre><span class="lnum">  76:  </span>    }</pre><pre class="alt"><span class="lnum">  77:  </span>}</pre><pre><span class="lnum">  78:  </span>&nbsp;</pre><pre class="alt"><span class="lnum">  79:  </span>&nbsp;</pre><pre><span class="lnum">  80:  </span><span class="preproc">#endif</span></pre></div>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p></p>
<p>测试程序：</p>
<div class="csharpcode">
<div class="csharpcode"><pre class="alt"><span class="lnum">   1:  </span>#include <span class="str">"ChaseMethord.h"</span></pre><pre><span class="lnum">   2:  </span>#include &lt;iostream&gt;</pre><pre class="alt"><span class="lnum">   3:  </span><span class="kwrd">using</span> <span class="kwrd">namespace</span> std;</pre><pre><span class="lnum">   4:  </span>&nbsp;</pre><pre class="alt"><span class="lnum">   5:  </span><span class="kwrd">int</span> main()</pre><pre><span class="lnum">   6:  </span>{</pre><pre class="alt"><span class="lnum">   7:  </span>    <span class="kwrd">float</span> a[]  = {1,1,2};</pre><pre><span class="lnum">   8:  </span>    <span class="kwrd">float</span> b[]  = {2,3,1,1};</pre><pre class="alt"><span class="lnum">   9:  </span>    <span class="kwrd">float</span> c[]  = {1,1,1};</pre><pre><span class="lnum">  10:  </span>    <span class="kwrd">float</span> f[]  = {1,2,2,0};</pre><pre class="alt"><span class="lnum">  11:  </span>    </pre><pre><span class="lnum">  12:  </span>    <span class="kwrd">float</span> *x = <span class="kwrd">new</span> <span class="kwrd">float</span>[4];</pre><pre class="alt"><span class="lnum">  13:  </span>    </pre><pre><span class="lnum">  14:  </span>    ChaseMethord(4, a, b, c, x,f);</pre><pre class="alt"><span class="lnum">  15:  </span>    </pre><pre><span class="lnum">  16:  </span>    <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; 4; i ++)</pre><pre class="alt"><span class="lnum">  17:  </span>    {</pre><pre><span class="lnum">  18:  </span>        cout &lt;&lt; x[i] &lt;&lt; endl;</pre><pre class="alt"><span class="lnum">  19:  </span>    }</pre><pre><span class="lnum">  20:  </span>    </pre><pre class="alt"><span class="lnum">  21:  </span>    delete [] x;    </pre><pre><span class="lnum">  22:  </span>  </pre><pre class="alt"><span class="lnum">  23:  </span>    <span class="kwrd">return</span> 0;</pre><pre><span class="lnum">  24:  </span>}</pre></div>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
</div><img src ="http://www.cppblog.com/blindcoder/aggbug/110348.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/blindcoder/" target="_blank">The cpper</a> 2010-03-23 14:01 <a href="http://www.cppblog.com/blindcoder/archive/2010/03/23/110348.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>TCP/IP Winsock编程要点</title><link>http://www.cppblog.com/blindcoder/archive/2010/03/10/109330.html</link><dc:creator>The cpper</dc:creator><author>The cpper</author><pubDate>Wed, 10 Mar 2010 01:28:00 GMT</pubDate><guid>http://www.cppblog.com/blindcoder/archive/2010/03/10/109330.html</guid><wfw:comment>http://www.cppblog.com/blindcoder/comments/109330.html</wfw:comment><comments>http://www.cppblog.com/blindcoder/archive/2010/03/10/109330.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/blindcoder/comments/commentRss/109330.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/blindcoder/services/trackbacks/109330.html</trackback:ping><description><![CDATA[<p>利用Winsock编程由同步和异步方式，同步方式逻辑清晰，编程专注于应用，在抢先式的多任务操作系统中(WinNt、Win2K)采用多线程方式效率基本达到异步方式的水平，应此以下为同步方式编程要点。&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 1、快速通信&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; Winsock的Nagle算法将降低小数据报的发送速度，而系统默认是使用Nagle算法,使用&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; int&nbsp;&nbsp; setsockopt(&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SOCKET&nbsp;&nbsp; s,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; level,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; optname,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const&nbsp;&nbsp; char&nbsp;&nbsp; FAR&nbsp;&nbsp; *optval,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; optlen&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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>&nbsp; );函数关闭它&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 例子：&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; SOCKET&nbsp;&nbsp; sConnect;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; sConnect=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; int&nbsp;&nbsp; bNodelay&nbsp;&nbsp; =&nbsp;&nbsp; 1;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; int&nbsp;&nbsp; err;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; err&nbsp;&nbsp; =&nbsp;&nbsp; setsockopt(&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sConnect,&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IPPROTO_TCP,&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP_NODELAY,&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (char&nbsp;&nbsp; *)&amp;bNodelay,&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sizoeof(bNodelay));//不采用延时算法&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; if&nbsp;&nbsp; (err&nbsp;&nbsp; !=&nbsp;&nbsp; NO_ERROR)&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; TRACE&nbsp;&nbsp; ("setsockopt&nbsp;&nbsp; failed&nbsp;&nbsp; for&nbsp;&nbsp; some&nbsp;&nbsp; reason\n");;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 2、SOCKET的SegMentSize和收发缓冲&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; TCPSegMentSize是发送接受时单个数据报的最大长度，系统默认为1460，收发缓冲大小为8192。&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 在SOCK_STREAM方式下，如果单次发送数据超过1460，系统将分成多个数据报传送，在对方接受到的将是一个数据流，应用程序需要增加断帧的判断。当然可以采用修改注册表的方式改变1460的大小，但MicrcoSoft认为1460是最佳效率的参数，不建议修改。&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 在工控系统中，建议关闭Nagle算法，每次发送数据小于1460个字节（推荐1400），这样每次发送的是一个完整的数据报，减少对方对数据流的断帧处理。&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 3、同步方式中减少断网时connect函数的阻塞时间&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 同步方式中的断网时connect的阻塞时间为20秒左右，可采用gethostbyaddr事先判断到服务主机的路径是否是通的，或者先ping一下对方主机的IP地址。&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; A、采用gethostbyaddr阻塞时间不管成功与否为4秒左右。&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 例子：&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; LONG&nbsp;&nbsp; lPort=3024;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; struct&nbsp;&nbsp; sockaddr_in&nbsp;&nbsp; ServerHostAddr;//服务主机地址&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; ServerHostAddr.sin_family=AF_INET;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; ServerHostAddr.sin_port=::htons(u_short(lPort));&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; ServerHostAddr.sin_addr.s_addr=::inet_addr("192.168.1.3");&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; HOSTENT*&nbsp;&nbsp; pResult=gethostbyaddr((const&nbsp;&nbsp; char&nbsp;&nbsp; *)&nbsp;&nbsp; &amp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; (ServerHostAddr.sin_addr.s_addr),4,AF_INET);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; if(NULL==pResult)&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; int&nbsp;&nbsp; nErrorCode=WSAGetLastError();&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; TRACE("gethostbyaddr&nbsp;&nbsp; errorcode=%d",nErrorCode);&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; else&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; TRACE("gethostbyaddr&nbsp;&nbsp; %s\n",pResult-&gt;h_name);;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; B、采用PING方式时间约2秒左右&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 暂略&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 4、同步方式中解决recv，send阻塞问题&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 采用select函数解决，在收发前先检查读写可用状态。&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; A、读&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 例子：&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; TIMEVAL&nbsp;&nbsp; tv01&nbsp;&nbsp; =&nbsp;&nbsp; {0,&nbsp;&nbsp; 1};//1ms钟延迟,实际为0-10毫秒&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; int&nbsp;&nbsp; nSelectRet;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; int&nbsp;&nbsp; nErrorCode;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; FD_SET&nbsp;&nbsp; fdr&nbsp;&nbsp; =&nbsp;&nbsp; {1,&nbsp;&nbsp; sConnect};&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; nSelectRet=::select(0,&nbsp;&nbsp; &amp;fdr,&nbsp;&nbsp; NULL,&nbsp;&nbsp; NULL,&nbsp;&nbsp; &amp;tv01);//检查可读状态&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; if(SOCKET_ERROR==nSelectRet)&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; nErrorCode=WSAGetLastError();&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; TRACE("select&nbsp;&nbsp; read&nbsp;&nbsp; status&nbsp;&nbsp; errorcode=%d",nErrorCode);&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; ::closesocket(sConnect);&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; goto&nbsp;&nbsp; 重新连接（客户方），或服务线程退出（服务方）;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; if(nSelectRet==0)//超时发生，无可读数据&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 继续查读状态或向对方主动发送&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; else&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 读数据&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; B、写&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; TIMEVAL&nbsp;&nbsp; tv01&nbsp;&nbsp; =&nbsp;&nbsp; {0,&nbsp;&nbsp; 1};//1ms钟延迟,实际为9-10毫秒&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; int&nbsp;&nbsp; nSelectRet;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; int&nbsp;&nbsp; nErrorCode;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; FD_SET&nbsp;&nbsp; fdw&nbsp;&nbsp; =&nbsp;&nbsp; {1,&nbsp;&nbsp; sConnect};&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; nSelectRet=::select(0,&nbsp;&nbsp;&nbsp;&nbsp; NULL,&nbsp;&nbsp; NULL,&amp;fdw,&nbsp;&nbsp; &amp;tv01);//检查可写状态&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; if(SOCKET_ERROR==nSelectRet)&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; nErrorCode=WSAGetLastError();&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; TRACE("select&nbsp;&nbsp; write&nbsp;&nbsp; status&nbsp;&nbsp; errorcode=%d",nErrorCode);&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; ::closesocket(sConnect);&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; //goto&nbsp;&nbsp; 重新连接（客户方），或服务线程退出（服务方）;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; if(nSelectRet==0)//超时发生，缓冲满或网络忙&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; //继续查写状态或查读状态&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; else&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; //发送&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 5、改变TCP收发缓冲区大小&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 系统默认为8192，利用如下方式可改变。&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; SOCKET&nbsp;&nbsp; sConnect;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; sConnect=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; int&nbsp;&nbsp; nrcvbuf=1024*20;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; int&nbsp;&nbsp; err=setsockopt(&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; sConnect,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; SOL_SOCKET,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; SO_SNDBUF,//写缓冲，读缓冲为SO_RCVBUF&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; (char&nbsp;&nbsp; *)&amp;nrcvbuf,&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; sizeof(nrcvbuf));&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; if&nbsp;&nbsp; (err&nbsp;&nbsp; !=&nbsp;&nbsp; NO_ERROR)&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; TRACE("setsockopt&nbsp;&nbsp; Error!\n");&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 在设置缓冲时，检查是否真正设置成功用&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; int&nbsp;&nbsp; getsockopt(&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; SOCKET&nbsp;&nbsp; s,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; int&nbsp;&nbsp; level,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; int&nbsp;&nbsp; optname,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; char&nbsp;&nbsp; FAR&nbsp;&nbsp; *optval,&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; int&nbsp;&nbsp; FAR&nbsp;&nbsp; *optlen&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; );&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 6、服务方同一端口多IP地址的bind和listen&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 在可靠性要求高的应用中，要求使用双网和多网络通道，再服务方很容易实现，用如下方式可建立客户对本机所有IP地址在端口3024下的请求服务。&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; SOCKET&nbsp;&nbsp; hServerSocket_DS=INVALID_SOCKET;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; struct&nbsp;&nbsp; sockaddr_in&nbsp;&nbsp; HostAddr_DS;//服务器主机地址&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; LONG&nbsp;&nbsp; lPort=3024;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; HostAddr_DS.sin_family=AF_INET;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; HostAddr_DS.sin_port=::htons(u_short(lPort));&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; HostAddr_DS.sin_addr.s_addr=htonl(INADDR_ANY);&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; hServerSocket_DS=::socket(&nbsp;&nbsp; AF_INET,&nbsp;&nbsp; SOCK_STREAM,IPPROTO_TCP);&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; if(hServerSocket_DS==INVALID_SOCKET)&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; AfxMessageBox("建立数据服务器SOCKET&nbsp;&nbsp; 失败!");&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; return&nbsp;&nbsp; FALSE;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; if(SOCKET_ERROR==::bind(hServerSocket_DS,(struct&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; sockaddr&nbsp;&nbsp; *)(&amp;(HostAddr_DS)),sizeof(SOCKADDR)))&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp; nErrorCode=WSAGetLastError&nbsp;&nbsp; ();&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; TRACE("bind&nbsp;&nbsp; error=%d\n",nErrorCode);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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>&nbsp; AfxMessageBox("Socket&nbsp;&nbsp; Bind&nbsp;&nbsp; 错误!");&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; return&nbsp;&nbsp; FALSE;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; if(SOCKET_ERROR==::listen(hServerSocket_DS,10))//10个客户&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; AfxMessageBox("Socket&nbsp;&nbsp; listen&nbsp;&nbsp; 错误!");&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; return&nbsp;&nbsp; FALSE;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; AfxBeginThread(ServerThreadProc,NULL,THREAD_PRIORITY_NORMAL);&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 在客户方要复杂一些，连接断后，重联不成功则应换下一个IP地址连接。也可采用同时连接好后备用的方式。&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 7、用TCP/IP&nbsp;&nbsp; Winsock实现变种Client/Server&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 传统的Client/Server为客户问、服务答，收发是成对出现的。而变种的Client/Server是指在连接时有客户和服务之分，建立好通信连接后，不再有严格的客户和服务之分，任何方都可主动发送，需要或不需要回答看应用而言，这种方式在工控行业很有用，比如RTDB作为I/O&nbsp;&nbsp; Server的客户，但I/O&nbsp;&nbsp; Server也可主动向RTDB发送开关状态变位、随即事件等信息。在很大程度上减少了网络通信负荷、提高了效率。&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; 采用1-6的TCP/IP编程要点，在Client和Server方均已接收优先，适当控制时序就能实现</p><img src ="http://www.cppblog.com/blindcoder/aggbug/109330.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/blindcoder/" target="_blank">The cpper</a> 2010-03-10 09:28 <a href="http://www.cppblog.com/blindcoder/archive/2010/03/10/109330.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用对话框创建CDialogBar派生的类</title><link>http://www.cppblog.com/blindcoder/archive/2009/12/17/103411.html</link><dc:creator>The cpper</dc:creator><author>The cpper</author><pubDate>Thu, 17 Dec 2009 09:04:00 GMT</pubDate><guid>http://www.cppblog.com/blindcoder/archive/2009/12/17/103411.html</guid><wfw:comment>http://www.cppblog.com/blindcoder/comments/103411.html</wfw:comment><comments>http://www.cppblog.com/blindcoder/archive/2009/12/17/103411.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/blindcoder/comments/commentRss/103411.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/blindcoder/services/trackbacks/103411.html</trackback:ping><description><![CDATA[<p>原文地址：<a href="http://hi.baidu.com/flying5/blog/item/bc09842d007c2331349bf7c9.html">http://hi.baidu.com/flying5/blog/item/bc09842d007c2331349bf7c9.html</a> <p>参考微软技术文档：<a href="http://support.microsoft.com/default.aspx?scid=kb;EN-US;q185672">http://support.microsoft.com/default.aspx?scid=kb;EN-US;q185672</a> <p>摘要：本文详细解说了CDialogBar的具体使用过程，可以做为VC++和MFC新手学习总结用。 <p>一、创建DialogBar的派生类 <p>首先，创建对话框资源：在对话框资源编辑器内生成一个Dialog资源，并将其风格（Style）属性必须设置为Child，不能设置为Overlapped或Popup，否则运行肯定出错；至于边界属性则随用户自己喜欢，一般都是选择None。其余属性也随用户选择，一般没有特殊要求还是选择默认的好。 <p>其次，创建基于CDialog的派生类：打开ClassWizard，为以上创建的资源添加一个以CDialog为基类的派生类（因为ClassWizard没有将CDialogBar列在基类目录清单中，所以用户只能先以CDialog类派生）。 <p>再次，修改派生类以CDialogBar为基类：通常需要手工修改几处代码，在本例中派生类以CDataStatus命名。（注：以后讲解中凡是手工改动都是以红色显示） <p>1、 在头文件中修改继承关系 <p>将class CDataStatus : public CDialog 改为 class CDataStatus : public CDialogBar <p>2、 在代码文件中修该构造函数继承关系 <p>将CDataStatus::CDataStatus(CWnd* pParent /*=NULL*/) <p>: CDialog(CDataStatus::IDD, pParent) <p>{ <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //{{AFX_DATA_INIT(CDataStatus) <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // NOTE: the ClassWizard will add member initialization here <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //}}AFX_DATA_INIT <p>} <p>改为 <p>CDataStatus::CDataStatus(CWnd* pParent /*=NULL*/) <p>{ <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //{{AFX_DATA_INIT(CDataStatus) <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // NOTE: the ClassWizard will add member initialization here <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //}}AFX_DATA_INIT <p>} <p>3、 将DDX绑定函数中的继承关系去掉 <p>即将void CDataStatus::DoDataExchange(CDataExchange* pDX) <p>{ <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CDialog::DoDataExchange(pDX); <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //{{AFX_DATA_MAP(CCurrentCheckDlg) <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ……….. <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //}}AFX_DATA_MAP <p>} <p>改为 <p>void CDataStatus::DoDataExchange(CDataExchange* pDX) <p>{ <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //{{AFX_DATA_MAP(CCurrentCheckDlg) <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; …………. <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //}}AFX_DATA_MAP <p>} <p>4、 重新初始化函数（这个相当重要，如果不这么做的话，DDX函数形同虚设，当然用户的工具条如果没有用到DDX的话当然可以不加这段代码）： <p>首先在ClassWizard的MessageMap中对消息该CDataStatus类的WM_INITDIALOG消息添加处理函数默认名为OnInitDialog。 <p>其次手工修改代码如下： <p>1、 添加消息映射函数。由于对话框形式的初始化函数消息并未加载到消息映射内，为此我们需要手工添加，要不然代码无法拦截该工具条的初始化消息，形式如下： <p>将BEGIN_MESSAGE_MAP(CDataStatus, CDialogBar) <p>&nbsp;&nbsp; //{{AFX_MSG_MAP(CDataStatus) <p>&nbsp;&nbsp; ....... <p>&nbsp;&nbsp; //}}AFX_MSG_MAP <p>END_MESSAGE_MAP() <p>改为： <p>BEGIN_MESSAGE_MAP(CDataStatus, CDialogBar) <p>&nbsp;&nbsp; //{{AFX_MSG_MAP(CDataStatus) <p>&nbsp;&nbsp; ....... <p>&nbsp;&nbsp; ON_MESSAGE(WM_INITDIALOG,OnInitDialog) <p>&nbsp;&nbsp; //}}AFX_MSG_MAP <p>END_MESSAGE_MAP() <p>2、 修改OnInitDialog函数，此函数并未传递参数，但是在这里我们需要让它传递参数，代码如下修改（当然头文件中，对声明也要做修改，在这里就不作赘述了） <p>将BOOL CDataStatus::OnInitDialog() <p>{ <p>&nbsp;&nbsp; CDialogBar::OnInitDialog(); <p>&nbsp;&nbsp; // TODO: Add extra initialization here <p>&nbsp;&nbsp; return TRUE; // return TRUE unless you set the focus to a control <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // EXCEPTION: OCX Property Pages should return FALSE <p>} <p>改为： <p>BOOL CDataStatus::OnInitDialog(UINT wParam,LONG lParam) <p>{ <p>&nbsp;&nbsp; //CDialogBar::OnInitDialog(); <p>&nbsp;&nbsp; // TODO: Add extra initialization here <p>&nbsp;&nbsp; BOOL bRet = HandleInitDialog(wParam,lParam); <p>&nbsp;&nbsp; if (!UpdateData(FALSE)) <p>&nbsp;&nbsp; { <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TRACE("InitCDataStatus Failed！"); <p>&nbsp;&nbsp; } <p>&nbsp;&nbsp; return TRUE; // return TRUE unless you set the focus to a control <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // EXCEPTION: OCX Property Pages should return FALSE <p>} <p>二、在框架类中实现该派生类的对象化 <p>首先，在框架类的头文件内声明实例对象，本例实例化：CDataStatus&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_wndDataStatus;当然头文件中不可避免要包含新派生类的头文件。 <p>其次，在框架类的OnCreate函数内创建对象并将对象绑定对话框资源。形式与创建ToolBar原理一样，本例实例如下： <p>if (!m_wndDataStatus.Create(this,IDD_DATASTATUS,WS_VISIBLE|WS_CHILD <p>|CBRS_SIZE_DYNAMIC|CBRS_BOTTOM,IDD_DATASTATUS)) <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TRACE0("Failed to create CDataStatus bar!"); <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1; <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <p>再次，最为关键的一点就是重写框架类的OnCmdMsg虚函数。如果不重写该函数，那么不光DDX功能无法实现，连最基本的OnCommand事件都无法实现。而且还得手工添加代码，形式如下： <p>BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, <p>AFX_CMDHANDLERINFO* pHandlerInfo) <p>{ <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // TODO: Add your specialized code here and/or call the base class <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); <p>} <p>改为： <p>BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* <p>pHandlerInfo) <p>{ <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // TODO: Add your specialized code here and/or call the base class <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (m_wndDataStatus.OnCmdMsg(nID,nCode,pExtra,pHandlerInfo)) <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp;&nbsp;&nbsp; TRUE; <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); <p>} <p>三、在CReBar上添加该实例化对象 <p>其实这一步倒是相当简单，只是自己以前没用过这个类，所以在这里也顺便用了一下。 <p>首先，在框架类的头文件中用CRebar声明一个对象，如CReBar&nbsp;&nbsp; m_wndReBar; <p>其次，在框架类的代码文件中的OnCreat函数体内，生成对象，代码如下： <p>if (!m_wndReBar.Create(this,RBS_BANDBORDERS,WS_CHILD | <p>WS_VISIBLE| CBRS_BOTTOM|WS_CLIPSIBLINGS|WS_CLIPCHILDREN)) <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TRACE0("Failed to create Rebar \n"); <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1; <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <p>再次，就是将所要添加的toolbar以及新生成的CDataStatus对象m_wndDataStatus加进Rebar的对象 <p>m_wndReBar中，代码如下： <p>m_wndReBar.AddBar(&amp;m_wndDataStatus,NULL,NULL, <p>RBBS_GRIPPERALWAYS|RBBS_FIXEDBMP); <p>CSDN上的一篇文章《利用CDialogBar来实现类似工具栏的浮动条 》 <p><a href="http://blog.csdn.net/houen_study/archive/2004/11/05/168229.aspx">http://blog.csdn.net/houen_study/archive/2004/11/05/168229.aspx</a> <p>如果你想实现有工具条的浮动和定位功能，而且可以方便的摆放任何控件上去，请继续看这篇文章吧！ <p>那就使用CDialogBar就可以拥有和CDialog一样的方便和快捷。 <p>&nbsp;&nbsp;&nbsp;&nbsp; 步骤1：添加一个CDialogBar派生类 <p>&nbsp;&nbsp;&nbsp;&nbsp; 在资源中添加一个对话框，再采用类向导来添加类，找不到CDialogBar作为基类吧，可以先用CDialog作为基类产生一个，然后把所以的“CDialog”替换为“CDialogBar”，替换完成了。编译一下，^_^有错误吧！！请看步骤2。 <p>&nbsp;&nbsp;&nbsp;&nbsp; 步骤2：解决编译错误并完善该类 <p>&nbsp;&nbsp;&nbsp;&nbsp; 其实错误就是构着函数调用基类时有问题，: CDialogBar(/*CDlgBar::IDD, pParent*/)象这样注释掉就可以了，添加一个类似OnInitDialog的函数，在CDialogBar中是不存在OnInitDialog的消息的,至少我还不知道,因为初始化是在创建后调用的所以我们就重写virtual BOOL Create(CWnd* pParentWnd,UINT nIDTemplate,UINT nStyle,UINT nID);这个函数。注意哦用向导添加的Create函数的参数是不对的喔,看上面。下面是实现代码（很简单的） <p>BOOL CDlgXXX::Create(CWnd* pParentWnd,UINT nIDTemplate,UINT nStyle,UINT nID)  <p>{ <p>// TODO: Add your specialized code here and/or call the base class <p>BOOL bRes= CDialogBar::Create(pParentWnd,nIDTemplate,nStyle,nID ); <p>InitDialogBar();//在类中添加一个成员函数就可以了 <p>return bRes; <p>} <p>BOOL CDlgXXX::InitDialogBar() <p>{ <p>UpdateData(FALSE);//这个一定要啊，这样就会有和CDialog一样的数据交换效果了 <p>return TRUE; <p>} <p>&nbsp;&nbsp;&nbsp;&nbsp; 步骤3：创建和使用 <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!m_barAttrib.Create(this,IDD_DLG_COM_ATTRIB, CBRS_RIGHT|CBRS_GRIPPER, XXX)) <p>{ <p>&nbsp;&nbsp; TRACE0("Failed to create dialogbar\n"); <p>&nbsp;&nbsp; return -1; <p>} <p>m_barAttrib.SetWindowText("部件属性"); <p>XXX是一个资源id手工直接在资源的.h文件中添加一条，不会，这里就不教了<img border="0" src="http://blog.csdn.net/Emoticons/hitwall.gif">。 <p>工具条的显示和隐藏代码如下，自己慢慢理解吧： <p>ShowControlBar(&amp;m_barAttrib, (m_barAttrib.GetStyle() &amp; WS_VISIBLE) == 0, FALSE); <p>&nbsp;&nbsp;&nbsp;&nbsp; 上面代码实现后DoDataExchange也是可以用，给控件添加控件就和CDialog一样的方便咯 <p>但是还有一个要注意的是就是控件类对象的添加，我试了一下好像不行，窗口句柄好像 <p>总是0的，不能使用。还是使用GetDlgItem(IDC_DRIVER_LIST)来取得控件指针吧。 <p>&nbsp;&nbsp;&nbsp; 其他方面的心得 <p>&nbsp;&nbsp;&nbsp;&nbsp; 利用DoDataExchange来控制自定义的输入格式控制这里就举一个文本框的例子 <p>给文本控件添加完变量后就在DoDataExchange会出现如下代码 <p>DDX_Text(pDX, IDC_COM_VAR, m_strVar);//系统产生的 <p>DDV_MaxChars(pDX, m_strVar,VAR_MAX_LEN);//加入长度控制后产生的 <p>DDV_FileNameString(pDX, m_strVar);//自定义的手工添加的实现见下面 <p>void CXXX::DDV_FileNameString(CDataExchange *pDX, CString m_strFileName) <p>{ <p>CString strError=_T("<a>\\/:*?\</a>"&lt;&gt;|"); <p>if(m_strFileName.SpanExcluding(strError) != m_strFileName) <p>{ <p>&nbsp;&nbsp; ::AfxMessageBox(_T("文件名中不能包含"+strError+"字符")); <p>&nbsp;&nbsp; pDX-&gt;Fail();//关键是这句执行这句后就会抛出异常下面的语句就不执行了 <p>} <p>} <p>还有几个注意点是 <p>1.只有执行了UpdateData()才会调用DoDataExchange函数若中途 执行了pDX-&gt;Fail(); UpdateData()就返回FALSE。 <p>2. DDX_Text(pDX, IDC_COM_VAR, m_strVar);//系统产生的 <p>DDV_MaxChars(pDX, m_strVar,VAR_MAX_LEN);//加入长度控制后产生的 <p>DDV_FileNameString(pDX, m_strVar);//自定义的手工添加的实现见下面 <p>如上面几句都是对一个控件的内容的控制，他们必须放在一块，且DDX_Text要放在第一句，这样在界面上就可以正确的指出那个控件的内容有问题，控件会被设置焦点并选中全部内容。 <p>好了先写这么多了 <img src ="http://www.cppblog.com/blindcoder/aggbug/103411.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/blindcoder/" target="_blank">The cpper</a> 2009-12-17 17:04 <a href="http://www.cppblog.com/blindcoder/archive/2009/12/17/103411.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>GDI+无闪烁绘图</title><link>http://www.cppblog.com/blindcoder/archive/2009/12/01/102320.html</link><dc:creator>The cpper</dc:creator><author>The cpper</author><pubDate>Tue, 01 Dec 2009 04:19:00 GMT</pubDate><guid>http://www.cppblog.com/blindcoder/archive/2009/12/01/102320.html</guid><wfw:comment>http://www.cppblog.com/blindcoder/comments/102320.html</wfw:comment><comments>http://www.cppblog.com/blindcoder/archive/2009/12/01/102320.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/blindcoder/comments/commentRss/102320.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/blindcoder/services/trackbacks/102320.html</trackback:ping><description><![CDATA[<p></p><pre class="csharpcode"><span class="kwrd">GDI+无闪烁绘图的原理就是不直接在OnDraw函数下绘图，而是先创建个Bitmap对象，然后用刚才的Bitmap对象创建一个Graphics的内存图像，然后所有的绘图操作都在</span></pre><pre class="csharpcode"><span class="kwrd">内存图像中进行，最后用DrawImage方法把内存图像显示到屏幕。</span></pre><pre class="csharpcode"><span class="kwrd">void</span> CDataView::OnDraw(CDC* pDC)
{
    CDocument* pDoc = GetDocument();
    <span class="rem">// TODO: 在此添加绘制代码</span>
    pDC-&gt;TextOut(100,100,L<span class="str">"数据视图"</span>);

    Graphics g(pDC-&gt;m_hDC); 

    CRect rcClient; 
    GetClientRect(&amp;rcClient); 
    Bitmap bmp(rcClient.Width(), rcClient.Height()); 
    Graphics * buffergraphics = Graphics::FromImage(&amp;bmp);<span class="rem">//关键部分，创建一个内存图像</span>
    SolidBrush brush(Color(255, 0,0, 255)); 
    buffergraphics -&gt;FillRectangle(&amp;brush,0, 0, rcClient.Width(),rcClient.Height()); <span class="rem">//在内存图像中画图</span>

    g.DrawImage(&amp;bmp,0, 0, rcClient.Width(), rcClient.Height());<span class="rem">//将内存图像显示到屏幕</span>
    delete buffergraphics ; 
    g.ReleaseHDC(pDC-&gt;m_hDC);

}</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style><img src ="http://www.cppblog.com/blindcoder/aggbug/102320.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/blindcoder/" target="_blank">The cpper</a> 2009-12-01 12:19 <a href="http://www.cppblog.com/blindcoder/archive/2009/12/01/102320.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mfc下建立带有文字说明的32位真色彩工具栏</title><link>http://www.cppblog.com/blindcoder/archive/2009/11/24/101808.html</link><dc:creator>The cpper</dc:creator><author>The cpper</author><pubDate>Tue, 24 Nov 2009 06:07:00 GMT</pubDate><guid>http://www.cppblog.com/blindcoder/archive/2009/11/24/101808.html</guid><wfw:comment>http://www.cppblog.com/blindcoder/comments/101808.html</wfw:comment><comments>http://www.cppblog.com/blindcoder/archive/2009/11/24/101808.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/blindcoder/comments/commentRss/101808.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/blindcoder/services/trackbacks/101808.html</trackback:ping><description><![CDATA[<p>首先在CMainFrame类下添加公用变量:</p> <blockquote> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CToolBar&nbsp;&nbsp;&nbsp;&nbsp; m_ToolBar;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //工具栏<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CImageList&nbsp; m_ImgList;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //工具栏上的图片</p></blockquote> <p>然后在该类下添加对工具栏上的操作：  <blockquote> <p>&nbsp;&nbsp;&nbsp; BOOL LoadImageList();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //装载图片<br>&nbsp;&nbsp;&nbsp; BOOL SetStyleToolbar();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //设置工具栏的样式</p></blockquote> <p>LoadImageList函数的实现：  <p>&nbsp;<pre class="csharpcode">BOOL CMainFrame::LoadImageList()
{
    <span class="kwrd">int</span>            i                    = 0;
    TCHAR        strPath[MAX_PATH]    = { 0 };
    TCHAR        strFull[MAX_PATH]    = { 0 };
    HBITMAP        hBitmap                = NULL;
    

    <span class="kwrd">while</span>(m_ImgList.Remove(0));   <span class="rem">//移除列表中所有元素</span>

    <span class="rem">//取得图片完整路径</span>
    GetCurrentDirectory(MAX_PATH, strPath);
    StrCat(strPath, _T("\\res\\"));
    
    <span class="kwrd">for</span>(i=0; i&lt; m_iPicCount; ++i)
    {

        StrCpy(strFull, strPath);
        StrCat(strFull, (LPCWSTR)m_pLoadPicInfo[i].fileName.c_str());
       

        hBitmap = (HBITMAP)LoadImage(AfxGetResourceHandle(), strFull, IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR|LR_LOADFROMFILE);
        CBitmap        bmp;
        bmp.Attach(hBitmap);
        m_ImgList.Add(&amp;bmp, RGB(0, 0, 0));
        bmp.DeleteObject();
    }
   
    <span class="kwrd">return</span> TRUE;
}</pre><pre class="csharpcode">SetStyleToolbar()函数的实现：</pre><pre class="csharpcode">BOOL CMainFrame::SetStyleToolbar()
{

    CToolBarCtrl&amp;    tbc    = m_ToolBar.GetToolBarCtrl();
    <span class="kwrd">while</span>(tbc.DeleteButton(0));
    tbc.SetImageList(&amp;m_ImgList);

    <span class="kwrd">int</span>        i            = 0;
    <span class="kwrd">int</span>        iButtons    = <span class="kwrd">sizeof</span>(tb) / <span class="kwrd">sizeof</span>(tb[0]);
    <span class="kwrd">for</span>(i = 0; i &lt; iButtons; ++i)
    {
        tbc.AddButtons(1, &amp;tb[i]);
    }

    <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; m_iPicCount; i++)
    {
        m_ToolBar.SetButtonText(i, (LPCTSTR)m_pLoadPicInfo[i].descript.c_str());
    }

    //</pre><pre class="csharpcode">    CRect temp;
    m_ToolBar.GetItemRect(0,&amp;temp);
    m_ToolBar.GetToolBarCtrl().SetButtonSize(CSize(temp.Width(),
        temp.Height()));
  
    <span class="kwrd">return</span> TRUE;
}</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<pre class="csharpcode">接下来在OnCreate函数下创建工具栏：</pre><pre class="csharpcode">&nbsp;</pre><pre class="csharpcode"><span class="rem">//创建自定义工具栏</span>
    m_ToolBar.CreateEx(<span class="kwrd">this</span>, 
        TBSTYLE_FLAT,
        WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP);

    m_ImgList.Create(32, 32, ILC_COLOR32|ILC_MASK, 0, 0);
    LoadImageList();
    SetStyleToolbar();</pre><pre class="csharpcode">&nbsp;</pre><pre class="csharpcode">创建好之后还得给工具栏上的按钮加上相应事件，要不然按钮会显示成灰色。由于按钮的ID都是自定义的，所以必须用MFC的ON_COMMAND_RANGE事件来响应按钮的消息。</pre><pre class="csharpcode">首先在CMainFrame的头文件处声明消息映射函数afx_msg void OnToolBarButton(UINT nID);这个函数的作用就是通过不同的按钮ID做出不同的响应。然后在CMainFrame</pre><pre class="csharpcode">的实现文件处在消息响应宏BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)和END_MESSAGE_MAP()之间加上消息映射：</pre>
<blockquote><pre class="csharpcode">           ON_COMMAND_RANGE(IDC_ADD, IDC_CAMERA, &amp;CMainFrame::OnToolBarButton)</pre></blockquote><pre class="csharpcode">CMainFrame::OnToolBarButton函数的实现如下：</pre><pre class="csharpcode"><span class="kwrd">void</span> CMainFrame::OnToolBarButton(UINT nID)
{
    <span class="kwrd">if</span> (nID &lt; IDC_ADD || nID &gt; IDC_FLAG)
    {
        <span class="kwrd">return</span>;
    }

    <span class="kwrd">switch</span>(nID)
    {
    <span class="kwrd">case</span> IDC_ADD:
        <span class="kwrd">break</span>;
    <span class="kwrd">default</span>:
        <span class="kwrd">break</span>;
    }
}</pre>
<p>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
</p>
<p><font size="2" face="Consolas">以下是用到的数据结构的定义：</font> 
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
</p>
<p>&nbsp;</p><pre class="csharpcode"><span class="kwrd">struct</span> BmpInfo
{
    wstring  fileName;               <span class="rem">//文件名</span>
    wstring  descript;               <span class="rem">//工具栏图片的说明文字</span>
};

<span class="rem">//为系统管理员显示的ToolBar</span>
<span class="kwrd">static</span> BmpInfo AdminToolBar[13] =
{
    {L<span class="str">"add.bmp"</span>,             L<span class="str">"添加设备"</span>},
    {L<span class="str">"delete.bmp"</span>,          L<span class="str">"删除设备"</span>},
    {L<span class="str">"home.bmp"</span>,            L<span class="str">"主视图"</span>},
    {L<span class="str">"dataview.bmp"</span>,        L<span class="str">"数据视图"</span>},
    {L<span class="str">"relativeView.bmp"</span>,    L<span class="str">"相对产气速率"</span>},
    {L<span class="str">"absView.bmp"</span>,         L<span class="str">"绝对产气速率"</span>},
    {L<span class="str">"analyseView.bmp"</span>,     L<span class="str">"数据分析"</span>},
    {L<span class="str">"print.bmp"</span>,           L<span class="str">"打印"</span>},
    {L<span class="str">"sample.bmp"</span>,          L<span class="str">"采样设置"</span>},
    {L<span class="str">"flag.bmp"</span>,            L<span class="str">"标定设置"</span>},
    {L<span class="str">"zoom in.bmp"</span>,        L<span class="str">"放大"</span>},
    {L<span class="str">"zoom out.bmp"</span>,       L<span class="str">"缩小"</span>},
    {L<span class="str">"camera.bmp"</span>,         L<span class="str">"保存图片"</span>}
};



<span class="rem">//为操作员和设备管理员显示的ToolBar</span>
<span class="kwrd">static</span> BmpInfo OperatorToolBar[8] =
{
    {L<span class="str">"home.bmp"</span>,            L<span class="str">"主视图"</span>},
    {L<span class="str">"dataview.bmp"</span>,        L<span class="str">"数据视图"</span>},
    {L<span class="str">"relativeView.bmp"</span>,    L<span class="str">"相对产气速率"</span>},
    {L<span class="str">"absView.bmp"</span>,         L<span class="str">"绝对产气速率"</span>},
    {L<span class="str">"print.bmp"</span>,           L<span class="str">"打印"</span>},
    {L<span class="str">"zoom in.bmp"</span>,         L<span class="str">"放大"</span>},
    {L<span class="str">"zoom out.bmp"</span>,        L<span class="str">"缩小"</span>},
    {L<span class="str">"camera.bmp"</span>,          L<span class="str">"保存图片"</span>}
};

<span class="rem">//为普通用户显示的ToolBar</span>
<span class="kwrd">static</span> BmpInfo CommanToolBar[7] = 
{
    {L<span class="str">"home.bmp"</span>,            L<span class="str">"主视图"</span>},
    {L<span class="str">"dataview.bmp"</span>,        L<span class="str">"数据视图"</span>},
    {L<span class="str">"relativeView.bmp"</span>,    L<span class="str">"相对产气速率"</span>},
    {L<span class="str">"absView.bmp"</span>,         L<span class="str">"绝对产气速率"</span>},
    {L<span class="str">"zoom in.bmp"</span>,         L<span class="str">"放大"</span>},
    {L<span class="str">"zoom out.bmp"</span>,        L<span class="str">"缩小"</span>},
    {L<span class="str">"camera.bmp"</span>,          L<span class="str">"保存图片"</span>}
};

<font color="#0000ff"></font>
<span class="rem">//定义按钮的ID</span>
<span class="preproc">#define</span> IDC_ADD             4000
<span class="preproc">#define</span> IDC_DELETE          4001
<span class="preproc">#define</span> IDC_HOME            4002
<span class="preproc">#define</span> IDC_DATAVIEW        4003
<span class="preproc">#define</span> IDC_RELATIVEVIEW    4004
<span class="preproc">#define</span> IDC_ABSVIEW         4005
<span class="preproc">#define</span> IDC_ANALYSE         4006
<span class="preproc">#define</span> IDC_PRINT           4007
<span class="preproc">#define</span> IDC_SAMPLE          4008
<span class="preproc">#define</span> IDC_FLAG            4009
<span class="preproc">#define</span> IDC_ZOOMIN          4010
<span class="preproc">#define</span> IDC_ZOOMOUT         4011
<span class="preproc">#define</span> IDC_CAMERA          4012

<span class="kwrd">static</span> TBBUTTON tb[] =
{
    {  0,  IDC_ADD,                TBSTATE_ENABLED , TBSTYLE_BUTTON,    0, 0 },
    {  1,  IDC_DELETE,            TBSTATE_ENABLED , TBSTYLE_BUTTON,    0, 0 },
    {  2,  IDC_HOME,            TBSTATE_ENABLED , TBSTYLE_BUTTON,    0, 0 },
    {  3,  IDC_DATAVIEW,        TBSTATE_ENABLED , TBSTYLE_BUTTON,    0, 0 },
    {  4,  IDC_RELATIVEVIEW,    TBSTATE_ENABLED , TBSTYLE_BUTTON,    0, 0 },
    {  5,  IDC_ABSVIEW,            TBSTATE_ENABLED , TBSTYLE_BUTTON,    0, 0 },
    {  6,  IDC_ANALYSE,            TBSTATE_ENABLED , TBSTYLE_BUTTON,    0, 0 },
    {  7,  IDC_PRINT,            TBSTATE_ENABLED , TBSTYLE_BUTTON,    0, 0 },
    {  8,  IDC_SAMPLE,            TBSTATE_ENABLED , TBSTYLE_BUTTON,    0, 0 },
    {  9,  IDC_FLAG,            TBSTATE_ENABLED , TBSTYLE_BUTTON,    0, 0 },
    {  10, IDC_ZOOMIN,            TBSTATE_ENABLED , TBSTYLE_BUTTON,    0, 0 },
    {  11, IDC_ZOOMOUT,            TBSTATE_ENABLED , TBSTYLE_BUTTON,    0, 0 },
    {  12, IDC_CAMERA,            TBSTATE_ENABLED , TBSTYLE_BUTTON,    0, 0 }
};</pre><pre class="csharpcode">&nbsp;</pre><pre class="csharpcode">编译运行之后，界面的显示效果如下：</pre><pre class="csharpcode"><a href="http://www.cppblog.com/images/cppblog_com/blindcoder/WindowsLiveWriter/mfc32_BEF0/s_2.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="s" border="0" alt="s" src="http://www.cppblog.com/images/cppblog_com/blindcoder/WindowsLiveWriter/mfc32_BEF0/s_thumb.png" width="644" height="441"></a> </pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style><img src ="http://www.cppblog.com/blindcoder/aggbug/101808.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/blindcoder/" target="_blank">The cpper</a> 2009-11-24 14:07 <a href="http://www.cppblog.com/blindcoder/archive/2009/11/24/101808.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>