<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="http://feeds.qzone.qq.com/rss.xsl" version="1.0"?>
<rss version="2.0" xmlns:qz="http://qzone.qq.com">
<channel>
<title><![CDATA[surpercore]]></title>
<description><![CDATA[suncore]]></description>
<link>http://289367588.qzone.qq.com</link>
<lastBuildDate>Sun, 29 Nov 2009 21:15:54 GMT</lastBuildDate>
<generator>Qzone</generator>
<language>zh-cn</language>
<copyright>Copyright (C), 2005-2008, Tencent Tech. Co., Ltd.</copyright>
<pubDate>Mon, 04 May 2009 13:07:53 GMT</pubDate>

<item>
<title><![CDATA[DVR和NVR的区别(转)]]></title>
<link>http://289367588.qzone.qq.com/blog/1241442473</link>
<description><![CDATA[   <br><br>   DVR和NVR都是视频监控产品，nvr是dvr以后才出来的产品，（Network Video Recorder）网络监控产品，业界说nvr是取代dvr的产品，但据目前看来，NVR终结DVR,可能性是零.<br>        DVR即是Digital Video Recorder——数字视频录像机或数字硬盘录像机，我们习惯上称为硬盘录像机。它是一套进行图像存储处理的计算机系统，具有对图像/语音进行长时间录像、录音、远程监视和控制的功能，DVR集合了录像机、画面分割器、云台镜头控制、报警控制、网络传输等五种功能于一身，用一台设备就能取代模拟监控系统一大堆设备的功能，而且在价格上也逐渐占有优势。 <br>        NVR全称为Network Video Recorder，相对于DVR(Digital Video Recorder)而言，其核心优势主要体现在网络化。NVR系统中，中心部署NVR，监控点部署网络摄像机或视频适配器，监控点设备与中心NVR之间通过任意IP网络相连。监控点视频、音频以及告警信号经网络摄像机或视频适配器数字化处理后，以IP码流形式上传到NVR，由NVR进行集中录像存储和管理。<br><br>        DVR系统中，中心部署DVR，监控点部署视频设备(模拟摄像机)、音频设备(拾音器/麦克风)以及报警设备(温感/烟感)等，各个监控点设备与中心DVR分别通过视频、音频、控制、报警等线缆一一相连。DVR提供集中编码、录像以及监控信号回放。DVR采用的是数字记录技术，在图像处理、图像储存、检索、备份、以及网络传递、远程控制等方面也远远优于模拟监控设备，DVR代表了电视监控系统的发展方向，是目前市面上电视监控系统的首选产品。市面上流行的产品有PC平台DVR和嵌入式DVR，嵌入式DVR在稳定性、可靠性、易用性等方面有“专业化”的优势，嵌入式DVR会逐步侵占PC平台DVR的市场。PC平台DVR在通用性、可扩张性方面占有优势，在网络视频监控系统中仍可负担管理主机的角色，仍然有其自身的市场份额。由于价格、性能等原因，在国内市场上的DVR产品主要是包括台湾在内的大中华地区及韩国的产品占主导地位，大陆地区企业具有“中国制造”的优势，但在技术上几乎完全依赖国外的技术发展，没有掌握核心芯片和嵌入式主板开发的关键技术，企业的技术创新能力较差，台湾和邻国韩国在这方面强于大陆地区企业。目前国外已有很多公司投入资金开发多路的MPEG-II、MPEG-4压缩芯片，和小波的图像压缩芯片，新型压缩芯片的出现和应用，将使数字化网络视频监控迈向新的时代。同时随着存储设备容量的不断增大，价格不断地降低，新的存储技术的发展，摄像机的全数字、高清晰度不断完善，高画质图像标准的产品将投入市场，成为数字化网络视频监控的新宠。另外，企业在开发新产品过程中还应该注意通过行业协会建立统一标准，使不同企业的产品能够通过网络真正实现数据共享，并且应尽可能与楼宇智能系统中其它各子系统实现无缝连接，实现楼宇系统的统一管理和控制。<br><br>　　NVR系统中，中心部署NVR，监控点部署网络摄像机或视频适配器，监控点设备与中心NVR之间通过任意IP网络相连。监控点视频、音频以及告警信号经网络摄像机或视频适配器数字化处理后，以IP码流形式上传到NVR，由NVR进行集中录像存储和管理。结合网络摄像机、视频编码器等IP前端，科达NVR可提供全IP视频监控解决方案，用户仅需借助现有网络即可完成整个系统的快速部署，并可在任意时间、任意地点对任意目标进行实时监控和管理。基于全网络化处理，NVR在部署、应用以及管理等各个方面都提供了全新的、创新的解决方案，拥有前所未有的网络化优势。<br><br>　　传统嵌入式DVR系统为模拟前端，监控点与中心DVR之间采用模拟方式互联，因受到传输距离以及模拟信号损失的影响，监控点的位置也存在很大的局限性，无法实现远程部署。而NVR作为全网络化架构的视频监控系统，监控点设备与NVR之间可以通过任意IP网络互联<br><br>　　布线，dvr比较繁琐，要视频线、音频线等，nvr一条网线解决。<br><br>　　即插即用<br><br>　　长久以来，包括NVR在内的网络产品，因罩着网络这层神秘面纱――要设IP地址，要操作复杂的管理后台等等，一直让大部分工程商“敬而远之”，但现在，使用NVR已经不必这样了，只需接上网线、打开电源，系统会自动搜索IP前端、自动分配IP地址、自动显示多画面，在安装设置上不说优于DVR，但至少是旗鼓相当了。<br><br>　　录像存储<br><br>　　DVR受到用户欢迎的一个重要因素就是它拥有强大的录像、存储功能，但是这一性能的发挥仍旧受制于其模拟前端，即DVR无法实现前端存储，一旦中心设备或线路出现故障，录像资料就无从获取了;而目前，市面上的NVR产品及系统可以支持中心存储、前端存储以及客户端存储三种存储方式，并能实现中心与前端互为备份，一旦因故导致中心不能录像时，系统会自动转由前端录像并存储;在存储的容量上，NVR也装置了大容量硬盘，并设硬盘接口、网络接口、USB接口，可满足海量的存储需求。<br><br>　　安全性<br><br>　　网络产品长期以来被认为有安全隐患，的确，在没有安全可靠的机制条件下，网络确实是一个多事之地，然而，在网络监控系统中，一旦通过使用AES码流加密、用户认证和授权等这些手段来确保安全，网络监控产品源于网络的安全隐忧就完全消除了，目前，NVR产品及系统已经可以实现这些保障;而相比之下，DVR模拟前端传输的音频、视频裸信号，没有任何加密机制，很容易被非法截获，而一旦被截获则很轻易就被显示出来。<br><br>　　管理<br><br>　　NVR监控系统的全网管理应当说是其一大亮点，它能实现传输线路、传输网络以及所有IP前端的全程监测和集中管理，包括设备状态的监测和参数的浏览;而DVR同样又是因其中心到前端为模拟传输，从而无法实现传输线路以及前端设备的实时监测和集中管理，前端或线路有故障时，要查实具体原因非常不便。<br><br>从上面产品层面的比较来看，NVR确实已经具备了全面取代DVR的基础。而从市场层面来看，NVR同样也具备全面取代DVR的趋势，原因在于以下三个方面：基础网络现在越来越普及，不管是远程网络还是被监控单位内部的局域网目前都非常普及和成熟，这就具备了网络化部署的先决条件;人们对监控的网络化需求日益突出，不仅要在本地实现监控，还希望能够通过远程，甚至通过无线方式进行监控，而这些只有进行网络化才能满足用户的需求;<br><br>　　但是目前市场上几乎所有的DVR都同时具有网络功能,而且有的DVR网络功能与性能非常强大,这种DVR完全都可以叫做是NVR了.NVR,可以直接接模拟网络摄像机,但是网络摄像机一般比普通CCTV模拟摄像机贵,也可以接模拟CCTV摄像机,但需要增加一个转换器,用网线替代视频线的代价是增加一个转换器.其实DVR或笔记本电脑就可以直接做成接受网络摄像机的信号,包括数字网络摄像机.简单地讲就是一个可以接模拟网络摄像机的嵌入式DVR.感觉目前意义不是特别大.<br><br> <!--v:3.2--> ]]></description>
<category><![CDATA[学习]]></category>
<author><![CDATA[289367588@qq.com(surpercore)]]></author>
<comments>http://289367588.qzone.qq.com/blog/1241442473#comment</comments>
<qz:effect>134217728</qz:effect>
<pubDate>Mon, 04 May 2009 13:07:53 GMT</pubDate>
<guid>http://289367588.qzone.qq.com/blog/1241442473</guid>
</item>

