#
1. _WIN32_WINNT not defined. Defaulting to _WIN32_WINNT_MAXVER (see WinSDKVer.h)
原因:版本问题,VC6中队版本的定义过低
解决方案:在StdAfx.h头文件里面加上#include <SDKDDKVer.h>有关于平台的定义
2.
- 1.strtok和strtok_s
char* strtok(char* strToken, const char* strDelimit );
strToken:待处理的字符串
strDelimit:分隔符
- 第一次调用该函数时,第一个参数传入需要分解的字符串,之后第一个参数使用NULL表示继续处理之前传入字符串的剩下内容
- NULL参数表示调用strtok继续从string中上次调用 strtok时保存的位置开始标记化
- 注:该函数会改变传入的字符串
-
- 2.fopen和fopen_s
- FILE * fopen(const char * path,const char * mode);
-
errno_t fopen_s( FILE** pFile, const char *filename, const char *mode );
3.sscanf和sscanf_s
-
int sscanf(
const char *, const char *, ...);
int sscanf(const char *buffer,const char *format,[argument ]...);
buffer存储的数据
format格式控制字符串
argument 选择性设定字符串
sscanf会从buffer里读进数据,依照format的格式将数据写入到argument里
待详述。。。
简易元素指那些仅包含文本的元素。它不会包含任何其他的元素或属性。
定义简易元素的语法:
<xs:element name="xxx" type="yyy"/>
此处 xxx 指元素的名称,yyy 指元素的数据类型。
最常用的类型是:
Ø xs:string
Ø xs:decimal
Ø xs:integer
Ø xs:boolean
Ø xs:date
Ø xs:time
简易元素可拥有指定的默认值或固定值。
当没有其他的值被规定时,默认值就会自动分配给元素。
<xs:element name="color" type="xs:string" default="red"/>
固定值同样会自动分配给元素,并且您无法规定另外一个值。
<xs:element name="color" type="xs:string" fixed="red"/>
简易元素无法拥有属性。假如某个元素拥有属性,它就会被当作某种复合类型。但是属性本身总是作为简易类型被声明的
定义属性的语法是:
<xs:attribute name="xxx" type="yyy"/>
在此处,xxx 指属性名称,yyy 则规定属性的数据类型。常用类型与简易元素相同。
属性可拥有指定的默认值或固定值。
当没有其他的值被规定时,默认值就会自动分配给元素。
<xs:attribute name="lang" type="xs:string" default="EN"/>
固定值同样会自动分配给元素,并且您无法规定另外的值。
<xs:attribute name="lang" type="xs:string" fixed="EN"/>
在缺省的情况下,属性是可选的。如需规定属性为必选,请使用 "use" 属性:
<xs:attribute name="lang" type="xs:string" use="required"/>
XSD:XML结构定义(XML Schemas Definition )
XML Schema描述了XML文档的结构。
文档设计者可以通过XML Schema指定一个XML文档所允许的结构和内容,并可据此检查一个XML文档是否是有效的。
XML Schema本身是一个XML文档,它符合XML语法结构。可以用通用的XML解析器解析它。
一个XML Schema会定义:文档中出现的元素、属性、子元素、子元素的数量、子元素的顺序、元素是否为空、元素和属性的数据类型、元素或属性的默认和固定值。
XML Schema是DTD的替代品。
原因:一是据将来的条件可扩展,二是比DTD丰富和有用,三是用XML书写,四是支持数据类型,五是支持命名空间。
优点:
1) XML Schema基于XML,没有专门的语法
2) XML Schema可以象其他XML文件一样解析和处理
3) XML Schema支持一系列的数据类型(int、float、Boolean、date等)
4) XML Schema提供可扩充的数据模型。
5) XML Schema支持综合命名空间
6) XML Schema支持属性组。
<schema> 元素是每一个 XML Schema 的根元素
<?xml version="1.0"?>
<xs:schema xmlns:xs=http://www.w3.org/2001/XMLSchema
targetNamespace="http://www.w3school.com.cn"
xmlns="http://www.w3school.com.cn"
elementFormDefault="qualified">
...
</xs:schema>
<?xml version="1.0"?>
是所有 XML 文档中都必须有的 XML 声明,用途是告诉 XML 解析器文档所遵从的 XML 规范的版本和使用字符集。目前 XML 规范的最高版本就是 1.0。除了 ISO-8859-1 外(缺省字符集,可以不写),我们做开发时最常用的两个字符集是 GBK 和 UTF-8。
包含在 <? ... ?> 中的内容叫做处理指令(Processing Instruction,PI),处理指令不是 XML 的一部分,它的作用是为 XML 应用程序处理 XML 提供一些指示。注意,刚才说的 XML 声明虽然与处理指令很像,但并不是处理指令。
xs:schema节点中的xmlns:xs指出:schema中用到的元素和数据类型来自命名空间 "http://www.w3.org/2001/XMLSchema"。同时它还规定了来自命名空间 "http://www.w3.org/2001/XMLSchema" 的元素和数据类型应该使用前缀 xs。
targetNamespace指出:被此 schema 定义的元素来自命名空间: "http://www.w3school.com.cn
xmlns指出:默认的命名空间是 "http://www.w3school.com.cn"。
elementFormDefault指出:任何 XML 实例文档所使用的且在此 schema 中声明过的元素必须被命名空间限定
在 XML 文档中引用 Schema
<?xml version="1.0"?>
<note xmlns="http://www.w3school.com.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3school.com.cn note.xsd">
...
</note>
xmlns:规定了默认命名空间的声明。此声明会告知 schema 验证器,在此 XML 文档中使用的所有元素都被声明于 "http://www.w3school.com.cn" 这个命名空间
xmlns:xsi:声明XML Schema实例名称空间(http://www.w3.org/2001/XMLSchema-instance),并将xsi前缀与该名称空间绑定,这样模式处理器就可以识别xsi:schemaLocation属性。XML Schema实例名称空间的前缀通常使用xsi。
xsi:schemaLocation:使用xsi:schemaLocation属性指定名称空间http://www.w3school.com.cn和模式位置http://www.w3school.com.cn note.xsd相关。
void *memcpy(void *dest, const void *src, int n);
功能:
从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。
头文件:
#include <string.h>
返回值:
指向dest的指针。
char *strcpy(char *dest, char *src);
功能:
把src所指由'\0'结束的字符串复制到dest所指的数组中。
头文件:
#include "string.h"
返回值:
指向dest的指针。
char * strncpy(char *dest, char *src, size_t n);
功能:
将字符串src中最多n个字符复制到字符数组dest中
返回值:
指向dest的指针。
头文件:
#include "string.h"
memcpy说明:
1.src和dest所指内存区域不能重叠,函数返回指向dest的指针。
2.与strcpy相比,memcpy并不是遇到'\0'就结束,而是一定会拷贝完n个字节。
3.如果目标数组destin本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。如果要追加数据,则每次执行memcpy后,要将目标数组地址增加到你要追加数据的地址。
//注意,src和dest都不一定是数组,任意的可读写的空间均可。
strcpy说明:
src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
当src串长度>dest串长度时,程序仍会将整个src串复制到dest区域,可是dest数组已发生溢出。因此会导致dest栈空间溢出以致产生崩溃异常。如果不考虑src串的完整性,可以把dest数组最后一元素置为NULL,从dest串长度处插入NULL截取字串。
strncpy说明:
它并不像strcpy一样只有遇到NULL才停止复制,而是多了一个条件停止,就是说如果复制到第n个字符还未遇到NULL,也一样停止。
如果n > dest串长度,dest栈空间溢出产生崩溃异常。
否则:
1)src串长度<=dest串长度,(这里的串长度包含串尾NULL字符)
如果n=(0, src串长度),src的前n个字符复制到dest中。但是由于没有NULL字符,所以直接访问dest串会发生栈溢出的异常情况。
如果n = src串长度,与strcpy一致。
如果n = dest串长度,[0,src串长度]处存放于desk字串,(src串长度, dest串长度]处存放NULL。
2)src串长度>dest串长度
如果n =dest串长度,则dest串没有NULL字符,会导致输出会有乱码。如果不考虑src串复制完整性,可以将dest最后一字符置为NULL。
综上,一般情况下,使用strncpy时,建议将n置为dest串长度(除非你将多个src串都复制到dest数组,并且从dest尾部反向操作),复制完毕后,为保险起见,将dest串最后一字符置NULL,避免发生在第2)种情况下的输出乱码问题。当然喽,无论是strcpy还是strncpy,保证src串长度<dest串长度才是最重要的。
strncpy_s:目标空间长度不够时,会弹出assert,使copy不能正常完成,使用时需要指定源缓冲区大小。
_s函数只是windows提供的特有函数,功能比较强大,但是在有跨平台需求的软件中,不建议使用。
strncpy:拷贝你指定的个数或者碰到'\0',不验证源缓冲区长度,可能造成越界。
memcpy:不理'\0',只拷贝你指定的个数,故strcpy可以不指定字符串长度,实现整串copy,而memcpy必定要指定长度。
1.具体功能
该命令用于在本地IP路由表中显示和修改条目。使用不带参数的ROUTE可以显示帮助。
2.语法详解
route [-f] [-p] [command [destination] [mask netmask] [gateway] [metric
metric] [if inte***ce]
3.参数说明
-f
清除所有不是主路由(子网掩码为255.255.255.255的路由)、环回网络路由(目标为127.0.0.0,子网掩码为255.255.255.0的路由)或多播路由(目标为224.0.0.0,子网掩码240.0.0.0的路由)的条目的路由表。如果它与命令之一(例如Add、Change或Delete)结合使用,表会在运行命令之前清除。
-p
与Add命令共同使用时,指定路由被添加到注册表并在启动TCP/IP协议的时候初始化IP路由表。默认情况下,启动TCP/IP协议时不会保存添加的路由,与Print命令一起使用时,则显示永久路由列表。所有其他的命令都忽略此参数。永久路由存储在注册表中的位置是:HKEY_LOCAL_MACHSYSTEMCurrentControlSetServicesTcpipParametersPersistentRoutes。
command 指定要运行的命令。下表列出了有效的命令。
destination
指定路由的网络目标地址。目标地址可以是一个IP网络地址(其中网络地址的主机地址位设置为0),对于主机路由是IP地址,对于默认路由是0.0.0.0。mask
subnetmask
指定与网络目标地址相关联的网掩码(又称子网掩码)。子网掩码对于IP网络地址可以是一适当的子网掩码,对于主机路由是255.255.255.255,对于默认路由是0.0.0.0。如果忽略,则使用子网掩码255.255.255.255。定义路由时由于目标地址和子网掩码之间的关系,目标地址不能比它对应的子网掩码更为详细。换句话说,如果子网掩码的一位是0,则目标地址中的对应位就不能设置为1。
gateway
指定超过由网络目标和子网掩码定义的可达到的地址集的前一个或下一个跃点IP地址。对于本地连接的子网路由,网关地址是分配给连子网接口的IP地址。对于要经过一个或多个路由器才可用到的远程路由,网关地址是一个分配给相邻路由器的、可直接达到的IP地址。
metric metric
为路由指定所需跃点数的整数值(范围是1~9999),它用来在路由表里的多个路由中选择与转发包中的目标地址最为匹配的路由。所选的路由具有最少的跃点数。跃点数能够反映跃点的数量、路径的速度、路径可靠性、路径吞吐量以及管理属性。
if inte***ce 指定目标可以到达的接口的接口索引。使用Route print命令可以显示接口及其对应接口索引的列表。对于接口索引可以使用十进制或十六进制的值。对于十六进制值,要在十六进制数的前面加上0x。忽略if参数时,接口由网关地址确定。
注意:路由表中跃点数一列的值较大是由于允许TCP/IP根据每个LAN接口的IP地址、子网掩码和默认网关的配置自动确定路由表中路由的跃点数造成的。默认启动的自动确定接口跃点数确定了每个接口的速度,调整了每个接口的路由跃点数,因此最快接口所创建的路由具有最低的跃点数。要删除大跃点数,请在每个LAN连接的TCP/IP协议的高级属性中禁用自动确定接口跃点数。
如果在systemrootSystem32DriversEtc文件夹的本地网络文件中存在适当的条目,名称可以用于Destination。只要名称可以通过“域名系统”(DNS)查询这样的标准主机名解析技术分解为IP地址,就可以将其用于Gateway,DNS查询使用存储在systemrootSystem32DriversEtc
文件夹下的本地主机文件和NetBIOS 名称解析。
如果是Print或Delete命令,可以忽略Gateway参数,使用通配符来表示目标和网关。Destination的值可以是由星号(*)指定的通配符。
如果指定目标含有一个星号(*)或问号(?),它被看作是通配符,只打印或删除匹配的目标路由。星号代表任意一字符序列,问号代表任一字符。例如,10.*.1、192.168.*、127.*和*224*都是星号通配符的有效使用。
使用了无效的目标和子网掩码(网掩码)值的组合,会显示“Route bad gateway address netmask”错误消息。目标中有一位或多位设置为1,而其在子网掩码中的对应位设置为0时会发生这个错误。可以通过二进制表示法表示目标和子网掩码来检查这种情况。以二进制表示的子网掩码包括表示目标网络地址部分的一连串的1和表示目标主机地址部分的一连串的0两个部
分。查看目标以确定目标的主机地址部分(由子网掩码所定义) 是否有些位设置成了1。
Windows 98 的Route命令不支持-p参数。
只有当TCP/IP协议在网络连接中安装为网络适配器属性的组件时,该命令才可用。
4.例举说明
例子1:要显示IP路由表的完整内容,执行以下命令:
route print
例子2:要显示IP路由表中以10.开始的路由,执行以下命令:
route print 10.*
例子3:要添加默认网关地址为192.168.12.1的默认路由,执行以下命令:
route add 0.0.0.0 mask 0.0.0.0 192.168.12.1
例子4:要添加目标为10.41.0.0,子网掩码为255.255.0.0,下一个跃点地址为10.27.0.1的路由,执行以下命令:
route add 10.41.0.0 mask 255.255.0.0 10.27.0.1
例子5:要添加目标为10.41.0.0,子网掩码为255.255.0.0,下一个跃点地址为10.27.0.1的永久路由,执行以下命令:
route -p add 10.41.0.0 mask 255.255.0.0 10.27.0.1
例子6:要添加目标为10.41.0.0,子网掩码为255.255.0.0,下一个跃点地址为10.27.0.1,跃点数为7的路由,执行以下命令:
route add 10.41.0.0 mask 255.255.0.0 10.27.0.1 metric 7
例子7:要添加目标为10.41.0.0,子网掩码为255.255.0.0,下一个跃点地址为10.27.0.1,接口索引为0x3的路由,执行以下命令:
route add 10.41.0.0 mask 255.255.0.0 10.27.0.1 if 0x3
例子8:要删除目标为10.41.0.0,子网掩码为255.255.0.0的路由,执行以下命令:
route delete 10.41.0.0 mask 255.255.0.0
例子9:要删除IP路由表中以10.开始的所有路由,执行以下命令:
route delete 10.*
例子10:要将目标为10.41.0.0,子网掩码为255.255.0.0的路由的下一个跃点地址由10.27.0.1更改为10.27.0.25,执行以下命令:
route change 10.41.0.0 mask 255.255.0.0 10.27.0.25
例子11:要添加静态路由让目标为172.0.0.0网段的都转发到网为为172.25.25.1的路由上
route add 172.0.0.0 mask 255.0.0.0 172.25.25.1 metric 2 -p
MFC消息映射机制:
在每个能接收和处理消息的类中,定义一个消息和消息函数静态对照表,即消息映射表。在消息映射表中,消息与对应的消息处理函数指针是成对出现的。某个类能处理的所有消息及其对应的消息处理函数的地址都列在这个类所对应的静态表中。当有消息需要处理时,程序只要搜索该消息静态表,查看表中是否含有该消息,就可知道该类能否处理此消息。如果能处理该消息,则同样依照静态表能很容易找到并调用对应的消息处理函数。
在程序中,当构造一个GDI对象后,该对象并不会立即生效,必须选入设备描述表,它才会在以后的绘制操作中生效。
一般情况下,在完成绘图操作之后,都要利用SelectObject函数把先前的GDI对象选入设备描述表,以便使其恢复到先前的状态。
MFC是微软为了简化程序员的开发工作,将大部分的Windows API函数封装到C++类中的面向对象的框架,是面向对象的函数库。
CWnd类是MFC中一个非常重要的类,它封装了与窗口相关的操作。
MFC中的WinMain函数是在程序编译链接时,由链接器将该函数链接到程序中的。
无论全局变量,还是全局对象,程序在运行时,在加载main函数之前,就已经为全局变量或全局对象分配了内存空间。
应用程序的实例是由实例句柄来标识的。对于MFC程序来说,通过产生一个应用程序类的对象来唯一标识应用程序的实例。每个MFC程序有且仅有一个从应用程序类派生的类。每个MFC程序实例有且仅有一个该派生类的实例化对象,该对象表示了应用程序本身。
Afx前缀的函数代表应用程序框架函数。应用程序框架实际上是一套辅助我们生成应用程序的框架模型,该模型把多个类进行了一个有机的集成,可以根据该模型提供的方案来设计我们自己的应用程序。
InitApplication函数完成MFC内部管理方面的工作。
微软在设计基础类库时,考虑到要把数据本身与它的显示分离开,于是就采用文档/视图结构。数据的存储和加载由文档类来完成,数据的显示和修改则由视图类来完成。
定义一个单文档模板对象,把文档对象、框架对象、视图对象有机地组织在一起;利用AddDocTemplate函数把这个单文档模板添加到文档模板中,从而把这三个类组织成为一个整体。
如果一个类中没有定义任何构造函数,那么C++编译器在某些情况下会为该类提供一个默认的构造函数,这个默认的构造函数是一个不带参数的构造函数。只要一个类汇总定义了一个构造函数,不管这个构造函数是否是带参数的构造函数,C++编译器就不再提供默认的构造函数。
如果一个类中没有定义任何的构造函数,那么编译器只有在以下三种情况,才会提供默认的构造函数:
1) 如果类有虚拟成员函数或者虚拟继承父类(即有虚拟基类)时;
2) 如果类的基类有构造函数(可以是用户定义的构造函数,或编译器提供的默认构造函数);
3) 在类中的所有非静态的对象数据成员,它们所属的类中有构造函数(可以是用户定义的构造函数,或编译器提供的默认构造函数)。
在类中定义成员变量时,不能直接给成员变量赋初值。
基类中的private成员不能被派生类访问,因此private成员不能被派生类所继承。
函数的覆盖:基类函数必须是虚函数,发生覆盖的两个函数分别位于派生类和基类中,函数的名称与参数列表必须完全相同。
函数的隐藏:派生类中具有与基类同名的函数,不考虑参数列表是否相同,从而在派生类中隐藏了基类的同名函数。
生成可执行文件有两个步骤:1.C++编译器对源文件单独进行编译:先由预处理器对预处理指令进行处理,在内存中输出翻译单元;编译器接收预处理的输出,将源代码转换成包含机器语言指令的目标文件。注意,在编译过程中,头文件不参见编译。2.连接器将目标文件和所用到的C++类库文件一起链接生成可执行文件。
编写标准C程序经常调用的C库函数是由编译器厂商提供的。Windows平台下也有类似的函数可供调用,不同的是,这些函数是由Windows操作系统本身提供的。
Windows操作系统提供了各种各样的函数,以方便我们开发Windows应用程序,这些函数是Windows操作系统提供给应用程序编程的接口,简称为API函数。所有主要的Windows函数都在Windows.h头文件中进行了声明。
MSDN是微软向开发人员提供的一套帮助系统,其中包含大量的开发文档、技术文章和示例代码。
Win32 SDK是Windows 32位平台下的软件开发包,包括了API函数、帮助文档、微软提供的一些辅助开发工具。
窗口是Windows应用程序中的一个非常重要的元素,一个Windows应用程序至少要有一个窗口。
在消息的结构体中有相关窗口的句柄,消息类型,消息参数,时间和鼠标位置等信息。
每一个Windows应用程序开始执行后,系统都会为该程序创建一个消息队列,这个消息队列用来存放该程序创建的窗口的消息。
Windows程序中的消息可以分为“进队消息”和“不进队消息”。
在函数调用过程中,会使用栈。_stdcall与_cdecl是两种不同的函数调用约定,定义了函数参数入栈的顺序,由调用函数还是被调用函数将参数弹出栈,以及产生函数修饰名的方法。
Windows应用程序的入口是WinMain函数,由插入到可执行文件中的启动代码调用。
WinMain函数的参数指定了该程序当前运行的实例句柄,命令行参数,以及窗口应该如何显示。
设计窗体类就是指定窗口的特征,包括窗口的样式,窗口过程函数,
窗口过程函数被调用的过程如下:
1) 在设计窗口类的时候,将窗口过程函数的地址赋值给lpfnWWndProc成员变量;
2) 调用RegsiterClass(&wndclass)注册窗口类,那么系统就有了我们所编写的窗口过程函数的地址;
3) 当应用程序接收到某一窗口的消息时,调用DispatchMessage(&msg)将消息回传给系统,系统则利用先前注册窗口类时得到的函数指针,调用窗口过程函数对消息进行处理。
Win32的API函数都遵循_stdcall调用约定。
在VC++开发环境中,默认的编译选项是_cdecl。
在Windows程序中,回调函数必须遵循_stdcall调用约定。
要在窗口中输出文字或者显示图形,需要用到设备描述表DC。DC是一个包含设备信息的结构体,在Windows平台下,所有的图形操作都是利用DC来完成的。
当窗口从无到有、改变尺寸、最小化后恢复、被其他窗口遮盖后再显示时,窗口的客户区都将变为无效。当窗口客户区的一部分或者全部变为“无效”时,系统会发送WM_PAINT消息,通知应用程序重新绘制窗口。
当窗口刚创建的时候,整个客户区都是无效的。因为这个时候程序还没有在窗口上绘制任何东西,当调用UpdateWindow函数时,会发送WM_PAINT消息给窗口过程,对窗口进行刷新。