<item>
<title><![CDATA[VC　CString,int,string,char*之间的转换]]></title>
<link>http://289367588.qzone.qq.com/blog/1238133203</link>
<description><![CDATA[VC　CString,int,string,char*之间的转换　2008-12-23 22:32<br>分类：VC++ 字号： 大大  中中  小小 1 CString,int,string,char*之间的转换 <br>string 转 CString <br>CString.format(&quot;%s&quot;, string.c_str()); <br>char 转 CString <br>CString.format(&quot;%s&quot;, char*); <br>char 转 string <br>string s(char *); <br>string 转 char * <br>char *p = string.c_str(); <br>CString 转 string <br>string s(CString.GetBuffer()); <br>1，string -&gt; CString <br>CString.format(&quot;%s&quot;, string.c_str()); <br>用c_str()确实比data()要好. <br>2，char -&gt; string <br>string s(char *); <br>你的只能初始化，在不是初始化的地方最好还是用assign(). <br>3,CString -&gt; string <br>string s(CString.GetBuffer()); <br>GetBuffer()后一定要ReleaseBuffer(),否则就没有释放缓冲区所占的空间. <br><br>《C++标准函数库》中说的 <br>有三个函数可以将字符串的内容转换为字符数组和C—string <br>1.data(),返回没有”\0“的字符串数组 <br>2,c_str()，返回有”\0“的字符串数组 <br>3，copy() <br><br>CString互转int <br>将字符转换为整数，可以使用atoi、_atoi64或atol。 <br>而将数字转换为CString变量，可以使用CString的Format函数。如 <br>CString s; <br>int i = 64; <br>s.Format(&quot;%d&quot;, i) <br>Format函数的功能很强，值得你研究一下。 <br>void CStrDlg::OnButton1() <br>{ <br>// TODO: Add your control notification handler code here <br>CString <br>ss=&quot;1212.12&quot;; <br>int temp=atoi(ss); <br>CString aa; <br>aa.Format(&quot;%d&quot;,temp); <br>AfxMessageBox(&quot;var is &quot; + aa); <br>} <br>sart.Format(&quot;%s&quot;,buf); <br>CString互转char* <br>///char * TO cstring <br>CString strtest; <br>char * charpoint; <br>charpoint=&quot;give string a value&quot;; <br>strtest=charpoint; <br><br>///cstring TO char * <br>charpoint=strtest.GetBuffer(strtest.GetLength()); <br>标准C里没有string,char *==char []==string <br>可以用CString.Format(&quot;%s&quot;,char *)这个方法来将char *转成CString。要把CString转成char *，用操作符（LPCSTR）CString就可以了。 <br><br>CString转换 char[100] <br>char a[100]; <br>CString str(&quot;aaaaaa&quot;); <br>strncpy(a,(LPCTSTR)str,sizeof(a)); <br>2 CString类型的转换成int <br>CString类型的转换成int <br>将字符转换为整数，可以使用atoi、_atoi64或atol。 <br>//CString aaa = &quot;16&quot; ; <br>//int int_chage = atoi((lpcstr)aaa) ; <br><br>而将数字转换为CString变量，可以使用CString的Format函数。如 <br>CString s; <br>int i = 64; <br>s.Format(&quot;%d&quot;, i) <br>Format函数的功能很强，值得你研究一下。 <br>如果是使用char数组，也可以使用sprintf函数。 <br>//CString ss=&quot;1212.12&quot;; <br>//int temp=atoi(ss); <br>//CString aa; <br>//aa.Format(&quot;%d&quot;,temp); <br><br>数字-&gt;字符串除了用CString::Format，还有FormatV、sprintf和不需要借助于Afx的itoa <br><br>3 char* 在装int <br>#include &lt;stdlib.h&gt; <br><br>int atoi(const char *nptr); <br>long atol(const char *nptr); <br>long long atoll(const char *nptr); <br>long long atoq(const char *nptr); <br><br>4 CString,int,string,char*之间的转换 <br>string aa(&quot;aaa&quot;); <br>char *c=aa.c_str(); <br><br>cannot convert from 'const char *' to 'char *' <br>const char *c=aa.c_str(); <br><br>5 CString,int,string,char*之间的转换 <br>string.c_str()只能转换成const char *, <br>要转成char *这样写: <br>string mngName； <br>char t[200]; memset(t,0,200); strcpy(t,mngName.c_str());  <!--v:3.2--> ]]></description>
<category><![CDATA[学习]]></category>
<author><![CDATA[289367588@qq.com(surpercore)]]></author>
<comments>http://289367588.qzone.qq.com/blog/1238133203#comment</comments>
<qz:effect>134217728</qz:effect>
<pubDate>Fri, 27 Mar 2009 05:53:23 GMT</pubDate>
<guid>http://289367588.qzone.qq.com/blog/1238133203</guid>
</item>

<item>
<title><![CDATA[转  WinSock学习笔记 一]]></title>
<link>http://289367588.qzone.qq.com/blog/1237286490</link>
<description><![CDATA[typedef unsigned int u_int;typedef u_int SOCKET; <br>◆Socket相当于进行网络通信两端的插座，只要对方的Socket和自己的Socket有通信联接，双方就可以发送和接收数据了。其定义类似于文件句柄的定义。 <br><br>◆Socket有五种不同的类型： <br><br>1、流式套接字(stream socket) <br>定义： <br>#define SOCK_STREAM 1 <br>流式套接字提供了双向、有序的、无重复的以及无记录边界的数据流服务，适合处理大量数据。它是面向联结的，必须建立数据传输链路，同时还必须对传输的数据进行验证，确保数据的准确性。因此，系统开销较大。 <br><br>2、 数据报套接字(datagram socket) <br><br>定义： <br>#define SOCK_DGRAM 2 <br>数据报套接字也支持双向的数据流，但不保证传输数据的准确性，但保留了记录边界。由于数据报套接字是无联接的，例如广播时的联接，所以并不保证接收端是否正在侦听。数据报套接字传输效率比较高。 <br><br>3、原始套接字(raw-protocol interface) <br><br>定义： <br>#define SOCK_RAW 3 <br>原始套接字保存了数据包中的完整IP头，前面两种套接字只能收到用户数据。因此可以通过原始套接字对数据进行分析。 <br>其它两种套接字不常用，这里就不介绍了。 <br><br>◆Socket开发所必须需要的文件(以WinSock V2.0为例)： <br><br>头文件：Winsock2.h <br><br>库文件：WS2_32.LIB <br><br>动态库：W32_32.DLL <br><br><wbr /><a href="http://www.vckbase.com/document/image/paragraph.gif" target="_blank"><img style="border:0;" src="http://www.vckbase.com/document/image/paragraph.gif" /></a><wbr /><span style="font-weight:bold"><wbr /> 一些重要的定义</span><wbr /> <br><br>1、数据类型的基本定义：这个大家一看就懂。 <br>typedef unsigned char u_char;typedef unsigned short u_short;typedef unsigned int u_int;typedef unsigned long u_long; <br>2、 网络地址的数据结构，有一个老的和一个新的的，请大家留意，如果想知道为什么， <br>请发邮件给Bill Gate。其实就是计算机的IP地址，不过一般不用用点分开的IP地 <br>址，当然也提供一些转换函数。 <br><br>◆ 旧的网络地址结构的定义，为一个4字节的联合： <br>struct in_addr {union {struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;struct { u_short s_w1,s_w2; } S_un_w;u_long S_addr;} S_un;#define s_addr S_un.S_addr /* can be used for most tcp &amp; ip code *///下面几行省略,反正没什么用处。}; <br>其实完全不用这么麻烦，请看下面: <br><br>◆ 新的网络地址结构的定义： <br>非常简单，就是一个无符号长整数 unsigned long。举个例子：IP地址为127.0.0.1的网络地址是什么呢？请看定义： <br>#define INADDR_LOOPBACK 0x7f000001 <br>3、 套接字地址结构 <br><br>(1)、sockaddr结构： <br>struct sockaddr {u_short sa_family; /* address family */char sa_data[14]; /* up to 14 bytes of direct address */}; <br>sa_family为网络地址类型，一般为AF_INET，表示该socket在Internet域中进行通信，该地址结构随选择的协议的不同而变化，因此一般情况下另一个与该地址结构大小相同的sockaddr_in结构更为常用，sockaddr_in结构用来标识TCP/IP协议下的地址。换句话说，这个结构是通用socket地址结构，而下面的sockaddr_in是专门针对Internet域的socket地址结构。 <br><br>(2)、sockaddr_in结构 <br>struct sockaddr_in {short sin_family;u_short sin_port;struct in_addr sin_addr;char sin_zero[8];}; <br>sin _family为网络地址类型，必须设定为AF_INET。sin_port为服务端口，注意不要使用已固定的服务端口，如HTTP的端口80等。如果端口设置为0，则系统会自动分配一个唯一端口。sin_addr为一个unsigned long的IP地址。sin_zero为填充字段，纯粹用来保证结构的大小。 <br><br>◆ 将常用的用点分开的IP地址转换为unsigned long类型的IP地址的函数： <br>unsigned long inet_addr(const char FAR * cp ) <br>用法： <br>unsigned long addr=inet_addr(&quot;192.1.8.84&quot;) <br>char * str=inet_ntoa(m_proxyAddress.sin_addr);<br>◆ 如果将sin_addr设置为INADDR_ANY，则表示所有的IP地址，也即所有的计算机。 <br>#define INADDR_ANY (u_long)0x00000000 <br>4、 主机地址： <br><br>先看定义： <br>struct hostent {char FAR * h_name; /* official name of host */char FAR * FAR * h_aliases; /* alias list */short h_addrtype; /* host address type */short h_length; /* length of address */char FAR * FAR * h_addr_list; /* list of addresses */#define h_addr h_addr_list[0] /* address, for backward compat */};h_name为主机名字。h_aliases为主机别名列表。h_addrtype为地址类型。h_length为地址类型。h_addr_list为IP地址，如果该主机有多个网卡，就包括地址的列表。 <br>另外还有几个类似的结构，这里就不一一介绍了。 <br><br>5、 常见TCP/IP协议的定义： <br>#define IPPROTO_IP 0 #define IPPROTO_ICMP 1 #define IPPROTO_IGMP 2 #define IPPROTO_TCP 6 #define IPPROTO_UDP 17 #define IPPROTO_RAW 255 <br>具体是什么协议，大家一看就知道了。 <br><br><wbr /><a href="http://www.vckbase.com/document/image/paragraph.gif" target="_blank"><img style="border:0;" src="http://www.vckbase.com/document/image/paragraph.gif" /></a><wbr /><span style="font-weight:bold"><wbr /> 套接字的属性</span><wbr /> <br><br>为了灵活使用套接字，我们可以对它的属性进行设定。 <br><br>1、 属性内容： <br>//允许调试输出#define SO_DEBUG 0x0001 /* turn on debugging info recording *///是否监听模式#define SO_ACCEPTCONN 0x0002 /* socket has had listen() *///套接字与其他套接字的地址绑定#define SO_REUSEADDR 0x0004 /* allow local address reuse *///保持连接#define SO_KEEPALIVE 0x0008 /* keep connections alive *///不要路由出去#define SO_DONTROUTE 0x0010 /* just use interface addresses *///设置为广播#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs *///使用环回不通过硬件#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible *///当前拖延值#define SO_LINGER 0x0080 /* linger on close if data present *///是否加入带外数据#define SO_OOBINLINE 0x0100 /* leave received OOB data in line *///禁用LINGER选项#define SO_DONTLINGER (int)(~SO_LINGER)//发送缓冲区长度#define SO_SNDBUF 0x1001 /* send buffer size *///接收缓冲区长度#define SO_RCVBUF 0x1002 /* receive buffer size *///发送超时时间#define SO_SNDTIMEO 0x1005 /* send timeout *///接收超时时间#define SO_RCVTIMEO 0x1006 /* receive timeout *///错误状态#define SO_ERROR 0x1007 /* get error status and clear *///套接字类型#define SO_TYPE 0x1008 /* get socket type */ <br>2、 读取socket属性： <br>int getsockopt(SOCKET s, int level, int optname, char FAR * optval, int FAR * optlen) <br>s为欲读取属性的套接字。level为套接字选项的级别，大多数是特定协议和套接字专有的。如IP协议应为 IPPROTO_IP。 <br>optname为读取选项的名称optval为存放选项值的缓冲区指针。optlen为缓冲区的长度 <br>用法： <br>int ttl=0; //读取TTL值int rc = getsockopt( s, IPPROTO_IP, IP_TTL, (char *)&amp;ttl, sizeof(ttl));//来自MS platform SDK 2003 <br>3、 设置socket属性： <br>int setsockopt(SOCKET s,int level, int optname,const char FAR * optval, int optlen) <br>s为欲设置属性的套接字。 <br>level为套接字选项的级别，用法同上。 <br>optname为设置选项的名称 <br>optval为存放选项值的缓冲区指针。 <br>optlen为缓冲区的长度 <br><br>用法： <br>int ttl=32; //设置TTL值int rc = setsockopt( s, IPPROTO_IP, IP_TTL, (char *)&amp;ttl, sizeof(ttl)); <br><wbr /><a href="http://www.vckbase.com/document/image/paragraph.gif" target="_blank"><img style="border:0;" src="http://www.vckbase.com/document/image/paragraph.gif" /></a><wbr /><span style="font-weight:bold"><wbr /> 套接字的使用步骤</span><wbr /> <br><br>1、启动Winsock：对Winsock DLL进行初始化，协商Winsock的版本支持并分配必要的 <br>资源。（服务器端和客户端） <br>int WSAStartup( WORD wVersionRequested, LPWSADATA lpWSAData )wVersionRequested为打算加载Winsock的版本，一般如下设置：wVersionRequested=MAKEWORD(2,0)或者直接赋值：wVersionRequested=2LPWSADATA为初始化Socket后加载的版本的信息,定义如下：typedef struct WSAData {WORD wVersion;WORD wHighVersion;char szDescription[WSADESCRIPTION_LEN+1];char szSystemStatus[WSASYS_STATUS_LEN+1];unsigned short iMaxSockets;unsigned short iMaxUdpDg;char FAR * lpVendorInfo;} WSADATA, FAR * LPWSADATA; <br>如果加载成功后数据为： <br>wVersion＝2表示加载版本为2.0。wHighVersion＝514表示当前系统支持socket最高版本为2.2。szDescription=&quot;WinSock 2.0&quot;szSystemStatus=&quot;Running&quot;表示正在运行。iMaxSockets＝0表示同时打开的socket最大数，为0表示没有限制。iMaxUdpDg＝0表示同时打开的数据报最大数，为0表示没有限制。lpVendorInfo没有使用，为厂商指定信息预留。 <br>该函数使用方法： <br>WORD wVersion=MAKEWORD(2,0);WSADATA wsData;int nResult= WSAStartup(wVersion,&amp;wsData);if(nResult !=0){//错误处理} <br>2、创建套接字：（服务器端和客户端） <br>SOCKET socket( int af, int type, int protocol );af为网络地址类型，一般为AF_INET，表示在Internet域中使用。type为套接字类型，前面已经介绍了。protocol为指定网络协议，一般为IPPROTO_IP。 <br>用法： <br>SOCKET sock=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);if(sock==INVALID_SOCKET){//错误处理} <br>3、套接字的绑定：将本地地址绑定到所创建的套接字上。（服务器端和客户端） <br>int bind( SOCKET s, const struct sockaddr FAR * name, int namelen )s为已经创建的套接字。name为socket地址结构，为sockaddr结构，如前面讨论的，我们一般使用sockaddr_in结构，在使用再强制转换为sockaddr结构。namelen为地址结构的长度。 <br>用法： <br>sockaddr_in addr;addr. sin_family=AF_INET;addr. sin_port= htons(0); //保证字节顺序addr. sin_addr.s_addr= inet_addr(&quot;192.1.8.84&quot;)int nResult=bind(s,(sockaddr*)&amp;addr,sizeof(sockaddr));if(nResult==SOCKET_ERROR){//错误处理} <br>4、 套接字的监听：（服务器端） <br>int listen(SOCKET s, int backlog ) <br>s为一个已绑定但未联接的套接字。 <br>backlog为指定正在等待联接的最大队列长度，这个参数非常重要，因为服务器一般可 <br>以提供多个连接。 <br>用法： <br>int nResult=listen(s,5) //最多5个连接if(nResult==SOCKET_ERROR){//错误处理} <br>5、套接字等待连接:：（服务器端） <br>SOCKET accept( SOCKET s, struct sockaddr FAR * addr, int FAR * addrlen ) <br>s为处于监听模式的套接字。 <br>sockaddr为接收成功后返回客户端的网络地址。 <br>addrlen为网络地址的长度。 <br><br>用法： <br>sockaddr_in addr;SOCKET s_d=accept(s,(sockaddr*)&amp;addr,sizeof(sockaddr));if(s==INVALID_SOCKET){//错误处理} <br>6、套接字的连结：将两个套接字连结起来准备通信。（客户端） <br>int connect(SOCKET s, const struct sockaddr FAR * name, int namelen ) <br>s为欲连结的已创建的套接字。 <br>name为欲连结的socket地址。 <br>namelen为socket地址的结构的长度。 <br><br>用法： <br>sockaddr_in addr;addr. sin_family=AF_INET;addr. sin_port=htons(0); //保证字节顺序addr. sin_addr.s_addr= htonl(INADDR_ANY) //保证字节顺序int nResult=connect(s,(sockaddr*)&amp;addr,sizeof(sockaddr));if(nResult==SOCKET_ERROR){//错误处理} <br>7、套接字发送数据：（服务器端和客户端） <br>int send(SOCKET s, const char FAR * buf, int len, int flags ) <br>s为服务器端监听的套接字。 <br>buf为欲发送数据缓冲区的指针。 <br>len为发送数据缓冲区的长度。 <br>flags为数据发送标记。 <br>返回值为发送数据的字符数。 <br><br>◆这里讲一下这个发送标记，下面8中讨论的接收标记也一样： <br><br>flag取值必须为0或者如下定义的组合：0表示没有特殊行为。 <br><br>#define MSG_OOB 0x1 /* process out-of-band data */ <br>#define MSG_PEEK 0x2 /* peek at incoming message */ <br>#define MSG_DONTROUTE 0x4 /* send without using routing tables */ <br>MSG_OOB表示数据应该带外发送，所谓带外数据就是TCP紧急数据。 <br>MSG_PEEK表示使有用的数据复制到缓冲区内，但并不从系统缓冲区内删除。 <br>MSG_DONTROUTE表示不要将包路由出去。 <br><br>用法： <br>char buf[]=&quot;xiaojin&quot;;int nResult=send(s,buf,strlen(buf));if(nResult==SOCKET_ERROR){//错误处理} <br>8、 套接字的数据接收：（客户端） <br>int recv( SOCKET s, char FAR * buf, int len, int flags ) <br>s为准备接收数据的套接字。 <br>buf为准备接收数据的缓冲区。 <br>len为准备接收数据缓冲区的大小。 <br>flags为数据接收标记。 <br>返回值为接收的数据的字符数。 <br><br>用法： <br>char mess[1000];int nResult =recv(s,mess,1000,0);if(nResult==SOCKET_ERROR){//错误处理} <br>9、中断套接字连接：通知服务器端或客户端停止接收和发送数据。（服务器端和客户端） <br>int shutdown(SOCKET s, int how) <br>s为欲中断连接的套接字。 <br>How为描述禁止哪些操作，取值为：SD_RECEIVE、SD_SEND、SD_BOTH。 <br>#define SD_RECEIVE 0x00#define SD_SEND 0x01#define SD_BOTH 0x02 <br>用法： <br>int nResult= shutdown(s,SD_BOTH);if(nResult==SOCKET_ERROR){//错误处理} <br>10、 关闭套接字：释放所占有的资源。（服务器端和客户端） <br>int closesocket( SOCKET s ) <br>s为欲关闭的套接字。 <br><br>用法： <br>int nResult=closesocket(s);if(nResult==SOCKET_ERROR){//错误处理} <!--v:3.2--> ]]></description>
<category><![CDATA[学习]]></category>
<author><![CDATA[289367588@qq.com(surpercore)]]></author>
<comments>http://289367588.qzone.qq.com/blog/1237286490#comment</comments>
<qz:effect>134218241</qz:effect>
<pubDate>Tue, 17 Mar 2009 10:41:30 GMT</pubDate>
<guid>http://289367588.qzone.qq.com/blog/1237286490</guid>
</item>

<item>
<title><![CDATA[转 WinSock学习笔记（二）]]></title>
<link>http://289367588.qzone.qq.com/blog/1237286312</link>
<description><![CDATA[<br> 与socket有关的一些函数介绍<br><br>1、读取当前错误值：每次发生错误时，如果要对具体问题进行处理，那么就应该调用这个函数取得错误代码。 <br><br>      int  WSAGetLastError(void );<br>      #define h_errno   WSAGetLastError()<br><br>错误值请自己阅读Winsock2.h。<br><br>2、将主机的unsigned long值转换为网络字节顺序(32位)：为什么要这样做呢？因为不同的计算机使用不同的字节顺序存储数据。因此任何从Winsock函数对IP地址和端口号的引用和传给Winsock函数的IP地址和端口号均时按照网络顺序组织的。<br>      u_long  htonl(u_long hostlong);<br>      举例：htonl(0)=0<br>      htonl(80)= 1342177280<br><br>3、将unsigned long数从网络字节顺序转换位主机字节顺序，是上面函数的逆函数。       u_long  ntohl(u_long netlong);<br>      举例：ntohl(0)=0<br>      ntohl(1342177280)= 80<br><br>4、将主机的unsigned short值转换为网络字节顺序(16位)：原因同2：       u_short  htons(u_short hostshort);<br>      举例：htonl(0)=0<br>      htonl(80)= 20480<br><br>5、将unsigned short数从网络字节顺序转换位主机字节顺序，是上面函数的逆函数。       u_short  ntohs(u_short netshort);<br>      举例：ntohs(0)=0<br>      ntohsl(20480)= 80<br><br>6、将用点分割的IP地址转换位一个in_addr结构的地址，这个结构的定义见笔记(一)，实际上就是一个unsigned long值。计算机内部处理IP地址可是不认识如192.1.8.84之类的数据。       unsigned long  inet_addr( const char FAR * cp );<br>      举例：inet_addr(&quot;192.1.8.84&quot;)=1409810880<br>      inet_addr(&quot;127.0.0.1&quot;)= 16777343<br><br>如果发生错误，函数返回INADDR_NONE值。<br><br>7、将网络地址转换位用点分割的IP地址，是上面函数的逆函数。       char FAR *  inet_ntoa( struct in_addr in );<br>      举例：char * ipaddr=NULL;<br>      char addr[20];<br>      in_addr inaddr;<br>      inaddr. s_addr=16777343;<br>      ipaddr= inet_ntoa(inaddr);<br>      strcpy(addr,ipaddr); <br>这样addr的值就变为127.0.0.1。<br>注意意不要修改返回值或者进行释放动作。如果函数失败就会返回NULL值。<br><br>8、获取套接字的本地地址结构：       int  getsockname(SOCKET s, struct sockaddr FAR * name, int FAR * namelen );<br>      s为套接字<br>      name为函数调用后获得的地址值<br>      namelen为缓冲区的大小。<br> <br>9、获取与套接字相连的端地址结构：<br>      int  getpeername(SOCKET s, struct sockaddr FAR * name, int FAR * namelen );<br>      s为套接字<br>      name为函数调用后获得的端地址值<br>      namelen为缓冲区的大小。<br> <br>10、获取计算机名：<br>      int  gethostname( char FAR * name, int namelen );<br>      name是存放计算机名的缓冲区<br>      namelen是缓冲区的大小<br>      用法：<br>      char szName[255];<br>      memset(szName,0,255);<br>      if(gethostname(szName,255)==SOCKET_ERROR)<br>      {<br>        //错误处理<br>      }<br>      返回值为：szNmae=&quot;xiaojin&quot;<br> <br>11、根据计算机名获取主机地址：       struct hostent FAR *  gethostbyname( const char FAR * name );<br><br>      name为计算机名。<br>      用法：<br>      hostent * host;<br>      char* ip;<br>      host= gethostbyname(&quot;xiaojin&quot;);<br>      if(host-&gt;h_addr_list[0])<br>      {<br>       struct in_addr addr;<br>       memmove(&amp;addr, host-&gt;h_addr_list[0]，4);<br>       //获得标准IP地址<br>       ip=inet_ ntoa (addr);<br>      }<br><br>      返回值为：hostent-&gt;h_name=&quot;xiaojin&quot;<br>          hostent-&gt;h_addrtype=2    //AF_INET<br>          hostent-&gt;length=4<br>          ip=&quot;127.0.0.1&quot;<br> <br> Winsock 的I/O操作：<br><br>1、 两种I/O模式 <br>阻塞模式：执行I/O操作完成前会一直进行等待，不会将控制权交给程序。套接字 默认为阻塞模式。可以通过多线程技术进行处理。 <br>非阻塞模式：执行I/O操作时，Winsock函数会返回并交出控制权。这种模式使用 起来比较复杂，因为函数在没有运行完成就进行返回，会不断地返回 WSAEWOULDBLOCK错误。但功能强大。<br>为了解决这个问题，提出了进行I/O操作的一些I/O模型,下面介绍最常见的三种：<br><br>2、select模型：<br><br>　　通过调用select函数可以确定一个或多个套接字的状态，判断套接字上是否有数据，或<br>者能否向一个套接字写入数据。       int  select( int nfds, fd_set FAR * readfds, fd_set FAR * writefds, <br>      fd_set FAR *exceptfds, const struct timeval FAR * timeout );<br>      <br>◆先来看看涉及到的结构的定义：<br>a、 d_set结构：<br>#define FD_SETSIZE 64?<br>typedef struct fd_set {<br>u_int fd_count; /* how many are SET? */<br>SOCKET fd_array[FD_SETSIZE]; /* an array of SOCKETs */<br>} fd_set;      <br>fd_count为已设定socket的数量<br>fd_array为socket列表，FD_SETSIZE为最大socket数量，建议不小于64。这是微软建<br>议的。<br><br>B、timeval结构： struct timeval {<br>long tv_sec; /* seconds */<br>long tv_usec; /* and microseconds */<br>};<br><br>tv_sec为时间的秒值。<br>tv_usec为时间的毫秒值。<br>这个结构主要是设置select()函数的等待值，如果将该结构设置为(0,0)，则select()函数<br>会立即返回。<br><br>◆再来看看select函数各参数的作用： <br>nfds：没有任何用处，主要用来进行系统兼容用，一般设置为0。<br><br>readfds：等待可读性检查的套接字组。<br><br>writefds；等待可写性检查的套接字组。<br><br>exceptfds：等待错误检查的套接字组。<br><br>timeout：超时时间。<br><br>函数失败的返回值：调用失败返回SOCKET_ERROR,超时返回0。<br>readfds、writefds、exceptfds三个变量至少有一个不为空，同时这个不为空的套接字组<br>种至少有一个socket，道理很简单，否则要select干什么呢。 举例：测试一个套接字是否可读：fd_set fdread;<br>//FD_ZERO定义<br>// #define FD_ZERO(set) (((fd_set FAR *)(set))-&gt;fd_count=0)<br>FD_ZERO(&amp;fdread);<br>FD_SET(s,&amp;fdread)； //加入套接字，详细定义请看winsock2.h<br>if(select(0,%fdread,NULL,NULL,NULL)&gt;0<br>{<br> //成功<br> if(FD_ISSET(s,&amp;fread) //是否存在fread中，详细定义请看winsock2.h<br> {<br>  //是可读的<br> }<br>}<br>◆I/O操作函数：主要用于获取与套接字相关的操作参数。 <br><br> int  ioctlsocket(SOCKET s, long cmd, u_long FAR * argp );     <br>s为I/O操作的套接字。<br>cmd为对套接字的操作命令。<br>argp为命令所带参数的指针。<br><br>常见的命令： //确定套接字自动读入的数据量<br>#define FIONREAD _IOR(''''f'''', 127, u_long) /* get # bytes to read */<br>//允许或禁止套接字的非阻塞模式，允许为非0，禁止为0<br>#define FIONBIO _IOW(''''f'''', 126, u_long) /* set/clear non-blocking i/o */<br>//确定是否所有带外数据都已被读入<br>#define SIOCATMARK _IOR(''''s'''', 7, u_long) /* at oob mark? */<br><br>3、WSAAsynSelect模型：<br>WSAAsynSelect模型也是一个常用的异步I/O模型。应用程序可以在一个套接字上接收以<br>WINDOWS消息为基础的网络事件通知。该模型的实现方法是通过调用WSAAsynSelect函<br>数 自动将套接字设置为非阻塞模式，并向WINDOWS注册一个或多个网络时间，并提供一<br>个通知时使用的窗口句柄。当注册的事件发生时，对应的窗口将收到一个基于消息的通知。<br>      int  WSAAsyncSelect( SOCKET s, HWND hWnd, u_int wMsg, long lEvent);       <br>s为需要事件通知的套接字<br>hWnd为接收消息的窗口句柄<br>wMsg为要接收的消息<br>lEvent为掩码，指定应用程序感兴趣的网络事件组合，主要如下： #define FD_READ_BIT 0<br>#define FD_READ (1 &lt;&lt; FD_READ_BIT)<br>#define FD_WRITE_BIT 1<br>#define FD_WRITE (1 &lt;&lt; FD_WRITE_BIT)<br>#define FD_OOB_BIT 2<br>#define FD_OOB (1 &lt;&lt; FD_OOB_BIT)<br>#define FD_ACCEPT_BIT 3<br>#define FD_ACCEPT (1 &lt;&lt; FD_ACCEPT_BIT)<br>#define FD_CONNECT_BIT 4<br>#define FD_CONNECT (1 &lt;&lt; FD_CONNECT_BIT)<br>#define FD_CLOSE_BIT 5<br>#define FD_CLOSE (1 &lt;&lt; FD_CLOSE_BIT)<br><br>用法：要接收读写通知：int nResult= WSAAsyncSelect(s,hWnd,wMsg,FD_READ|FD_WRITE)；<br>if(nResult==SOCKET_ERROR)<br>{<br> //错误处理<br>}<br><br>取消通知：<br>      int nResult= WSAAsyncSelect(s,hWnd,0，0)； <br><br>当应用程序窗口hWnd收到消息时，wMsg.wParam参数标识了套接字，lParam的低字标明<br>了网络事件，高字则包含错误代码。<br><br>4、WSAEventSelect模型<br>WSAEventSelect模型类似WSAAsynSelect模型，但最主要的区别是网络事件发生时会被发<br>送到一个事件对象句柄，而不是发送到一个窗口。<br><br>使用步骤如下：<br>a、 创建事件对象来接收网络事件：<br>#define WSAEVENT HANDLE<br>#define LPWSAEVENT LPHANDLE<br>WSAEVENT WSACreateEvent( void );<br><br>该函数的返回值为一个事件对象句柄，它具有两种工作状态：已传信(signaled)和未传信<br>(nonsignaled)以及两种工作模式：人工重设(manual reset)和自动重设(auto reset)。默认未<br>未传信的工作状态和人工重设模式。<br><br>b、将事件对象与套接字关联，同时注册事件，使事件对象的工作状态从未传信转变未<br>已传信。<br>      int  WSAEventSelect( SOCKET s,WSAEVENT hEventObject,long lNetworkEvents );  <br>s为套接字<br>hEventObject为刚才创建的事件对象句柄<br>lNetworkEvents为掩码，定义如上面所述<br><br>c、I/O处理后，设置事件对象为未传信BOOL WSAResetEvent( WSAEVENT hEvent );<br>Hevent为事件对象<br><br>成功返回TRUE，失败返回FALSE。<br><br>d、等待网络事件来触发事件句柄的工作状态：<br><br>DWORD WSAWaitForMultipleEvents( DWORD cEvents,<br>const WSAEVENT FAR * lphEvents, BOOL fWaitAll,<br>DWORD dwTimeout, BOOL fAlertable );<br>lpEvent为事件句柄数组的指针<br>cEvent为为事件句柄的数目，其最大值为WSA_MAXIMUM_WAIT_EVENTS <br>fWaitAll指定等待类型：TRUE：当lphEvent数组重所有事件对象同时有信号时返回；<br>FALSE：任一事件有信号就返回。<br>dwTimeout为等待超时（毫秒）<br>fAlertable为指定函数返回时是否执行完成例程<br><br>对事件数组中的事件进行引用时，应该用WSAWaitForMultipleEvents的返回值，减去<br>预声明值WSA_WAIT_EVENT_0，得到具体的引用值。例如：<br><br>nIndex=WSAWaitForMultipleEvents(…);<br>MyEvent=EventArray[Index- WSA_WAIT_EVENT_0];<br>e、判断网络事件类型：<br><br>int WSAEnumNetworkEvents( SOCKET s,<br>WSAEVENT hEventObject, LPWSANETWORKEVENTS lpNetworkEvents );<br>s为套接字<br>hEventObject为需要重设的事件对象<br>lpNetworkEvents为记录网络事件和错误代码，其结构定义如下：<br><br>typedef struct _WSANETWORKEVENTS {<br> long lNetworkEvents;<br> int iErrorCode[FD_MAX_EVENTS];<br>} WSANETWORKEVENTS, FAR * LPWSANETWORKEVENTS;<br>f、关闭事件对象句柄：<br><br>BOOL WSACloseEvent(WSAEVENT hEvent);<br>调用成功返回TRUE，否则返回FALSE。<br> <!--v:3.2--> ]]></description>
<category><![CDATA[学习]]></category>
<author><![CDATA[289367588@qq.com(surpercore)]]></author>
<comments>http://289367588.qzone.qq.com/blog/1237286312#comment</comments>
<qz:effect>134217728</qz:effect>
<pubDate>Tue, 17 Mar 2009 10:38:32 GMT</pubDate>
<guid>http://289367588.qzone.qq.com/blog/1237286312</guid>
</item>

<item>
<title><![CDATA[socket]]></title>
<link>http://289367588.qzone.qq.com/blog/1236913448</link>
<description><![CDATA[setsockopt()　　简述：<br>　　设置套接口的选项。<br>　　#include &lt;winsock.h&gt;<br>　　int PASCAL FAR setsockopt( SOCKET s, int level, int optname,<br>　　const char FAR* optval, int optlen);<br>　　s：标识一个套接口的描述字。<br>　　level：选项定义的层次；目前仅支持SOL_SOCKET和IPPROTO_TCP层次。<br>　　optname：需设置的选项。<br>　　optval：指针，指向存放选项值的缓冲区。<br>　　optlen：optval缓冲区的长度。<br>　　注释：<br>　　setsockopt()函数用于任意类型、任意状态套接口的设置选项值。尽管在不同协议层上存在选项，但本函数仅定义了最高的“套接口”层次上的选项。选项影响套接口的操作，诸如加急数据是否在普通数据流中接收，广播数据是否可以从套接口发送等等。<br>　　有两种套接口的选项：一种是布尔型选项，允许或禁止一种特性；另一种是整形或结构选项。允许一个布尔型选项，则将optval指向非零整形数；禁止一个选项optval指向一个等于零的整形数。对于布尔型选项，optlen应等于sizeof(int)；对其他选项，optval指向包含所需选项的整形数或结构，而optlen则为整形数或结构的长度。SO_LINGER选项用于控制下述情况的行动：套接口上有排队的待发送数据，且closesocket()调用已执行。参见closesocket()函数中关于SO_LINGER选项对closesocket()语义的影响。应用程序通过创建一个linger结构来设置相应的操作特性：<br>　　struct linger {<br>　　        int l_onoff;<br>　　        int l_linger;<br>　　};<br>　　为了允许SO_LINGER，应用程序应将l_onoff设为非零，将l_linger设为零或需要的超时值（以秒为单位），然后调用setsockopt()。为了允许SO_DONTLINGER（亦即禁止SO_LINGER），l_onoff应设为零，然后调用setsockopt()。<br>　　缺省条件下，一个套接口不能与一个已在使用中的本地地址捆绑（参见bind()）。但有时会需要“重用”地址。因为每一个连接都由本地地址和远端地址的组合唯一确定，所以只要远端地址不同，两个套接口与一个地址捆绑并无大碍。为了通知WINDOWS套接口实现不要因为一个地址已被一个套接口使用就不让它与另一个套接口捆绑，应用程序可在bind()调用前先设置SO_REUSEADDR选项。请注意仅在bind()调用时该选项才被解释；故此无需（但也无害）将一个不会共用地址的套接口设置该选项，或者在bind()对这个或其他套接口无影响情况下设置或清除这一选项。<br>　　一个应用程序可以通过打开SO_KEEPALIVE选项，使得WINDOWS套接口实现在TCP连接情况下允许使用“保持活动”包。一个WINDOWS套接口实现并不是必需支持“保持活动”，但是如果支持的话，具体的语义将与实现有关，应遵守RFC1122“Internet主机要求－通讯层”中第4.2.3.6节的规范。如果有关连接由于“保持活动”而失效，则进行中的任何对该套接口的调用都将以WSAENETRESET错误返回，后续的任何调用将以WSAENOTCONN错误返回。<br>　　TCP_NODELAY选项禁止Nagle算法。Nagle算法通过将未确认的数据存入缓冲区直到蓄足一个包一起发送的方法，来减少主机发送的零碎小数据包的数目。但对于某些应用来说，这种算法将降低系统性能。所以TCP_NODELAY可用来将此算法关闭。应用程序编写者只有在确切了解它的效果并确实需要的情况下，才设置TCP_NODELAY选项，因为设置后对网络性能有明显的负面影响。TCP_NODELAY是唯一使用IPPROTO_TCP层的选项，其他所有选项都使用SOL_SOCKET层。<br>　　如果设置了SO_DEBUG选项，WINDOWS套接口供应商被鼓励（但不是必需）提供输出相应的调试信息。但产生调试信息的机制以及调试信息的形式已超出本规范的讨论范围。<br>　　setsockopt()支持下列选项。其中“类型”表明optval所指数据的类型。<br>　　选项 类型 意义<br>　　SO_BROADCAST BOOL 允许套接口传送广播信息。<br>　　SO_DEBUG BOOL 记录调试信息。<br>　　SO_DONTLINER BOOL 不要因为数据未发送就阻塞关闭操作。设置本选项相当于将SO_LINGER的l_onoff元素置为零。<br>　　SO_DONTROUTE BOOL 禁止选径；直接传送。<br>　　SO_KEEPALIVE BOOL 发送“保持活动”包。<br>　　SO_LINGER struct linger FAR* 如关闭时有未发送数据，则逗留。<br>　　SO_OOBINLINE BOOL 在常规数据流中接收带外数据。<br>　　SO_RCVBUF int 为接收确定缓冲区大小。<br>　　SO_REUSEADDR BOOL 允许套接口和一个已在使用中的地址捆绑（参见bind()）。<br>　　SO_SNDBUF int 指定发送缓冲区大小。<br>　　TCP_NODELAY BOOL 禁止发送合并的Nagle算法。<br>　　setsockopt()不支持的BSD选项有：<br>　　选项名 类型 意义<br>　　SO_ACCEPTCONN BOOL 套接口在监听。<br>　　SO_ERROR int 获取错误状态并清除。<br>　　SO_RCVLOWAT int 接收低级水印。<br>　　SO_RCVTIMEO int 接收超时。<br>　　SO_SNDLOWAT int 发送低级水印。<br>　　SO_SNDTIMEO int 发送超时。<br>　　SO_TYPE int 套接口类型。<br>　　IP_OPTIONS 在IP头中设置选项。<br>　　返回值：<br>　　若无错误发生，setsockopt()返回0。否则的话，返回SOCKET_ERROR错误，应用程序可通过WSAGetLastError()获取相应错误代码。<br>　　错误代码：<br>　　WSANOTINITIALISED：在使用此API之前应首先成功地调用WSAStartup()。<br>　　WSAENETDOWN：WINDOWS套接口实现检测到网络子系统失效。<br>　　WSAEFAULT：optval不是进程地址空间中的一个有效部分。<br>　　WSAEINPROGRESS：一个阻塞的WINDOWS套接口调用正在运行中。<br>　　WSAEINVAL：level值非法，或optval中的信息非法。<br>　　WSAENETRESET：当SO_KEEPALIVE设置后连接超时。<br>　　WSAENOPROTOOPT：未知或不支持选项。其中，SOCK_STREAM类型的套接口不支持SO_BROADCAST选项，SOCK_DGRAM类型的套接口不支持SO_DONTLINGER 、SO_KEEPALIVE、SO_LINGER和SO_OOBINLINE选项。<br>　　WSAENOTCONN：当设置SO_KEEPALIVE后连接被复位。<br>　　WSAENOTSOCK：描述字不是一个套接口。<br> <!--v:3.2--> ]]></description>
<category><![CDATA[学习]]></category>
<author><![CDATA[289367588@qq.com(surpercore)]]></author>
<comments>http://289367588.qzone.qq.com/blog/1236913448#comment</comments>
<qz:effect>134217728</qz:effect>
<pubDate>Fri, 13 Mar 2009 03:04:08 GMT</pubDate>
<guid>http://289367588.qzone.qq.com/blog/1236913448</guid>
</item>

<item>
<title><![CDATA[一些算法研究]]></title>
<link>http://289367588.qzone.qq.com/blog/1235322860</link>
<description><![CDATA[<span style="font-size:13px;line-height:1.8em;">1、大数阶乘 </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">   相信大家有遇到过计算大数阶乘时，使用一般数据类型出现数据溢出的情况。比如计算1000！=？此题的计算结果用十进制大概有3000位。试问有哪种数据类型能有3000位了？ </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">   既然一般的数据类型无法满足位数要求，我们自然会想到用数组来表示各位数。具体步骤如下：</span><wbr /><br><span style="font-size:13px;line-height:1.8em;">一、先计算需要数组大概位数，上面计算了1000！需要3000位，于是创建一个数组并初始化，int_fac[3000]={1，}；因在阶乘的过程中产生了进位，所以同样需建立一个数组并初始化，int_add[3000]={0，}；设置最高位 int top=0; </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">二、抽象阶乘过程。 </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">   6！=5！*6。 </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">   5！=120 ，用数组来表示: </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">   int_fac[0]=0; </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">   int_fac[1]=2; </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">   int_fac[2]=1; </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">   6!-&gt; </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">   int_fac[0]=0*6; <span style="text-decoration:underline;"><wbr />// 0位的数字不需要加前一数组的进位，即其值为：int_fac[0]*6%10；进位数组为int_fac[0]*6/10。</span><wbr /> </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">   int_fac[1]=2*6; <span style="text-decoration:underline;"><wbr />//这里结果为(2*6+int_add[0])%10，其商进位到int_add[1]=(2*6+int_add[0])/10 。</span><wbr /> </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">   int_fac[2]=1*6+1 <span style="text-decoration:underline;"><wbr />//int_fac[2]=(int_fac[2]*6+int_add[1])%10  int_add[2]=(int_fac[2]*6+int_add[1])/10</span><wbr /> </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">经过上面的过程分析，可以抽象到如下三个过程； </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">  1、为最低位做的运算和进位 </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">    add[0]=fac[0]*i/10;   </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">    fac[0]=fac[0]*i%10; </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">  2、为其他位做的运算和进位 </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">    for(int j=1;j&lt;top+1;j++) </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">     { </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">      add[j]=(fac[j]*i+add[j-1])/10; </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">      fac[j]=(fac[j]*i+add[j-1])%10; </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">     } </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">  3、由最高位向上进位的操作 </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">    while(add[top]&gt;0) </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">     { </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">      top++; </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">      add[top]=add[top-1]/10; </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">      fac[top]=add[top-1]%10; </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">     } </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">三、逐一输出数组 </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">    for(int n=top;n&gt;=0;n--) </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">    { </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">     printf(&quot;%d&quot;,fac[n]); </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">    } </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">四、调试代码 </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">int fac[3000]={1,}; </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">int add[3000]={0,}; </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">int top=0; </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">int number; </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">    printf(&quot;求N的阶乘,请输入一数字N!&quot;); </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">    scanf(&quot;%d&quot;,&amp;number); </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">       for(int i=1;i&lt;number+1;i++) </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">    { </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">     add[0]=fac[0]*i/10; </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">     fac[0]=fac[0]*i%10; </span><wbr /><br><br><span style="font-size:13px;line-height:1.8em;">     for(int j=1;j&lt;top+1;j++) </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">     { </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">      add[j]=(fac[j]*i+add[j-1])/10; </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">      fac[j]=(fac[j]*i+add[j-1])%10; </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">     } </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">     while(add[top]&gt;0) </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">     { </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">      top++; </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">      add[top]=add[top-1]/10; </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">      fac[top]=add[top-1]%10; </span><wbr /><br><br><span style="font-size:13px;line-height:1.8em;">     } </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">    } </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">    for(int n=top;n&gt;=0;n--) </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">    { </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">     printf(&quot;%d&quot;,fac[n]); </span><wbr /><br><span style="font-size:13px;line-height:1.8em;">    } </span><wbr /> <!--v:3.2--> ]]></description>
<category><![CDATA[学习]]></category>
<author><![CDATA[289367588@qq.com(surpercore)]]></author>
<comments>http://289367588.qzone.qq.com/blog/1235322860#comment</comments>
<qz:effect>134218240</qz:effect>
<pubDate>Sun, 22 Feb 2009 17:14:20 GMT</pubDate>
<guid>http://289367588.qzone.qq.com/blog/1235322860</guid>
</item>

<item>
<title><![CDATA[谈我对攻读计算机研究生的看法(转)]]></title>
<link>http://289367588.qzone.qq.com/blog/1234280319</link>
<description><![CDATA[原文出处：『IT视界』[大话IT] 谈谈我对攻读计算机研究生的看法<br><br>回复CSDN和KAOYAN诸位网友的几点看法，（为避免吵架，郑重声明，本人不是高手，只是有感而发的一点个人陋见，欢迎指正，事先感谢）：<br>　　就我自己的理解，谈谈我对读研和软件学院的看法，不妥之处一笑了之即可。<br>　　如果你有实际开发工作经验，感觉自己的水平和实力进入了一个高原期，迫切需要从理论上提高，那么计算机学院是唯一选择。因为计算机学院才能让你在理论上更上一层楼。软件学院从教学计划上就没有把你往这方面带。当然能不能更上一层楼最终还是完全取决于你自己。需要特别说明的是，工作经验并不一定等于开发经验，我见过很多工作2-3年的人，但是没有一点开发经验。<br>　　你说：“他们都有很强的开发能力,只是不太喜欢读书,也只是希望混个学历对今后在岗位上晋升有好处”，我可以向你保证，你所说的人绝对不是开发能力很强的人。因为，1）高手不可能不喜欢读书；2）高手不可能想去混一个学历；3）高手不可能认为晋升是因为学历的原因。<br>　　还需要说明的是，考计算机的人未必个个都是高手，严格来说，大部分都不会编程序。也就是说，庸庸碌碌之辈仍然占绝大多数。研究生毕业的师兄只拿2500元左右的比比皆是，所以不要寄希望于拿一张研究生文凭出去赚高薪。但是，对于有实际开发工作经验的人，要想自己在3年之中有一个真正的提高的话，计算机学院提供了广阔的平台。就我所知，每一个月拿2万以上的也有（上海育碧，图形特效算法设计）。所以，同为研究生毕业，能力的差距是极大的。所以，不要去问“研究生毕业能拿多少？”，要问“像我这种水平的人，研究生毕业能拿多少钱？”这样人家才能够准确地回答你。<br>　　所谓“有实际开发工作经验”是指你目前已经具备下列能力：1）你已经认为C++和汇编语言都是很简单的语言，并能够自如地运用；2）你能够在30分钟之内想到正确的五子棋AI算法设计思路和方向；3）你完全理解STL为什么这么重要；4）你能够独立地解决所有的编译与链接问题，哪怕你从来没有遇到的问题，你也不需要询问任何人；5）英文网站是你的首要信息来源；6）能够读懂英语写成的国际标准，比如NTFS磁盘格式标准。7）你经常站在集合论的角度思考算法问题；8）能够理解一个简单的驱动程序，能够理解一个简单3D交互程序；9）你能够认识到线性代数和概率论在实际编程工作中的极端重要性；10）你完全理解COM的设计思想，尤其能够理解COM为什么要设计成这样；11）当我说到虚函数的重要作用时，你不会急着去找书来翻；12）你能够说出C++为什么比其他语言优秀的理由，记住这种理由应该来自于你的开发体会，而不是因为其他人都这么说。此外还有很多判断标准，但如果你同时具备5条以上，可以认为你已经具备相应的开发经验了。在这种状态下读研，你将取得读研效益的最大值。<br>　　读研最重要的是要明白你自己要干什么，不能等导师来告诉你你应该干什么。研究生的优势在于理论功底深厚，思维具有穿透力，当然编程能力首先要过关，不要读完研究生还不知道MFC程序的WinMain函数在哪里。所以，研究生期间，你一定要做有理论深度的算法设计，比如大规模数据的搜索算法，性能是首要考虑因素，不要奢望SQL函数能够帮你解决问题，所有的问题你都必须自己解决，你必须解决内外存交换的性能瓶颈。再比如极品飞车的3D场景生成，图形变换，碰撞检测，物性模拟，纹理映射，灯光模型等等，这些都是可以保证你能拿到2万以上月薪的技术。如果你认为这些东西太难，不可能做得出来的话，那么你就不适合读研。真的，要是你认为读研之后还是要去搞一般的程序设计，如信息管理系统之类的软件，那么你读研的价值就完全不会得到体现，因为这些工作根本就不需要读研。<br>　　软件学院宣称培养软件开发人才，恕我直言，我从来没有看见那个高手是培训成功的。成为软件开发高手的路只有一条：自学！软件开发中需要大量的编程实践和独立思考，只有在此过程中，你才能够逐步成长起来。软件学院宣称培养软件项目经理，这更是搞笑，在某种意义上这是欺骗行为。学院里面能够培养出软件开发经理更是十足的谎言，软件项目经理必须，或者说更强调从战争中学会战争。没有实践经验的项目经理就是绣花枕头一个。<br>　　实话实说，软件学院就是一个蒙钱的机构，公关工作做得很好，善于打广告，而且都是打着高薪的幌子，就如同外面的什么北大青鸟培训班一样。两个字：蒙钱！四个字：还是蒙钱！<br>　　总之一句话，如果你只想成为软件开发高手（比如认为会编驱动程序或杀毒软件就是高手的那种），建议工作，不要考研；完全没有工作经验的，也不建议考研，你进来了只有瞎混一通。如果你有上述工作经验且想成为高级软件工程师（能够独立理解并设计出快速傅立叶变换算法的那种软件工程师）的话，那么强烈建议考研。考研让你有3年放松思考的机会，也有3年让你思想和技术积累沉淀的机会。非常难得的机会。不考研的话，这种机会就是一种奢侈，可望而不可即的那么一种奢侈。<br>　　所以，不管你是哪一种情况，都不建议考软件学院。除非你是女生，把能够成为一个研究生当着一生最大满足的那种女生。<br>　　1）关于读书的机会成本问题。读研的机会成本的确是很高。任何人都可以简单地计算出来。所以，我也不赞成所有的人都去读研。读研只适合那些痛感数学在编程中的极端重要性的人。如果对理论工具和理论思维的极端重要性没有切肤的认识，那么读研的价值几乎为0；读研的好处在于：A，把你自己放在一个学术和工程的交叉点上；B，让你具备了进入微软等世界顶级软件研发机构的可能性；记住只是可能性。但是不读研这种可能性为0；C，如前所述，如果没有读研的机会，你也就没有静下心来好好钻研几年理论的机会；一边工作拿高薪，一边深入地学习各种理论，诸位认为这可能吗？我反正认为不可能，我觉得学习钻研理论最需要的就是一个长期安静独处的环境，一边工作一边读书是不可能有这样的环境的，你会觉得每天都在疲于奔命。而读研正好可以提供这样一个环境。我同时还反对整天跟着导师的屁股后面跑，这样会浪费很多时间。读计算机的研究生，主要依靠自己去查阅最新文献，自己去研读文献，和导师的口头交流一个月一次就足够了，前提还需要导师的水平足够牛。如果导师的水平不牛，这也没关系，不理他就是了，自己做好自己的事情即可。<br>　　2）关于研究生教学质量问题。坦白地说，全国都是“洪桐县中无好人”，尤其在计算科学领域，大牛极少。那为什么还要去读研？大哉问！把读研的收获寄托在名校或名师的名我认为气上，是注定要失败的。读研全靠自学，研究生之间的差距全部体现在自学能力上面。又有人问，既然是自学，为什么非要读研？回答是：因为读研就是为你买一份保险，就是买一份你自学三年之后不会失业的保险。这份保险主要是一种心理上的后盾，让你在自学过程中经得起诱惑，能够从容镇定地去追寻计算机理论发展的坚实足迹，从欧拉，费马，高斯，康托，图灵等巨匠那里寻找方法论的珠宝。倘若没有这份保证，你在家里面自学3个月，保证你会被失业的压力压得喘不过气来，何谈安心学习？<br>　　3）关于实战经验与理论学习的优劣问题。这没有定论，如前所述，管理信息系统，设备驱动开发，工具软件开发，软件病毒剖析等等这些工作不太需要创造性，需要的是耐心和经验，需要的是对既有规范的准确理解，这类开发工作最适合在实战中提高，理论学习没什么作用。但是在人工智能，模式识别，图像压缩，虚拟现实，巨量数据检索，自然语言理解，计算机图形学等等领域，理论学习就占据着绝对的统治地位！这些领域的突破对人类的生活的影响是极其巨大而深刻的。某些领域处于一个极其快速发展的态势之中，比如计算机图形学，相信诸君能够从众多3D游戏的灿烂辉煌中体认到我的这种说法。在这些领域，如果没有扎实的理论功底，一切都是那么遥远，不管你花了多少时间在编程上面。<br>　　4）关于高级研发人员的知识结构问题。首先声明，我不是一个纯粹理论激进分子，即认为除了理论之外，一切都不重要。我认为，纯熟的编程技能是最基本但也是最必不可少的技能。没有这个基础，一切计算机理论就是空谈（研究图灵可计算性理论的研究者除外）。有了这个基础之后，下列理论学习方向必须重点突破：<br>　　1，科学哲学。这是核心中的核心！可惜国内不开这门课。不但不开课，而且还作为批判对象来引用，实在是遗憾至极！这是一门教你如何“钓鱼”的学科，在一切科学研究中居于最核心的地位。它是古今科研方法和思维方法的集大成者，很难想象一个成熟的研究者没有一套自己的方法论体系。科学哲学最需要的是领会与总结，它的思想与启示会伴随我们的一生。<br>　　2，康托集合论，矩阵方法，离散结构，图论方法，群论方法之间的紧密关系。最重要的认识这些理论对实践的重要启示和方法引导。我始终认为，如果你学了一门理论之后，却不知道这门理论有什么作用，那么你的理论就白学了，你什么东西都没有捞着。所以，学习任何理论之前，先问自己：它有什么用？在哪里用？如何用？带着这些问题去学习理论，你才会真正地学到东西。用这三个问题去问你的理论课老师，他的回答就是判断其实际水平的最佳标准。<br>　　3，思维要有极强的穿透力，学会看透文献作者没有写出来的动机。绝大部分大师都有隐瞒自己最具有方法论启示意义的思考环节的习惯。牛顿和华罗庚先生都有这个坏习惯。这让大家认为他们是天才，因为很多问题他想到了，我们想不到。但是为什么他们能想到，我们想不到？他们是怎样想到的？没有人告诉我们牛顿发现万有引力定律时的思考过程，当然，牛顿可以慷慨地把他的思考结果告诉我们，但是，他那可以点石成金的“金手指”却没有教给我们。我们的任务就是要培养透过文章看穿作者背后意图和动机的能力，在这方面，台湾的侯捷和美国的Donbox是绝佳典范。这两只老狐狸（呵呵，是爱称）凭着其猎犬一般的嗅觉，抽丝剥茧，一个把COM背后的幕后设计动机揭开并暴露到了光天化日之下，另一个把MFC的宏观架构做了一次完美的外科手术。其非凡的思维穿透力令人惊叹。<br>　　4，英语。英语本身不重要，但是用英语写成的文献就极其重要了。所以，专门把英语作为一个重头戏列出来。大家不要相信英语无用论的鬼话。对于搞计算机的而言，英语就是你的母语！<br>　　5，其它的具体理论还有很多，但是都不如这三个方面重要，因为我觉得这三个方面是最具有根本性，全局性的能力培养环节。需要指出的是，很多高深理论对你的工作是无意义的，当心时间陷进去。一定要把效率最高的时间段用在最具有决定性意义的理论学习上。<br>　　5）关于读研之后的出路是否光明的问题。我们应该承认，读研之后，你的工作机会不是变多了，而是变少了。而且越是高手，他的工作机会和工作范围就越少。这是因为，越是搞前沿研发的公司，其数量越少，在这个圈子的人也就越少。你找工作的范围就越小，试问：如果微软的OS设计专家出来找工作，能够让他选择的公司能有几家？但是，这种公司数量的减少是以工资待遇的急剧上升为补偿的，同时，你在工作中所受到的充分尊重也是在一般公司中体会不到的。所以不要担心学了高科技用不上，呵呵，你只会越来越感觉自己学的不够用。相信接到过猎头公司电话的人会体会得到。真正的高手从来就不会担心工作的问题，也从来不会到人才市场上去找工作。既然选择了理论深入，那么就应该把眼光放得更远。<br> <!--v:3.2--> ]]></description>
<category><![CDATA[杂谈]]></category>
<author><![CDATA[289367588@qq.com(surpercore)]]></author>
<comments>http://289367588.qzone.qq.com/blog/1234280319#comment</comments>
<qz:effect>134217728</qz:effect>
<pubDate>Tue, 10 Feb 2009 15:38:39 GMT</pubDate>
<guid>http://289367588.qzone.qq.com/blog/1234280319</guid>
</item>

<item>
<title><![CDATA[ADO的智能指针]]></title>
<link>http://289367588.qzone.qq.com/blog/1234075208</link>
<description><![CDATA[_ConnectionPtr接口返回一个记录集或一个空指针。通常使用它来创建一个数据连接或执行一条不返回任何结果的SQL语句，如一个存储过程。使用 _ConnectionPtr接口返回一个记录集不是一个好的使用方法。对于要返回记录的操作通常用_RecordserPtr来实现。而用 _ConnectionPtr操作时要想得到记录条数得遍历所有记录，而用_RecordserPtr时不需要。<br>    _CommandPtr接口返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。在使用_CommandPtr接口时，你可以利用全局 _ConnectionPtr接口，也可以在_CommandPtr接口里直接使用连接串。如果你只执行一次或几次数据访问操作，后者是比较好的选择。但如果你要频繁访问数据库，并要返回很多记录集，那么，你应该使用全局_ConnectionPtr接口创建一个数据连接，然后使用_CommandPtr 接口执行存储过程和SQL语句。<br>    _RecordsetPtr是一个记录集对象。与以上两种对象相比，它对记录集提供了更多的控制功能，如记录锁定，游标控制等。同_CommandPtr接口一样，它不一定要使用一个已经创建的数据连接，可以用一个连接串代替连接指针赋给 _RecordsetPtr的connection成员变量，让它自己创建数据连接。如果你要使用多个记录集，最好的方法是同Command对象一样使用已经创建了数据连接的全局_ConnectionPtr接口，然后使用_RecordsetPtr执行存储过程和SQL语句。<br> <!--v:3.2--> ]]></description>
<category><![CDATA[学习]]></category>
<author><![CDATA[289367588@qq.com(surpercore)]]></author>
<comments>http://289367588.qzone.qq.com/blog/1234075208#comment</comments>
<qz:effect>134217728</qz:effect>
<pubDate>Sun, 08 Feb 2009 06:40:08 GMT</pubDate>
<guid>http://289367588.qzone.qq.com/blog/1234075208</guid>
</item>

<item>
<title><![CDATA[盖茨乔布斯远去+互联网英雄时代谢幕]]></title>
<link>http://289367588.qzone.qq.com/blog/1232206962</link>
<description><![CDATA[导语：国外媒体日前撰文称，史蒂夫·乔布斯(Steve Jobs)正在淡出苹果的舞台——或许一去不返——标志着从上世界六十年代激进嬉皮士运动发端的一个互联网时代的终结。自与他齐名的竞争对手比尔·盖茨 (Bill Gates)从微软退休转向慈善事业7个月后，乔布斯也将因健康原因退居幕后。 <br><br>　　英雄落幕 <br><br>　　曾改变了当代文化的盖茨和乔布斯，被PC支持者和Mac拥趸奉为各自阵营的领袖。在咖啡馆及其他硅谷社交场合，关于各自阵营技术孰优孰劣的激烈争论不绝于耳，双方各执一词，互不相让。PC支持者最常引用的事实是，全球超过90%的电脑运行着微软的操作系统，这令狂热的苹果迷感到挫败。两大敌对技术都拥有各自争议性的代表人物：PC领域是盖茨，而乔布斯则代表了苹果阵营。 <br><br>　　互联网先锋雅虎的创始人杨致远本周将帅印移交给了新任CEO卡罗尔·巴茨(Carol Bartz)，淡出了雅虎的历史舞台。硅谷Enderle Group公司分析师罗勃·恩德利(Rob Enderle)表示：“在许多方面，我们正在远离那个领袖人物塑造公司的时代”，“有人可能要说‘谷歌小子’怎么样，但它们的创始人真的是偶像人物吗？我认为不是。我们似乎在远离那个灵魂人物打造一个公司的时代。” <br><br>　　具有讽刺意味的是，就在谷歌和其他互联网公司的超级明星利用数百万用户的隐私谋取广告利润时，这些公司的创始人们却在不遗余力地保护自己的隐私。恩德利说：“从很多方面看，在这个明星倍出、品牌不断更迭的时代，网络公司正在丧失自己的个性。” <br><br>　　彼得·弗瑞斯(Peter Friess)是一家位于硅谷中心的创新科技博物馆的馆长兼历史学家。他认为，同样出生于1955年的乔布斯和盖茨都成长在崇尚叛逆精神的上世纪60年代，因此身上也打上了那个时代的烙印。二人都为了追逐一个为大众生产电脑的梦想而从大学辍学。而乔布斯在与友人斯蒂夫·沃兹尼亚克(Steve Wozniak)制造出首台苹果电脑前，就别出心裁地发明了一个叫“蓝匣子”的设备，用于盗打长途电话。 <br><br>　　时势造人 <br><br>　　“他们成长在一个文化对大众至关重要的时代。”弗瑞斯说，“那是一个革命性时代。时势造人。如今，谷歌、Facebook等网络公司在随波逐流方面走得更远。社交网站并不能像乔布斯或者盖茨那样改变世界。” <br><br>　　将个人电脑推向大众正符合了那个年代嬉皮士们“将权利归于人民”(Power to the people)的理想。盖茨和乔布斯在互联网诞生之前就卖出了第一批PC和Mac，随后他们又领导各自的公司在互联网时代走向辉煌。 <br><br>　　加州大学伯克利分校信息学院助教克罗伊·切西尔(Coye Cheshire)认为，“随着时间的推移，我想有一天我们也会以同样的方式回顾搜索巨头的领导人，但我感觉这不是一个重量级的比较”，“只有我们拥有了PC、Mac、iPod、Xbox、Zune、iPhone(手机上网)等等后，这些了不起的信息服务才能变得实用并真正造福社会。” <br><br>　　切西尔认为，全球气候变暖及大国的石油争夺战为在可更新能源领域，类似盖茨和乔布斯的偶像人物的出现提供了一个大舞台，“在大众中推广PC确实将权利放到了人民手中”，“我期待在可更新能源领域，将出现像电脑产业的乔布斯一样有远见的领袖人物。” <br><br>　　2年前，乔布斯和盖茨难得一见地联袂出席了加州召开的“All Things Digital”大会。他们开玩笑说，外界关于他们敌视的传言并不准确，乔布斯风趣地说：“我们已秘密结婚了10多年。”引发在场听众哄堂大笑。 <br><br>　　“没有人愿意死去……但死亡是我们共同的终点。”乔布斯2005年在斯坦福大学开学典礼上对满场的学生们说，“<span style="filter: glow(color=#996600,strength=3);color:#FFFFFF;display:inline-block;line-height:1.8em;">死亡也许是生命中最了不起的发明，因为它送走耋耄老者，给新生代让路</span><wbr />。”(肖恩) <br><br>读后感：正如steve jobs对学生们说的话一样，作为新生代的一辈，要从父母的手中接过接力棒．向&quot;jobs们&quot;致敬！ <!--v:3.2--> ]]></description>
<category><![CDATA[学习]]></category>
<author><![CDATA[289367588@qq.com(surpercore)]]></author>
<comments>http://289367588.qzone.qq.com/blog/1232206962#comment</comments>
<qz:effect>134218240</qz:effect>
<pubDate>Sat, 17 Jan 2009 15:42:42 GMT</pubDate>
<guid>http://289367588.qzone.qq.com/blog/1232206962</guid>
</item>

<item>
<title><![CDATA[windows 消息函数探讨]]></title>
<link>http://289367588.qzone.qq.com/blog/1231779594</link>
<description><![CDATA[PreTranslateMessage的理解: <br>    PreTranslateMessage只能处理消息队列中的消息,也就是由PostMessage发出的消息/鼠标键盘消息等. <br>    SendMessage发送的消息并不放在消息队列中,而是直接调用处理函数进行处理,所以这种消息用PreTranslateMessage的捕获不到的,如WM_KIllFOCUS和WM_SETFOCUS. <br>    SendMessage的消息是直接执行处理函数的,它要等消息执行完才返回(执行完SendMessage函数);而PostMessage则把消息发送后立即返回,把消息挂到消息队列中等待执行. <br>    GetCurrentMessage　获得当前消息的消息信息。 <br>　　SendNotifyMessage　如果是本线程创建的窗口　那么相当与sendMessage,其它线程创建的窗口，大致相当与postmessage，但是优先级可能比postmessage高，这个不是很确定。 <br>　　GetMessage和PeekMessage都是从队列中取一条消息。 <br>如果消息队列中没有消息，PeekMessage立刻返回0；否则返回非0； <br>GetMessage：如果消息队列有消息，它也返回非0；但当消息队列为空时，它不立刻返回0，而是线程挂在这里，一直等到有消息到来，才返回非0。 <br>    TranslateMessage是用来把虚拟键消息转换为字符消息。由于Windows对所有键盘编码都是采用虚拟键的定义，这样当按键按下时，并不得字符消息，需要键盘映射转换为字符的消息。TranslateMessage函数用于将虚拟键消息转换为字符消息。字符消息被投递到调用线程的消息队列中，当下一次调用GetMessage函数时被取出。当我们敲击键盘上的某个字符键时，系统将产生WM_KEYDOWN和WM_KEYUP消息。这两个消息的附加参数（wParam和lParam）包含的是虚拟键代码和扫描码等信息，而我们在程序中往往需要得到某个字符的ASCII码，TranslateMessage这个函数就可以将WM_KEYDOWN和WM_ KEYUP消息的组合转换为一条WM_CHAR消息（该消息的wParam附加参数包含了字符的ASCII码），并将转换后的新消息投递到调用线程的消息队列中。注意，TranslateMessage函数并不会修改原有的消息，它只是产生新的消息并投递到消息队列中。也就是说TranslateMessage会发现消息里是否有字符键的消息，如果有字符键的消息，就会产生WM_CHAR消息，如果没有就会产生什么消息 <br>   DispatchMessage函数，它的意思就是说要把这条消息发送到窗口里的消息处理函数WindowProc。 <br><div style="text-align:center;"><span style="font-weight:bold"><wbr />DRAWITEMSTRUCT</span><wbr /><span style="font-weight:bold"><wbr />结构中各域的详解</span><wbr /></div><div style="text-align:center;">typedef   struct   tagdrawitemstruct   {   </div>  uint       ctltype; //   <br>  uint       ctlid; //   <br>  uint       itemid; //   <br>  uint       itemaction; //   <br>  uint       itemstate; //   <br>  hwnd       hwnditem; //   <br>  hdc     hdc; //   <br>  rect       rcitem; //   <br>  dword     itemdata; //   <br>  }   drawitemstruct;   <br>   <br>  ctltype&lt;----------------------------------   <br>  odt_button       owner-drawn   button   <br>  odt_combobox       owner-drawn   combo   box   <br>  odt_listbox       owner-drawn   list   box   <br>  odt_menu       owner-drawn   menu   <br>  odt_listview       list   view   control   <br>  odt_static       owner-drawn   static   control   <br>  odt_tab       tab   control     <br>     <br>  itemaction&lt;-------------------------------   <br>  oda_drawentire   <br>  oda_focus   <br>  oda_select   <br>     <br>  itemstate&lt;--------------------------------   <br>  ods_checked   <br>  ods_disabled   <br>  ods_focus   <br>  ods_grayed   <br>  ods_selected   <br>  ods_comboboxedit   <br>  ods_default   <br>   <br>typedef   struct   tagdrawitemstruct   {   <br>  uint       ctltype;//控件类型   <br>  uint       ctlid;      //控件id   <br>  uint       itemid;  //菜单项、列表框或组合框中某一项的索引值   <br>  uint       itemaction;//控件行为   <br>  uint       itemstate;    //控件状态   <br>  hwnd       hwnditem;    //父窗口句柄或菜单句柄   <br>  hdc     hdc;//控件对应的绘图设备句柄   <br>  rect       rcitem;  //控件所占据的矩形区域   <br>  dword     itemdata;      //列表框或组合框中某一项的值   <br>  }   drawitemstruct,   *pdrawitemstruct,   *lpdrawitemstruct;   <br>  下面详细解释各个变量或机构的含义：   <br>     <br>  drawitemstruct结构文档   <br>     <br>  drawitemstruct   <br>     <br>  drawitemstruct   为需要自绘的控件或者菜单项提供了必要的信息。在需要绘制的控件或者菜单项对应的wm_drawitem消息函数中得到一个指向该结构的指针。   drawitemstruct结构的定义如下：   <br>  typedef   struct   tagdrawitemstruct   {   <br>  uint   ctltype;   <br>  uint   ctlid;   <br>  uint   itemid;   <br>  uint   itemaction;   <br>  uint   itemstate;   <br>  hwnd   hwnditem;   <br>  hdc   hdc;   <br>  rect   rcitem;   <br>  ulong_ptr   itemdata;   <br>  }drawitemstruct;   <br>     <br>  结构成员：   <br>     <br>  ctltype   <br>  指定了控件的类型，其取值如下表所示。   <br>     <br>  取值   <br>  描述   <br>     <br>  odt_button   <br>  按钮控件   <br>     <br>  odt_combobox   <br>  组合框控件   <br>     <br>  odt_listbox   <br>  列表框控件   <br>     <br>  odt_listview   <br>  列表视图控件   <br>     <br>  odt_menu   <br>  菜单项   <br>     <br>  odt_static   <br>  静态文本控件   <br>     <br>  odt_tab   <br>  tab控件   <br>     <br>  ctlid   <br>     <br>  指定了自绘控件的id值，而对于菜单项则不需要使用该成员   <br>     <br>  itemid   <br>  表示菜单项id，也可以表示列表框或者组合框中某项的索引值。对于一个空的列表框或组合框，该成员的值为–1。这时应用程序只绘制焦点矩形虽然此时控件中没有需要显示的项，但是绘制焦点矩形还是很有必要的，因为这样做能够提示用户该控件是否具有输入焦点。当然也可以设置itemaction   成员为合适值，使得无需绘制焦点。   <br>     <br>  itemaction   <br>  指定绘制行为，其取值可以为下表中所示值的一个或者多个的联合。   <br>     <br>  取值   <br>  描述   <br>     <br>  oda_drawentire   <br>  当整个控件都需要被绘制时，设置该值   <br>     <br>  oda_focus   <br>  如果控件需要在获得或失去焦点时被绘制，则设置该值。此时应该检查itemstate成员，以确定控件是否具有输入焦点。   <br>     <br>  oda_select   <br>  如果控件需要在选中状态改变时被绘制，则设置该值。此时应该检查itemstate   成员，以确定控件是否处于选中状态。   <br>     <br>     <br>  itemstate   <br>  指定了当前绘制操作完成后，所绘项的可见状态。例如，如果菜单项应该被灰色显示，则可以指定ods_grayed状态标志。其取值可以为下表中所示值的一个或者多个的联合。   <br>     <br>  取值   <br>  描述   <br>     <br>  ods_checked   <br>  如果菜单项将被选中，则可设置该值。该值只对菜单项有用。   <br>     <br>  ods_comboboxedit   <br>  在自绘组合框控件中只绘制选择区域。   <br>     <br>  ods_default   <br>  默认值。   <br>     <br>  ods_disabled   <br>  如果控件将被禁止，则设置该值。   <br>     <br>  ods_focus   <br>  如果控件需要输入焦点，则设置该值。   <br>     <br>  ods_grayed   <br>  如果控件需要被灰色显示，则设置该值。该值只在绘制菜单时使用。   <br>     <br>  ods_hotlight   <br>  windows   98/me,   windows   2000/xp:   如果鼠标指针位于控件之上，则设置该值，这时控件会显示高亮颜色。   <br>     <br>  ods_inactive   <br>  windows   98/me,   windows   2000/xp:   表示没有激活的菜单项。   <br>     <br>  ods_noaccel   <br>  windows   2000/xp:   控件是否有快速键盘。   <br>     <br>  ods_nofocusrect   <br>  windows   2000/xp:   不绘制捕获焦点的效果。   <br>     <br>  ods_selected   <br>  选中的菜单项。   <br>     <br>  hwnditem   <br>  指定了组合框、列表框和按钮等自绘控件的窗口句柄；如果自绘的对象时菜单项，则表示包含该菜单项的菜单句柄。   <br>     <br>  hdc   <br>  指定了绘制操作所使用的设备环境。   <br>     <br>  rcitem   <br>  指定了将被绘制的矩形区域。这个矩形区域就是上面hdc的作用范围。系统会自动裁剪组合框、列表框或按钮等控件的自绘制区域以外的部分。也就是说rcitem中的坐标点指的就是控件的左上角。但是系统不裁剪菜单项，所以在绘制菜单项的时候，必须先通过一定的换算得到该菜单项的位置，以保证绘制操作在我们希望的区域中进行。   <br>     <br>  itemdata   <br>  对于菜单项，该成员的取值可以是由   <br>     <br>  cmenu::appendmenu、   <br>  cmenu::insertmenu或者   <br>  cmenu::modifymenu   <br>     <br>  等函数传递给菜单的值。   <br>     <br>  对于列表框或这组合框，该成员的值可以为由   <br>     <br>  combobox::addstring、   <br>  ccombobox::insertstring、   <br>  clistbox::addstring或者   <br>  clistbox::insertstring   <br>     <br>  等传递给控件的值。   <br>     <br>  如果ctltype   的取值是odt_button或者odt_static,   itemdata的取值为0。<br><br><span style="font-family:'Times';line-height:1.8em;">DWORD =Double Word   Word=2</span><wbr />字节 <br>以下是转载。 <br>NMHDR   =   Notify   Message   Handler <br>NMHDR   结构包含下列成员：   <br>  typedef   struct   tagNMHDR   {   <br>  HWND   hwndFrom;     //   handle   of   control   sending   message   <br>  UINT   idFrom;//   identifier   of   control   sending   message   <br>  UINT   code;     //   notification   code;   see   below   <br>  }   NMHDR;   <br>   <br>  消息通过下面的宏定义之：   <br>  ON_NOTIFY(   wNotifyCode,   idControl,   memberFxn   )   <br>  wNotifyCode     <br>  通知消息标识符代码，如   TBN_BEGINADJUST。     <br>  idControl     <br>  发送通知的控件的标识符。     <br>  memberFxn     <br>  接收到通知时调用的成员函数。     <br>   <br>  成员函数将用下列原型声明：   <br>  afx_msg   void   memberFxn(   NMHDR   *   pNotifyStruct,   LRESULT   *   result   );   <br><br>在WM_NOTIFY中，lParam中放的是一个称为NMHDR结构的指针。在wParam中放的则是控件的ID。   <br>   <br>          NMHDR结构是很值得一提的，该结构包括有关制作该通知的控件的任何内容，而不受空间和类型的限制，他的来历也是很有意思的。   <br>          在最初的windows3.x中，根本就不存在什么WM_NOTIFY，控件通知它们父窗口，如鼠标点击,控件背景绘制事件，通过发送一个消息到父窗口。简单的通知仅发送一个WM_COMMAND消息，包含一个通知码和一个在wParam中的控件ID及一个在lPraram中的控件句柄。这样一来，wParam和lParam就都被填充了，没有额外的空间来传递一些其它的消息，例如鼠标按下的位置和时间。   <br>          为了克服这个困难，windows3.x就提出了一个比较低级的解决策略，那就是给一些消息添加一些附加消息，最为明显的就是控件自画用到的DRAWITEMSTRUCT。不知道大家对这个结构熟悉不，不过，如果你是老手，你应该非常清楚这个结构，这个结构包含了9个内容，几乎你需要控制的信息都给你提供了。为什么说它比较低级呢？因为不同的消息附加的内容不同，结果就是一盘散沙，非常混乱。   <br>          在win32中，MS又提出了一个更好的解决方案：引进NMHDR结构。这个结构的引进就是消息统一起来，利用它可以传递复杂的信息。这个结构的布局如下：   <br>          NMHDR   <br>          {   <br>                  HWnd   hWndFrom   ;   相当于原WM_COMMAND传递方式的lParam   <br>                  UINT   idFrom   ;       相当于原WM_COMMAND传递方式的wParam（low-order）   <br>                  UINT   code   ;           相当于原WM_COMMAND传递方式的Notify   Code(wParam&quot;s   high-order)   <br>          }；   <br>          对于这个结构的应用于WM_NOTIFY信息结构，结果WM_NOTIFY就变成了：   <br>          A、无附加信息。结构变得很简单，就是一个NMHDR结构。   <br>          B、有附加信息。定义一个大的结构，它的第一个元素就是NMHDR结构，它的后面放置附加信息。 <br><br>举例://得到选中的列 <br>void   CMyView::OnColumnclick(NMHDR*   pNMHDR,   LRESULT*   pResult)     <br>  {         <br>  NM_LISTVIEW*   pNMListView   =   (NM_LISTVIEW*)pNMHDR;   <br>     <br>//得到选中的列       <br>  column=pNMListView-&gt;iSubItem;   <br>} <br>Sendmessage(this-m_hwnd, [url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_11wo.htm]CDM_GETFILEPATH[/url],1024,(lparam)(lpcstr)str</span><wbr />)通过此消息，可以获得打开与保存文件对话框的文件路径。顺藤摸瓜，把所有Ccommondialog的消息贴了出来，如下。Common Dialog Box MessagesThe following constants identify strings that you can use with the [url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/messques_10h1.htm]<span style="font-weight:bold"><wbr /><span style="color:#5e4830;line-height:1.8em;">RegisterWindowMessage</span><wbr /></span><wbr />[/url] function to get a message identifier. You can use these message identifiers to send messages to or receive messages from common dialog boxes. <br><br><br><br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_3d2f.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">COLOROKSTRING</span><wbr />[/url] <br><br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_74kn.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">FILEOKSTRING</span><wbr />[/url] <br><br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_1y07.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">FINDMSGSTRING</span><wbr />[/url] <br><br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_9d2f.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">HELPMSGSTRING</span><wbr />[/url] <br><br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_390n.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">LBSELCHSTRING</span><wbr />[/url] <br><br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_96jr.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">SETRGBSTRING</span><wbr />[/url] <br><br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_0tlz.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">SHAREVISTRING</span><wbr />[/url] <br><br><br>The following are messages you can send to a <span style="font-weight:bold"><wbr />Font</span><wbr /> dialog box. <br><br><br><br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_96d0.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">WM_CHOOSEFONT_GETLOGFONT</span><wbr />[/url] <br><br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_05kj.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">WM_CHOOSEFONT_SETFLAGS</span><wbr />[/url] <br><br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_8tmc.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">WM_CHOOSEFONT_SETLOGFONT</span><wbr />[/url] <br>The following are messages that a <span style="font-weight:bold"><wbr />Page Setup</span><wbr /> dialog box sends to an application-defined [url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_05nv.htm]<span style="font-weight:bold"><wbr /><span style="color:#5e4830;line-height:1.8em;">PagePaintHook</span><wbr /></span><wbr />[/url] hook procedure.<br><br><br> <br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_7z1w.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">WM_PSD_ENVSTAMPRECT</span><wbr />[/url]<br> <br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_1zck.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">WM_PSD_FULLPAGERECT</span><wbr />[/url]<br> <br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_0ypg.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">WM_PSD_GREEKTEXTRECT</span><wbr />[/url]<br> <br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_6k38.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">WM_PSD_MARGINRECT</span><wbr />[/url]<br> <br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_2vn8.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">WM_PSD_MINMARGINRECT</span><wbr />[/url]<br> <br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_38br.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">WM_PSD_PAGESETUPDLG</span><wbr />[/url]<br> <br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_7rg4.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">WM_PSD_YAFULLPAGERECT</span><wbr />[/url]<br> <br><br>The following are messages that a hook procedure can send to an Explorer-style <span style="font-weight:bold"><wbr />Open</span><wbr /> or <span style="font-weight:bold"><wbr />Save As</span><wbr /> dialog box. <br><br><br> <br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_11wo.htm]<span style="font-family:'Times';line-height:1.8em;">CDM_GETFILEPATH</span><wbr />[/url]</span><wbr /></span><wbr /></span><wbr /></span><wbr /><br>获得打开对话框的文件路径<br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_7jxw.htm]<span style="font-family:'Times';line-height:1.8em;">CDM_GETFOLDERIDLIST</span><wbr />[/url]<br> <br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_3srs.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">CDM_GETFOLDERPATH</span><wbr />[/url]<br> <br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_4nqb.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">CDM_GETSPEC</span><wbr />[/url]<br> <br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_28mk.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">CDM_HIDECONTROL</span><wbr />[/url]<br> <br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_4lf8.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">CDM_SETCONTROLTEXT</span><wbr />[/url]<br> <br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_7iwk.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">CDM_SETDEFEXT</span><wbr />[/url]<br> <br><br>The following are notification messages that an Explorer-style <span style="font-weight:bold"><wbr />Open</span><wbr /> or <span style="font-weight:bold"><wbr />Save As</span><wbr /> dialog box can send to a hook procedure. <br><br><br> <br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_4817.htm]<span style="font-family:'Times';line-height:1.8em;">CDN_FILEOK</span><wbr />[/url]<br> <br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_2xet.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">CDN_FOLDERCHANGE</span><wbr />[/url]<br> <br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_8okw.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">CDN_HELP</span><wbr />[/url]<br> <br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_3ihx.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">CDN_INITDONE</span><wbr />[/url]<br> <br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_4q05.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">CDN_SELCHANGE</span><wbr />[/url]<br> <br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_7wku.htm]<span style="font-family:'Times';line-height:1.8em;">CDN_SHAREVIOLATION</span><wbr />[/url]<br> <br>[url=mk:@MSITStore:D:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\winui.chm::/devdoc/live/pdui/commdlg3_4bs5.htm]<span style="color:#5e4830;font-family:'Times';line-height:1.8em;">CDN_TYPECHANGE</span><wbr />[/url]<br> <!--v:3.2--> ]]></description>
<category><![CDATA[个人日记]]></category>
<author><![CDATA[289367588@qq.com(surpercore)]]></author>
<comments>http://289367588.qzone.qq.com/blog/1231779594#comment</comments>
<qz:effect>134218240</qz:effect>
<pubDate>Mon, 12 Jan 2009 16:59:54 GMT</pubDate>
<guid>http://289367588.qzone.qq.com/blog/1231779594</guid>
</item>

</channel>
</rss>

