C、C++函数和类库详解(VC++版)(2016-06-26更新)

C、C++函数和类库详解(VC++版)(未完成)

整理者:赤勇玄心行天道

QQ:280604597

Email:280604597@qq.com

大家有什么不明白的地方,或者想要详细了解的地方可以联系我,我会认真回复的

1   可执行程序编译流程

 

文件名

目录位置

解决方案资源管理器位置

说明

Projname.rc

Projname

源文件

项目的资源脚本文件。资源脚本文件包含如下内容,具体取决于项目的类型和为项目选择的支持(例如工具栏、对话框或 HTML):

  • 默认菜单定义。
  • 快捷键和字符串表。
  • 默认“关于”对话框。
  • 其他对话框。
  • 图标文件(res\Projname.ico)。
  • 版本信息。
  • 位图。
  • 工具栏。
  • HTML文件。

资源文件包含标准 Microsoft 基础类资源的文件 Afxres.rc。

一个项目最多只能有一个资源脚本文件。

Resource.h

Projname

头文件

包含项目使用的资源定义的资源头文件。

Projname.rc2

Projname\res

源文件

包含项目使用的附加资源的脚本文件。可以在项目的.rc文件的顶部包括.rc2文件。

.rc2文件用于存放由多个不同项目使用的资源。不必为不同的项目多次创建相同的资源,而是可以将它们放在一个.rc2文件中,然后将该.rc2文件包括在主.rc文件中。

一个项目最多只能有一个附加资源的脚本文件。

Projname.def

Projname

源文件

DLL项目的模块定义文件。对于控件,它提供控件的名称和说明以及运行时堆的大小。

一个项目最多只能有一个模块定义文件。

Projname.ico

Projname\res

资源文件

项目或控件的图标文件。该图标在应用程序最小化时出现。它还用在应用程序的“关于”框中。默认情况下,MFC提供MFC图标,ATL提供ATL图标。

ProjnameDoc.ico

Projname\res

资源文件

包括文档/视图结构支持的MFC项目的图标文件。

Toolbar.bmp

Projname\res

资源文件

表示工具栏或调色板中的应用程序或控件的位图文件。该位图包含在项目的资源文件中。初始工具栏和状态栏在CMainFrame类中构造。

 

2   函数库

2.1 函数模板(未完成)

函数名称

xxx

头文件

#include <xxx.h>

#include <xxx.h>

库文件

#pragma comment(lib, "xxx.lib")

函数功能

函数主要功能说明。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.2 内存分配

2.2.1 realloc

函数名称

realloc

头文件

#include <stdlib.h>

#include <malloc.h>

库文件

函数功能

调整一块已分配的旧内存的长度,或者直接分配一块新内存。

函数声明

void * realloc (

void * ptr,

size_t size

);

函数参数

ptr,[输入]:

已分配的旧内存指针。

如果为NULL,表示直接分配一块新内存,此时本函数就类似malloc()函数。

size,[输入]:

新内存的长度,单位字节。

如果为0,表示释放已分配的旧内存。

如果新内存比旧内存大,再把旧内存的数据全部拷贝过来,新内存的指针与旧内存可能一样,也可能不一样,扩大的内存部分里的数据是未被初始化过的。

如果新内存比旧内存小,就会把旧内存截断作为新内存,新内存的指针与旧内存一样,被截断的数据会丢失。

如果新内存和旧内存一样大,将不做任何改动。

返回值

非NULL:新内存的指针。

NULL:失败,已分配的旧内存的长度、指针和数据都不会改变。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

如果内存不再使用时,记得调用free()释放内存,防止内存泄露。

分配的内存是全局的,在整个进程内有效。

旧内存必须是先前通过调用malloc(), calloc(), 或realloc()函数分配的。

 

 

2.2.2 malloc

函数名称

malloc

头文件

#include <stdlib.h>

#include <malloc.h>

库文件

函数功能

分配一块指定长度的内存。

函数声明

void * malloc (

size_t size

);

函数参数

size,[输入]:

存放内存的长度的值,单位字节。

返回值

非NULL:分配的内存的指针。

NULL:失败,调用errno变量查看错误码。

错误码

ENOMEM:内存不足。

线程安全

原子操作

其他说明

如果内存不再使用时,记得调用free()释放内存,防止内存泄露。

分配的内存是全局的,整个进程都可以使用。

分配的内存里的数据是未被初始化过的。

 

 

2.2.3 calloc

函数名称

calloc

头文件

#include <stdlib.h>

#include <malloc.h>

库文件

函数功能

分配一块nmemb个子块长度为size的内存,子块与子块之间是连续的,等同于malloc ( nmemb * size)。

函数声明

void * calloc (

size_t nmemb,

size_t size

);

函数参数

nmemb,[输入]:

存放多少个子块的值。

size,[输入]:

存放每个子块长度的值,单位字节。

返回值

非NULL:内存的指针。

NULL:失败,调用errno变量查看错误码。

错误码

ENOMEM:内存不足。

线程安全

原子操作

其他说明

如果内存不再使用时,记得调用free()释放内存,防止内存泄露。

分配的内存是全局的,在整个进程内有效。

内存里的数据是全部被初始化为0。

 

 

2.2.4 _msize

函数名称

_msize

头文件

#include <malloc.h>

库文件

函数功能

用于获取alloc()相关函数或new分配的内存的实际可用的长度,单位字节,此长度等于分配内存时指定的长度。

函数声明

size_t _msize (

void * memblock

);

函数参数

memblock,[输入]:

存放alloc()相关函数或new分配的内存指针。

本参数必须是有效指针,且为起始指针,不能为内存中间位置的指针,不能为NULL,否则导致意外结果。

返回值

正整数:分配内存的长度,单位字节。

错误码

线程安全

原子操作

其他说明

 

 

 

2.2.5 free

函数名称

free

头文件

#include <malloc.h>

库文件

函数功能

释放调用alloc()系列函数分配的内存。

函数声明

void free (

void * memblock

);

函数参数

memblock,[输入]:

存放调用alloc()系列函数分配的内存的内存指针,不能为无效内存指针,否则会内存读写错误。

返回值

错误码

线程安全

原子操作

其他说明

 

 

 

2.3 shell命令

2.3.1 _popen(未完成)

函数名称

_popen

头文件

#include <stdio.h>

库文件

函数功能

另启动一个进程执行shell命令,并建立一条管道,可以将shell命令进程的标准输入或输出重定向到这条管道上,调用进程就可以通过这条管道读取shell命令启动的进程的标准输出,或者也可以输出数据到该进程的标准输入。

只能建立一条管道,一条管道只能重定向标准输入或者标准输出,不能同时重定向。

函数声明

FILE * _popen (

const char * command,

const char * mode

);

函数参数

command,[输入]:

存放shell命令字符串的指针,此命令对应的可执行文件必须是控制台程序,如果是窗口程序就会导致错误。例如:"dir /a"是控制台程序,但不能是"calc"(calc是计算器程序)。如果要重定向串口程序,参考:http://msdn.microsoft.com/zh-cn/library/ms682499.aspx

mode,[输入]:

重定向方式,"r"表示重定向标准输出,"w"表示重定向标准输入,"t"表示文本模式,"b"表示二进制模式。"r"和"w"二选一,"t"和"b"二选一。例如:"rt"、"rb"、"wt"、"wb"。

返回值

NULL:失败,读取errno变量查看错误码。

其他:管道的文件描述符。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

返回的文件描述符可以调用fgets()、fputs()、fscanf()、fprintf()等函数来操作标准输入或标准输出。

返回的文件描述符在使用完后必须调用feof()函数关闭。

shell命令启动的进程不会随调用进程的退出而退出,而是在执行完后自己退出。

 

 

2.3.2 system(未完成)

函数名称

system

头文件

#include <stdlib.h>

库文件

函数功能

执行一个shell命令,调用/bin/sh -c "shell命令"来另启动一个进程执行,命令执行完后此函数才返回。执行命令期间,SIGCHLD信号被锁定,SIGINT和SIGQUIT信号被忽略。

函数声明

int system (

const char * command

);

函数参数

command,[输入]:

要执行的shell命令的字符串。

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

此函数在使用/bin/sh启动执行shell命令时,会丢掉调用进程的setuid和setgid位。

 

 

2.3.3 Sleep

函数名称

Sleep

头文件

#include <Windows.h>

库文件

#pragma comment(lib, "Kernel32.lib")

函数功能

使当前线程暂停运行一段时间,暂停期间线程不占用CPU资源,且会进行消息循环。

函数声明

VOID Sleep (

DWORD dwMilliseconds

);

函数参数

dwMilliseconds,[输入]:

存放要暂停运行多少毫秒的值,为INFINITE宏表示无限暂停,为0表示让出一次本线程的时间片给其他线程(用时很短)。

返回值

错误码

线程安全

原子操作

其他说明

本函数的准确性会受到软硬件环境的影响。

 

 

2.3.4 Beep(未完成)

函数名称

Beep

头文件

#include <Windows.h>

库文件

#pragma comment(lib, "Kernel32.lib")

函数功能

让计算机发出警笛声。

函数声明

BOOL Beep (

DWORD dwFreq,

DWORD dwDuration

);

函数参数

dwFreq,[输入]:

存放警笛声的频率的值,频率越高声音越大,单位Hz,范围37 Hz至32767 Hz。

dwDuration,[输入]:

存放警笛声的持续时间的值,单位毫秒,如果本参数为负数,表示不发出警笛声。

返回值

非0:成功。

0:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

 

 

 

2.3.5 GetModuleFileName(未完成)

函数名称

GetModuleFileName

头文件

#include <Windows.h>

库文件

#pragma comment(lib, "Kernel32.lib")

函数功能

获取指定模块的程序文件的绝对路径字符串,存放到指定的内存。

函数声明

DWORD GetModuleFileName (

HMODULE hModule,

LPSTR lpFilename,

DWORD nSize

);

函数参数

hModule,[输入]:

一个模块的句柄。如果是一个DLL模块的句柄,就获取DLL库文件的绝对路径字符串;如果是一个应用程序的实例句柄,就获取该应用程序的可执行文件的绝对路径字符串。如果本参数为NULL,表示获取本进程可执行文件的绝对路径字符串,在DLL模块中调用也是如此。

lpFilename,[输出]:

存放绝对路径字符串的内存指针。

nSize,[输入]:

存放绝对路径字符串的内存的最大长度。

返回值

正整数:如果绝对路径字符串的内存的最大长度足够大,就返回绝对路径字符串的长度,不包括\0;如果不够大,就返回绝对路径字符串截断后的长度,包括\0,并设置ERROR_INSUFFICIENT_BUFFER错误码,但winXP系统设置ERROR_SUCCESS错误码。

0:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

如果一个DLL模块被多个进程加载,获取到的绝对路径字符串可能不一样。

_pgmptr全局变量会在进程启动前自动初始化成本进程可执行文件的绝对路径字符串的内存指针。

 

 

2.3.6 SetCurrentDirectory(未完成)

函数名称

SetCurrentDirectory

头文件

#include <Windows.h>

库文件

#pragma comment(lib, "Kernel32.lib")

函数功能

设置本程序的当前活动目录。

函数声明

BOOL SetCurrentDirectory (

LPCSTR lpPathName

);

函数参数

lpPathName,[输入]:

存放当前活动目录字符串的内存指针,可以是相对或绝对目录。

返回值

非0:成功。

0:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.4 文件

2.4.1 打开或创建文件

2.4.1.1   open(未完成)

函数名称

open

头文件

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

函数功能

用普通模式打开指定的文件,同时还可以创建文件。普通模式是指当输出数据到文件时,会直接输出到文件,等到数据已经输出到文件后才返回,可以保证输出成功,但会减慢输出操作。

函数声明

int open (

const char * pathname,

int flags

);

函数参数

pathname,[输入]:

存放要打开的文件的路径字符串的内存指针,可以是相对或绝对的路径。

不能为NULL。

flags,[输入]:

打开文件时使用的模式和权限。可以是(用"|"选一至多个):

O_RDONLY以只读方式打开文件。

O_WRONLY以只写方式打开文件。

O_RDWR以可读写方式打开文件。

以上三种标记只能使用一个,以下的标记没有限制。

O_CREAT如果使用此标记,表示如果要打开的文件不存在则创建并打开该文件,如果要打开的文件存在,则直接打开;如果不使用此标记,表示如果要打开的文件不存在,则立即返回失败并设置ENOENT错误码,如果要打开的文件存在,则直接打开。

O_EXCL如果使用此标记,并使用O_CREAT标记,表示如果要打开的文件不存在,则创建并打开该文件,如果要打开的文件存在,则立即返回失败并设置EEXIST错误码。此外,若O_CREAT与O_EXCL同时设置,并且欲打开的文件为符号连接,则会打开文件失败。如果使用此标记,必须同时使用O_CREAT标记。此标记一般用于检测文件是否是本进程创建的。

O_NOCTTY如果使用此标记,表示如果要打开的文件为终端机设备时,则不会将该终端机当成进程控制终端机。

O_TRUNC如果使用此标记,并使用可写方式打开,表示把要打开的文件的长度清为0,而原来存于该文件的数据也会消失。

O_APPEND如果使用此标记,表示每次写文件时都会从文件末尾开始,在NFS文件系统上,如果多个进程同时追加写入同一个文件时,有可能会导致写入结果错乱,因为在此文件系统上的追加功能不是原子操作;如果不使用此标记,表示每次写文件时从文件指针开始。

O_NONBLOCK如果使用此标记,表示以非阻塞方式操作打开文件,也就是无论有无数据读取或等待,都会立即返回。

O_NDELAY同O_NONBLOCK。

O_SYNC以同步的方式打开文件。

O_NOFOLLOW如果参数pathname 所指的文件为一符号连接,则会令打开文件失败。

O_DIRECTORY如果参数pathname 所指的文件并非为一目录,则会令打开文件失败。

此为Linux2.2以后特有的旗标,以避免一些系统安全问题。参数mode 则有下列数种组合,只有在建立新文件时才会生效,此外真正建文件时的权限会受到umask值所影响,因此该文件权限应该为(mode-umaks)。

S_IRWXU00700 权限,表示该文件所有者具有可读、可写及可执行的权限。

S_IRUSR00400权限,表示该文件所有者具有可读取的权限。

S_IWUSR00200 权限,表示该文件所有者具有可写入的权限。

S_IXUSR00100 权限,表示该文件所有者具有可执行的权限。

S_IRWXG00070权限,表示该文件所有组具有可读、可写及可执行的权限。

S_IRGRP00040 权限,表示该文件所有组具有可读的权限。

S_IWGRP00020权限,表示该文件所有组具有可写入的权限。

S_IXGRP00010 权限,表示该文件所有组具有可执行的权限。

S_IRWXO00007权限,表示其他用户具有可读、可写及可执行的权限。

S_IROTH00004 权限,表示其他用户具有可读的权限

S_IWOTH00002权限,表示其他用户具有可写入的权限。

S_IXOTH00001 权限,表示其他用户具有可执行的权限。

返回值

-1:失败,调用errno变量查看错误码。

其他:被打开文件的普通模式文件描述符。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

要读取或写入某个文件,必须要先打开该文件。

文件使用完毕后,记得调用close()函数关闭文件描述符,释放资源。

 

 

2.4.1.2   fopen(未完成)

函数名称

fopen

头文件

#include <stdio.h>

函数功能

用缓存模式打开指定的文件,同时还可以创建文件。

缓存模式是指当输出数据到文件时,会先输出到缓存,函数就立即返回,然后等缓存满了系统再一次性输出到文件,可以减少输出数据次数,加速输出效率,但会延迟输出操作,存在丢数据的可能。

函数声明

FILE * fopen (

     const char * filename,

     const char * mode

  );

函数参数

filename,[输入]:

存放要打开的文件的路径字符串的内存指针,路径要加文件名,可以是相对或绝对的路径。

mode,[输入]:

存放用什么方式打开文件的字符串的内存指针。

返回值

NULL:失败,调用errno变量查看错误码。

其他:被打开文件的缓存模式文件描述符。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

要读取或写入某个文件,必须要先打开该文件。

文件使用完毕后,记得调用fclose()函数关闭文件描述符,释放资源。

可以调用fflush()函数将缓存里的数据立即输出到文件。

 

 

2.4.1.3   CreateFile(未完成)

函数名称

CreateFile

头文件

#include <Windows.h>

函数功能

打开指定的文件,同时还可以创建文件。

函数声明

HANDLE CreateFile (

LPCTSTR lpFileName,

DWORD dwDesiredAccess,

DWORD dwShareMode,

LPSECURITY_ATTRIBUTES lpSecurityAttributes,

DWORD dwCreationDisposition,

DWORD dwFlagsAndAttributes,

HANDLE hTemplateFile

);

函数参数

lpFileName,[输入]:

存放要打开的文件的路径字符串的内存指针。

dwDesiredAccess,[输入]:

参数说明。

参数1,[输入|输出|输入&输出]:

参数说明。

参数1,[输入|输出|输入&输出]:

参数说明。

参数1,[输入|输出|输入&输出]:

参数说明。

参数1,[输入|输出|输入&输出]:

参数说明。

参数1,[输入|输出|输入&输出]:

参数说明。

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.4.2 读取文件

2.4.2.1   fread(未完成)

函数名称

fread

头文件

#include <xxx.h>

#include <xxx.h>

函数功能

函数主要功能说明。

函数声明

类型 函数名 (类型 参数1, 类型 参数2, ……);

函数参数

参数1:[输入|输出|输入&输出],参数说明。

参数2:[输入|输出|输入&输出],参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知

其他说明

……

……

 

 

2.4.3 写入文件

2.4.3.1   fprintf(未完成)

函数名称

xxx

头文件

#include <xxx.h>

#include <xxx.h>

函数功能

函数主要功能说明。

函数声明

类型 函数名 (类型 参数1, 类型 参数2, ……);

函数参数

参数1:[输入|输出|输入&输出],参数说明。

参数2:[输入|输出|输入&输出],参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知

其他说明

"\n"会被自动转换为"\r\n"。

 

 

2.4.3.2   fputs(未完成)

函数名称

fputs

头文件

#include <stdio.h>

函数功能

将字符串输出到文件。

函数声明

int fputs (

const char * str,

FILE * stream

);

函数参数

str,[输入]:

存放要输出的字符串的内存指针。

stream,[输入]:

存放要输出的文件的缓存模式文件描述符。

返回值

大于等于0:输出了多少个字节。

-1:失败。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

如果是直接输出字符串,不格式化输出时,fputs()函数效率比fprintf()函数效率高很多。

 

 

2.4.3.3   vprintf(未完成)

函数名称

xxx

头文件

#include <xxx.h>

#include <xxx.h>

函数功能

函数主要功能说明。

函数声明

类型 函数名 (类型 参数1, 类型 参数2, ……);

函数参数

参数1:[输入|输出|输入&输出],参数说明。

参数2:[输入|输出|输入&输出],参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知

其他说明

……

……

 

 

2.4.4 监测文件

2.4.4.1   select(未完成)

函数名称

select

头文件

#include <Ws2tcpip.h>

函数功能

阻塞检查一个或多个套接字是否处于可读、可写或错误的状态。

函数声明

int select (

int nfds,

fd_set FAR * readfds,

fd_set FAR * writefds,

fd_set FAR * exceptfds,

const struct timeval FAR * timeout

);

函数参数

nfds,[输入]:

此参数无意义,直接填0,此参数只是为了与Berkeley套接字兼容。

readfds,[输入&输出]:

输入时,存放需要检查可读状态的套接字组的内存指针,不需要就填NULL。

writefds,[输入&输出]:

输入时,存放需要检查可写状态的套接字组的内存指针,不需要就填NULL。

exceptfds,[输入&输出]:

输入时,存放需要检查错误状态的套接字组的内存指针,不需要就填NULL。

timeout,[输入&输出]:

输入时,存放阻塞检查的超时时间的结构体的内存指针。

为NULL表示超时时间为无限。

为0秒0微秒表示不阻塞立即返回。

返回值

SOCKET_ERROR:失败,调用WSAGetLastError()函数查看错误码。

0:成功,但在阻塞检查的超时时间内没有任何套接字处于需要检查的状态。

大于0:成功,已经有多少个套接字处于需要检查的状态。

线程安全

其他说明

 

 

 

 

2.4.4.2   FindFirstChangeNotification(未完成)

函数名称

FindFirstChangeNotification

头文件

#include <Windows.h>

函数功能

监视指定的目录中的变化,并返回变化通知句柄。不能监视文件,只能监视目录。

每一个变化通知句柄会对应一个唯一的通知队列,当指定的目录有要监视的变化行为时,操作系统就会自动把这条变化通知追加到变化通知句柄对应的通知队列里。

函数声明

HANDLE FindFirstChangeNotification (

LPCTSTR lpPathName,

BOOL bWatchSubtree,

DWORD dwNotifyFilter

);

函数参数

lpPathName,[输入]:

存放要监视的目录的路径字符串的内存指针,不能为文件的路径。

bWatchSubtree,[输入]:

存放是否要监视目录的子项,TRUE表示要,FALSE表示不要。

dwNotifyFilter,[输入]:

存放要监视哪些变化,可以是(用'|'选一至多个):

FILE_NOTIFY_CHANGE_FILE_NAME:只监视文件名称的变化。不监视目录名称的变化。

FILE_NOTIFY_CHANGE_DIR_NAME:只监视目录名称的变化。不监视文件名称的变化。

FILE_NOTIFY_CHANGE_ATTRIBUTES:监视文件和目录的属性的变化。

FILE_NOTIFY_CHANGE_SIZE:监视文件实际大小的变化。不监视文件内容和目录实际大小的变化。

FILE_NOTIFY_CHANGE_LAST_WRITE:监视文件的最后修改时间的变化。

FILE_NOTIFY_CHANGE_LAST_ACCESS:监视文件的最后访问时间的变化。

FILE_NOTIFY_CHANGE_CREATION:监视文件的创建时间的变化。

FILE_NOTIFY_CHANGE_SECURITY:监视安全属性的变化。

返回值

INVALID_HANDLE_VALUE:失败,调用GetLastError()函数查看错误码。

其他:变化通知句柄。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

此函数返回的变化通知句柄可以调用WaitForSingleObject()函数等待通知队列里什么时候有变化通知,当等待到有变化通知后,WaitForSingleObject()函数会立即返回,然后应该调用FindNextChangeNotification()函数移除最老的一条通知,要不然再次调用WaitForSingleObject()函数时,会因为通知队列里有变化通知而立即返回。

此函数返回的变化通知句柄只能监视是否有变化,无法知道具体的变化文件。

变化通知句柄使用完后需要调用FindCloseChangeNotification()函数释放句柄资源。

此系列函数无法区分通知队列里存放的具体是哪个文件或目录的哪种变化的通知,只知道有变化。

 

 

2.4.4.3   FindNextChangeNotification(未完成)

函数名称

FindNextChangeNotification

头文件

#include <Windows.h>

函数功能

根据FindFirstChangeNotification()函数获取的变化通知句柄,移除变化通知句柄对应的通知队列里最老的一条通知,如果通知队列里无通知,此函数也返回成功。

函数声明

BOOL FindNextChangeNotification (

HANDLE hChangeHandle

);

函数参数

hChangeHandle,[输入]:

存放变化通知句柄。

返回值

非0:成功。

0:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

 

 

 

2.4.4.4   FindCloseChangeNotification(未完成)

函数名称

FindCloseChangeNotification

头文件

#include <Windows.h>

函数功能

关闭FindFirstChangeNotification()函数获取的变化通知句柄,并释放句柄资源。

函数声明

BOOL FindCloseChangeNotification (

HANDLE hChangeHandle

);

函数参数

hChangeHandle,[输入]:

存放变化通知句柄的值。

返回值

非0:成功。

0:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

 

 

 

2.4.4.5   ReadDirectoryChangesW(未完成)

函数名称

ReadDirectoryChangesW

头文件

#include <Windows.h>

函数功能

监视一个目录下的所有改动。

函数声明

BOOL ReadDirectoryChangesW (

HANDLE hDirectory,

LPVOID lpBuffer,

DWORD nBufferLength,

BOOL bWatchSubtree,

DWORD dwNotifyFilter,

LPDWORD lpBytesReturned,

LPOVERLAPPED lpOverlapped,

LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine

);

函数参数

参数1:[输入|输出|输入&输出],参数说明。

参数2:[输入|输出|输入&输出],参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.4.5 移动、复制、删除、重命名文件

2.4.5.1   SHFileOperation(未完成)

函数名称

SHFileOperation

头文件

#include <Shellapi.h>

函数功能

以Shell命令方式移动、复制、删除、重命名文件或目录,并指定是否显示操作过程窗口。

函数声明

int SHFileOperation (

LPSHFILEOPSTRUCT lpFileOp

);

函数参数

lpFileOp,[输入&输出]:

输入时,存放对指定文件或目录的指定操作的Shell命令文件操作结构体的内存指针。详见SHFILEOPSTRUCT结构体详解。

输出时,存放其他信息。

返回值

0:成功,如果用户取消了操作,也返回成功。

非0:失败。

在lpFileOp参数输出时的fAnyOperationsAborted成员变量查看错误码或具体情况。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.4.6 移动文件

2.4.6.1   MoveFile(未完成)

函数名称

MoveFile

头文件

#include <Windows.h>

函数功能

移动一个已存在的文件或目录(包括子项)到其他路径。

函数声明

BOOL MoveFile (

LPCSTR lpExistingFileName,

LPCSTR lpNewFileName

);

函数参数

lpExistingFileName,[输入]:

存放要移动的文件或目录的路径字符串的内存指针。

lpNewFileName,[输入]:

存放移动后的文件或目录的路径字符串的内存指针,此路径在移动前不能是已存在的,可以为相对或绝对路径。

如果要移动文件,本参数的路径字符串需包含新文件名,不能只包含新文件所在目录。

如果要移动目录,本参数的路径字符串需包含新目录名,不能只包含新目录所在目录。

要移动的文件与移动后的文件可以不在同一分区里,但要移动的目录与移动后的目录必须在同一分区里。

文件或目录的属性与移动前一致。

返回值

非0:成功。

0:失败,调用GetLastError()函数查看错误码。

错误码

ERROR_FILE_EXISTS(80):移动后的文件或目录已存在。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

 

 

 

2.4.6.2   MoveFileEx(未完成)

函数名称

MoveFile

头文件

#include <Windows.h>

函数功能

移动一个已存在的文件或目录(包括子项)到其他路径。

函数声明

BOOL MoveFileEx (

LPCTSTR lpExistingFileName,

LPCTSTR lpNewFileName,

DWORD dwFlags

);

函数参数

lpExistingFileName,[输入]:

存放要移动的文件或目录的路径字符串的内存指针。

lpNewFileName,[输入]:

存放移动后的文件或目录的路径字符串的内存指针,此路径在移动前不能是已存在的,可以为相对或绝对路径。

如果要移动文件,本参数的路径字符串需包含新文件名,不能只包含新文件所在目录。

如果要移动目录,本参数的路径字符串需包含新目录名,不能只包含新目录所在目录。

要移动的文件可以与移动后的文件不在同一分区里,但要移动的目录必须与移动后的目录在同一分区里。

文件或目录的属性移动后与移动前一致。

dwFlags,[输入]:

移动文件时的一些行为,可以为(用'|'选零至多个):

MOVEFILE_REPLACE_EXISTING

如果设置本标记,表示如果移动后的文件或目录已存在,就将其替换。

如果不设置本标记,表示如果移动后的文件或目录已存在,就报错。

MOVEFILE_COPY_ALLOWED

如果设置本标记,则允许要移动的文件或目录与移动后的文件或目录在不同的分区里。

如果不设置本标记,则不允许,并报ERROR_NOT_SAME_DEVICE错误。

MOVEFILE_DELAY_UNTIL_REBOOT

移动操作在系统下次重新启动时正式进行。这样便可改换系统文件。

如果设置本标记,本函数会把要移动的文件的信息写入到注册表项HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\PendingFileRenameOperations下,此时本函数的返回值只说明写入注册表的操作是否成功。

返回值

非0:成功。

0:失败,调用GetLastError()函数查看错误码。

错误码

ERROR_FILE_EXISTS(80):移动后的文件或目录的路径已存在。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

 

 

 

2.4.7 删除文件

2.4.7.1   DeleteFile(未完成)

函数名称

DeleteFile

头文件

#include <Windows.h>

函数功能

删除一个指定的已存在的文件。

函数声明

BOOL DeleteFile (

LPCTSTR lpFileName

);

函数参数

lpFileName,[输入]:

存放要删除的文件的路径字符串的内存指针,可以为相对或绝对路径,不能为NULL。

返回值

非0:成功。

0:失败,调用GetlastError()函数查看错误码。

错误码

ERROR_FILE_NOT_FOUND:要删除的文件不存在。

ERROR_ACCESS_DENIED:要删除的文件拒绝访问,可能文件是只读文件,或正在被打开,或正在被内存映射等。

……

线程安全

原子操作

其他说明

如果要删除只读文件,需要先把文件的只读属性去掉。

调用本函数的进程必须具有该文件的删除权限,或者具有该文件所在父目录的删除子项权限。

本函数不能删除目录,删除非空目录可以调用SHFileOperation()函数,删除空目录可以调用RemoveDirectory()函数。

如果要删除的文件已经被打开,或被内存映射,本函数返回失败。

本函数是给要删除的文件做删除标记,而不是立即删除,当该文件的句柄被全部关闭时,文件会被自动删除。在该文件被做删除标记期间,如果还有进程调用CreateFile()函数来打开文件,会返回ERROR_ACCESS_DENIED错误。

如果要删除的文件是一个Symbolic link符号链接文件,则只会删除符号链接文件,不会删除被链接的文件。如果要删除被链接的文件,可以调用CreateFile()函数并设置FILE_FLAG_DELETE_ON_CLOSE标记。

本函数是直接永久删除文件,不会把文件移动到回收站。

 

 

2.4.8 查找文件

2.4.8.1   FindFirstFile(未完成)

函数名称

FindFirstFile

头文件

#include <Windows.h>

库文件

#pragma comment(lib, "Kernel32.lib")

函数功能

在指定的路径下查找名称相匹配的一个或多个文件或目录,返回查找句柄。

函数声明

HANDLE FindFirstFile (

LPCTSTR lpFileName,

LPWIN32_FIND_DATA lpFindFileData

);

函数参数

lpFileName,[输入]:

存放要查找的路径字符串的内存指针,支持通配符。例如:"C:\\*","D:\\doc\\file.doc"。

本参数不能为NULL,或非路径字符串。

如果本参数是含有通配符的路径,调用进程必须具有上级目录的访问权限。

lpFindFileData,[输出]:

存放第一个查找到的文件或目录的属性的结构体的内存指针。

本参数不能为NULL。

返回值

INVALID_HANDLE_VALUE:失败,调用GetLastError()函数查看错误码。

其他:成功,查找句柄。

错误码

ERROR_FILE_NOT_FOUND:没有查找到文件。

EXXXX:错误码说明。

……

线程安全

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

如果是查找多个文件或目录,可以根据本函数返回的查找句柄循环调用FindNextFile()函数获取文件信息。

如果是查找多个文件或目录,本函数会匹配"."和".."目录。例如:查找"C:\\*"路径,会查找出" C:\\."和" C:\\.."目录

本函数返回的查找句柄在不使用后,必须调用FindClose()函数释放句柄。

 

 

2.4.9 文件属性

2.4.9.1   GetFileSize(未完成)

函数名称

GetFileSize

头文件

#include <Windows.h>

函数功能

获取指定文件的大小,不是占用空间,且不支持文件夹。

函数声明

DWORD GetFileSize (

HANDLE hFile,

LPDWORD lpFileSizeHigh

);

函数参数

hFile,[输入]:

存放文件句柄的值。可以调用CreateFile()函数获取文件句柄。

lpFileSizeHigh,[输出]:

存放接收文件大小的变量的内存指针,单位字节,可以为NULL。

返回值

INVALID_HANDLE_VALUE:失败,调用GetLastError()查看错误码。

其他:文件的大小,单位字节。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

获取到的是文件的实时大小,不是操作系统缓存记住的大小。

 

 

 

 

2.4.10   路径字符串

2.4.10.1 路径截断与合并

2.4.10.1.1    PathFindFileName

函数名称

PathFindFileName

头文件

#include <Shlwapi.h>

#pragma comment(lib, "Shlwapi.lib")

函数功能

获取路径字符串里的文件名子串的起始指针。

函数声明

char * PathFindFileName (

    const char * pPath

  );

函数参数

pPath,[输入]:路径字符串。

返回值

文件名子串的起始指针

错误码

线程安全

原子操作

其他说明

示例:

路径字符串:"c:\path\file"

文件名子串:"file"

 

路径字符串:"c:\path"

文件名子串:"path"

 

路径字符串:"c:\path\"

文件名子串:"path\"

 

路径字符串:"c:\"

文件名子串:"c:\"

 

路径字符串:"c:"

文件名子串:"c:"

 

路径字符串:"path"

文件名子串:"path"

 

路径字符串:""

文件名子串:""

 

 

2.4.10.1.2    PathFindExtension

函数名称

PathFindExtension

头文件

#include <Shlwapi.h>

#pragma comment(lib, "Shlwapi.lib")

函数功能

获取路径字符串里的文件的扩展名子串的起始指针。如果扩展名出现空格,将返回失败。

函数声明

char * PathFindExtension (

    const char * pPath

  );

函数参数

pPath,[输入]:路径字符串的内存指针。

返回值

文件扩展名前的'.'字符指针:成功。

路径字符串的'\0'字符指针:失败。

错误码

线程安全

原子操作

其他说明

一个正确的文件扩展名不能出现空格。

 

示例:

路径字符串:"abc.txt"

扩展名子串:".txt"

 

路径字符串:"abc.txt "

扩展名子串:""

 

路径字符串:"abc."

扩展名子串:"."

 

路径字符串:"abc"

扩展名子串:""

 

 

GetModuleFileName       得到模块路径名

PathRemoveArgs  去除路径的参数

PathRemoveBackslash 去除路径最后的反斜杠“\”

PathAddBackslash    在路径最后加上反斜杠“\”

PathRemoveBlanks    去除路径前后的空格

PathAddExtension    在文件路径后面加上扩展名

PathRemoveExtension 去除文件路径扩展名

PathRenameExtension 更改文件路径扩展名

PathRemoveFileSpec  去除文件名,得到目录

PathUnquoteSpaces   去除路径中的首尾空格

PathQuoteSpaces 判断路径中是否有空格,有的话,就是用“”引号把整个路径包含起来

PathAppend  将一个路径追加到另一个路径后面

PathCombine 合并两个路径

PathSkipRoot    去掉路径中的磁盘符或UNC部分。

PathStripPath   去掉路径中的目录部分,得到文件名。

PathStripToRoot 去掉路径的文件部分,得到根目录。

PathCompactPath 根据像素值生成符合长度的路径。

如原始路径:          C:\path1\path2\sample.txt

根据120像素截断后为:  C:\pat...\sample.txt

根据25像素截断后为:   ...\sample.txt

PathCompactPathEx   根据字符个数来生成符合长度的路径。

PathSetDlgItemPath  将路径数据设置到对话框的子控件上。

PathUndecorate  去除路径中的修饰——具体还没看明白,MSDN的例子只是去掉了括号。

PathUnExpandEnvStrings  将路径中部分数据替换为系统环境变量格式

 

 

2.4.10.2 路径查找比较函数

PathFindOnPath  从路径中查找路径

PathFindExtension   查找路径的扩展名

PathFindFileName    获取路径的文件名

PathFindNextComponent   查找匹配路径(不太熟悉)

PathFindSuffixArray 查找给定的文件名是否有给定的后缀。

PathGetArgs 获取路径参数

PathGetCharType 获取路径字符类型

PathGetDriveNumber  根据逻辑盘符返回驱动器序号

 

 

2.4.10.3 路径转换函数

PathRelativePathTo  创建一个路径到另一个路径的相对路径。

PathResolve 将一个相对路径或绝对路径转换为一个合格的路径,这个理解起来比较拗口。

PathCanonicalize    规范化路径。将格式比较乱的路径整理成规范的路径格式。

PathBuildRoot   根据给定的磁盘序号创建根目录路径

CreateDirectory 创建目录

     

GetShortPathName    将长路径转为8.3格式的短路径格式

GetLongPathName 将短路径格式转为长路径。

PathGetShortPath    将长路径转为短路径格式(8.3格式)

PathCreateFromUrl   将URL路径转为MS-DOS格式

PathMakePretty  把路径全部转为小写,增加可读性。

PathMakeSystemFolder    给路径增加系统属性

PathUnmakeSystemFolder  去除路径中的系统属性。

PathMakeUniqueName  从模板创建统一的路径格式——没用过,不熟悉

PathProcessCommand  生成一个可执行的路径,比如有参数的,会自动将路径用“”包含。

这在ShellExecute中比较有用。

 

 

2.4.10.4 路径验证函数

PathCleanupSpec 去除路径中不合法的字符

PathCommonPrefix    比较并提取两个路径相同的前缀

PathFileExists  验证路径是否存在

PathMatchSpec   判断路径是否匹配制定的扩展名。

PathIsDirectory 判断路径是否是一个有效的目录

PathIsFileSpec  验证路径是否一个文件名(有可能是一个路径)

PathIsExe   验证路径是否是可执行文件。注意:不仅仅是.exe,还有.bat,.com,.src等

PathIsRoot  路径是否为根路径

PathIsRelative  判断路径是否是相对路径

PathIsContentType   检测文件是否为制定类型。

例如:PathIsContentType( “hello.txt” ,“text/plain” ) 返回TRUE

PathIsContentType( “hello.txt” ,“image/gif” ) 返回FALSE

PathIsHTMLFile  判断路径是否是html文件类型——根据系统注册类型判断。

PathIsLFNFileSpec   判断路径是否是长路径格式

PathIsNetworkPath   判断路径是否是一个网络路径。

PathIsPrefix    判断路径是否含有指定前缀

PathIsSameRoot  判断路径是否有相同根目录

PathIsSlow  判断路径是否是一个高度延迟的网络连接——我也不太明白是啥意思。

PathIsSystemFolder  判断路径是否有系统属性(属性可以自己设定)

PathIsUNC   路径是否是UNC格式(网络路径)

PathIsUNCServer 路径是否是UNC服务器

PathIsUNCServerShare    路径是否仅仅是UNC的共享路径格式

PathIsURL   路径是否是http格式。

PathYetAnotherMakeUniqueName    基于已存在的文件,自动创建一个唯一的文件名。比较有用,比如存在“新建文件”,此函数会创建文件名“新建文件(2)”。

 

 

2.4.11   标准输入、输出和出错

2.4.11.1 ungetc

函数名称

ungetc

头文件

#include <stdio.h>

库文件

函数功能

把一个字符退回到标准输入文件中的第一个字符,下一次将读出此字符,不会将此字符写到文件中和设备上,只将字符退回到标准I/O库的流缓存区中,此字符不能被正在调用的输入流函数读出。

函数声明

int ungetc (

int c,

FILE * stream

);

函数参数

c,[输入]:

要退回的字符,只能是ASCII码的字符,值为0-255。

stream,[输入]:

标准输入文件句柄,也就是stdin。

返回值

EOF:失败。

其他:退回的字符c参数。

错误码

 

线程安全

是 或 否 或 未知

其他说明

 

 

 

2.4.11.2 printf(未完成)

函数名称

printf

头文件

#include <stdio.h>

库文件

函数功能

格式化输出字符串到标准输出文件。

格式化输出字符串就是指可以将一些变量按照一定的格式组合成一个字符串,然后输出到指定的位置。

函数声明

int printf (

const char * format,

...

);

函数参数

format,[输入]:

存放格式化字符串的内存指针,不能为NULL。

格式化字符串主要是使用'%'号来进行转义的,用于描述动态参数的输出格式,转义格式如下:

格式

%[对齐方式][符号][标志][对齐填充][最少输出长度][.精度][长度]格式类型

对齐方式

输出右对齐。

-

输出左对齐。

符号

输出数值为正时不冠以任何符号,为负时冠以'-'负号。

+

输出数值为正时冠以'+'正号,为负时冠以'-'负号。

空格

输出数值为正时冠以' '空格,为负时冠以'-'负号。

标志

#

如果格式类型为o,则在输出时加前缀0;

如果格式类型为x,则在输出时加前缀0x;

如果格式类型为X,则在输出时加前缀0X;

如果格式类型为e、E、f、F,则总是输出小数点,即使精度设置为0;

如果格式类型为g、G,则除了数值为0外总是显示小数点;

如果格式类型为其他类,则无意义;

对齐填充

如果为右对齐,左边填充空格。

如果为左对齐,右边填充空格。

0

如果为右对齐,左边填充'0'。

如果为左对齐,右边填充空格。

最少输出长度

输出时按照实际长度输出。

十进制整数

用来表示最少输出长度。

如果实际长度超过该长度,就按实际长度输出。

如果实际长度少于该长度,则按对齐方式输出。

*

最少输出长度从动态参数中指定,必须是不超过long型的整数。

精度

输出时按照标准精度输出。

.十进制整数

精度格式符以'.'开头,后跟十进制整数。

如果输出数字,则表示小数的位数;若实际位数大于所定义的精度数,则四舍五入。若不足则右边补0。

如果输出的是字符串,则表示输出字符的个数;若实际位数大于所定义的精度数,则截去超过的部分。若不足则原样输出。

*

精度从动态参数中指定,必须是不超过long型的整数。

长度

h

和整数格式类型一起使用,表示一个short int 或者 unsigned short int 类型数值。

例如:“%hu”、“%hx”和“%6.4hd”

l

和整数格式类型一起使用,表示一个long int 或者unsigned long int 类型值。

例如:“%ld”和“%8lu”

ll

和整数格式类型一起使用,表示一个long long int或 unsigned long long int 类型值 (C99标准)。

例如:“%lld”和“%8llu”

L

和浮点转换说明符一起使用,表示一个long double值。

例如:“%Lf”和“%10.4Le”

j

和整数转换说明符一起使用,表示一个intmax_t或uintmax_t值。

示例:“%jd”和“%8jX”

t

和整数转换说明符一起使用,表示一个ptrdiff_t值(与两个指针之间的差相对应的类型) (C99标准)。

例如:“%td”和“%12ti”

z

和整数转换说明符一起使用,表示一个size_t值(sizeof返回的类型) (C99标准)。

例如:“%zd”和“%12zx”

格式类型

c

输出单个ASCII码字符

d

输出有符号十进制整数

i

输出有符号十进制整数

e

以“科学记数法”的形式输出有符号十进制浮点数,如2.451e+02

E

以“科学记数法”的形式输出有符号十进制浮点数,如2.451E+02

f

输出有符号十进制浮点数,不带精度时,保留6位小数

g

选用e或f格式中较短宽度的一个输出十进制浮点数,不输出无效零

G

选用E或f格式中较短宽度的一个输出十进制浮点数,不输出无效零

o

输出无符号八进制整数

p

输出指针变量的无符号十六进制地址值

s

输出char类型字符串

S

输出wchar_t类型字符串

u

输出无符号十进制整数

x

输出无符号小写十六进制整数,不能输出有符号的,如1a2b3c4d

X

输出无符号大写十六进制整数,不能输出有符号的,如1A2B3C4D

%

输出字符'%'

I64

配合u、d等,可以输入输出64位整数。VC++平台有效。如%I64u,%I64d。注意大写。

 

 

...,[输入]:

存放格式化字符串中转义的各个参数。

返回值

输出字符串的长度,单位字节。

错误码

线程安全

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

printf("[%d]", 123);

输出:[123]

printf("[%10d]", 123);

输出:[       123]

printf("[%*d]", 5, 123);

输出:[  123]

printf("[%*d]", (long long)5, 123);

输出:[    0]

printf("[%-10d]", 123);

输出:[123       ]

printf("[%+d]", 123);

输出:[+123]

printf("[% d]", 123);

输出:[ 123]

printf("[%#o]", 123);

输出:[0173]

printf("[%#x]", 123);

输出:[0x7B]

printf("[%#f]", 123.0);

输出:[123.000000]

 

 

2.4.11.3 scanf(未完成)

函数名称

scanf

头文件

#include <stdio.h>

库文件

函数功能

从标准输入文件格式化输入字符串。

格式化输入字符串就是指从指定的位置输入字符串,然后将字符串按照一定的格式拆分并存放到变量。

函数声明

int scanf (

const char * format,

...

);

函数参数

format,[输入]:

存放格式化字符串的内存指针,不能为NULL。

格式化字符串主要是使用'%'号来进行转义的,用于描述动态参数的输出格式,转义格式如下:

格式

%[标志][最少输出长度][.精度][长度]格式类型

标志

#

如果格式类型为o,则在输出时加前缀0;

如果格式类型为x,则在输出时加前缀0x;

如果格式类型为X,则在输出时加前缀0X;

如果格式类型为e、E、f、F,则当结果总是输出小数点;

如果格式类型为g、G,则除了数值为0外总是显示小数点;

如果格式类型为其他类,则无意义;

最多输入长度

输出时按照实际长度输出。

十进制整数

用来表示最少输出长度。

如果实际长度超过该长度,就按实际长度输出。

如果实际长度少于该长度,则按对齐方式输出。

*

最少输出长度从动态参数中指定,必须是不超过long型的整数。

长度

h

和整数格式类型一起使用,表示一个short int 或者 unsigned short int 类型数值。

例如:“%hu”、“%hx”和“%6.4hd”

l

和整数格式类型一起使用,表示一个long int 或者unsigned long int 类型值。

例如:“%ld”和“%8lu”

ll

和整数格式类型一起使用,表示一个long long int或 unsigned long long int 类型值 (C99标准)。

例如:“%lld”和“%8llu”

L

和浮点转换说明符一起使用,表示一个long double值。

例如:“%Lf”和“%10.4Le”

j

和整数转换说明符一起使用,表示一个intmax_t或uintmax_t值。

示例:“%jd”和“%8jX”

t

和整数转换说明符一起使用,表示一个ptrdiff_t值(与两个指针之间的差相对应的类型) (C99标准)。

例如:“%td”和“%12ti”

z

和整数转换说明符一起使用,表示一个size_t值(sizeof返回的类型) (C99标准)。

例如:“%zd”和“%12zx”

格式类型

c

输出单个ASCII码字符

d

输出十进制有符号整数

i

输出十进制有符号整数

e

以“科学记数法”的形式输出十进制有符号浮点数,如2.451e+02

E

以“科学记数法”的形式输出十进制有符号浮点数,如2.451E+02

f

输出十进制的有符号浮点数,不带域宽时,保留6位小数

g

选用e或f格式中较短宽度的一个输出十进制浮点数,不输出无效零

G

选用E或f格式中较短宽度的一个输出十进制浮点数,不输出无效零

o

输出无符号八进制整数

p

输出指针的无符号十六进制地址值

s

输出char类型字符串

S

输出wchar_t类型字符串

u

输出无符号十进制整数

x

输出无符号小写十六进制整数 (不输出前缀Ox),如1a2b3c4d

X

输出无符号大写十六进制整数 (不输出前缀Ox),如1A2B3C4D

%

输出字符'%'

I64

配合u、d等,可以输入输出64位整数。MSVC平台有效。如%I64u,%I64d。注意大写

 

 

...,[输出]:

存放格式化字符串中转义的各个参数。

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.5 内存映射文件

文件内存映射后,读取速度很快,比把文件内容一次性读取到内存再读取内存还要快。

 

CreateFileMapping  创建内存映射文件句柄,使用前必须已经打开了该文件,不能映射长度为0的文件的,否则报1006错误。

MapViewOfFile  具体将文件中的哪一段映射到内存。

UnmapViewOfFile  释放映射的内存。

CloseHandle  关闭内存映射句柄。

 

 

2.6 文件系统

2.6.1 分区剩余空间

2.6.1.1   GetDiskFreeSpaceEx(未完成)

函数名称

GetDiskFreeSpaceEx

头文件

#include <Windows.h>

函数功能

获取指定分区的用户可用空间、用户总空间和总可用空间。

函数声明

BOOL WINAPI GetDiskFreeSpaceEx(

LPCTSTR lpDirectoryName,

PULARGE_INTEGER lpFreeBytesAvailable,

PULARGE_INTEGER lpTotalNumberOfBytes,

PULARGE_INTEGER lpTotalNumberOfFreeBytes

);

函数参数

lpDirectoryName,[输入]:

存放分区上的一个目录字符串的内存指针,为NULL表示当前活动目录所在分区。例如:"C:"、"C:\"、"C:\windows"都表示C盘,".\\"表示当前活动目录所在分区。

目录字符串后面不能加文件名,否侧会失败。

目录字符串只要在指定分区上即可,必须已经存在。

调用进程对该分区必须具有FILE_LIST_DIRECTORY权限。

lpFreeBytesAvailable,[输出]:

存放用于存放用户可用空间的结构体的内存指针,单位字节,不需要就填NULL。

用户可用空间是指启动本程序的用户对指定分区的可用空间,如果启用了磁盘配额,此参数有可能小于指定分区的总可用空间。

lpTotalNumberOfBytes,[输出]:

存放用于存放用户总空间的结构体的内存指针,不需要就填NULL。

用户总空间是指启动本程序的用户对指定分区的可用空间与已用空间之和,如果启用了磁盘配额,此参数有可能小于指定分区的总空间。

lpTotalNumberOfFreeBytes,[输出]:

存放用于存放总可用空间的结构体的内存指针,不需要就填NULL。

总可用空间是指分区的总可用空间。

返回值

非0:成功。

0:失败。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

本函数获取的分区为光驱时,lpFreeBytesAvailable和lpTotalNumberOfFreeBytes参数输出0,除非刻录光驱内有空白可写光盘。

 

 

2.7 时钟

地球分为24个时区:中时区(+0)、东一区(+1)、东二区(+2)、东三区(+3)、东四区(+4)、东五区(+5)、东六区(+6)、东七区(+7)、东八区(+8)、东九区(+9)、东十区(+10)、东十一区(+11)、东西十二区(+/-12)、西十一区(-11)、西十区(-10)、西九区(-9)、西八区(-8)、西七区(-7)、西六区(-6)、西五区(-5)、西四区(-4)、西三区(-3)、西二区(-2)、西一区(-1)。

中时区也叫UTC通用协调时、UTC协调世界时、GMT格林尼治时,简称协调时。

本地时区也叫本地时,是在操作系统中设定的,例如:北京地区,那就是东八区北京时间。

UTC协调时的1970年1月1日00:00:00为计算机起始时刻,所有的计算机时钟最早只能设置到这个时刻。

北京时(东八区)的计算机起始时刻为1970年1月1日08:00:00。

2.7.1 高精度性能计数器

2.7.1.1   QueryPerformanceFrequency(未完成)

函数名称

QueryPerformanceFrequency

头文件

#include <Windows.h>

函数功能

查看当前高精度性能计数器的时钟频率,如果硬件不支持高精度性能计数器本函数会返回失败。

函数声明

BOOL QueryPerformanceFrequency (

LARGE_INTEGER * lpFrequency

);

函数参数

lpFrequency,[输出]:

存放当前高精度性能计数器的时钟频率的共用体变量的内存指针。

返回值

非0:成功。

0:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

高精度性能计数器的时钟频率就是每秒累加多少次,频率越高,精度也就越高。

 

 

2.7.1.2   QueryPerformanceCounter(未完成)

函数名称

QueryPerformanceCounter

头文件

#include <Windows.h>

函数功能

查看当前高精度性能计数器的数值,如果硬件不支持高精度性能计数器本函数会返回失败。

函数声明

BOOL QueryPerformanceCounter (

LARGE_INTEGER * lpPerformanceCount

);

函数参数

lpPerformanceCount,[输出]:

存放当前高精度性能计数器的数值的共用体变量的内存指针。

返回值

非0:成功。

0:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

在多处理器的计算机上,每个处理器都有独立的高精度性能计数器,所以多次调用此函数会返回不同处理器的数值。如果要为线程指定处理器相关性,请使用SetThreadAffinityMask()函数。

当前高精度性能计数器的数值除以时钟频率就是计算机已经运行了多少秒。

记录两个时刻的高精度性能计数器的数值,相减后得出间隔时间,然后除以时钟频率就知道时隔多少秒,多少毫秒,甚至是微秒。

 

 

2.7.2 获取时区

2.7.2.1   GetTimeZoneInformation(未完成)

函数名称

GetTimeZoneInformation

头文件

#include <Windows.h>

库文件

函数功能

获取当前系统的时区。

函数声明

DWORD WINAPI GetTimeZoneInformation (

LPTIME_ZONE_INFORMATION lpTimeZoneInformation

);

函数参数

lpTimeZoneInformation,[输出]:

参数说明。

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.7.3 设置时区

2.7.3.1   SetTimeZoneInformation(未完成)

函数名称

SetTimeZoneInformation

头文件

#include <xxx.h>

#include <xxx.h>

库文件

#pragma comment(lib, "xxx.lib")

函数功能

函数主要功能说明。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.7.4 获取时钟

2.7.4.1   time

函数名称

time

头文件

#include <time.h>

库文件

函数功能

获取当前系统时钟,从计算机起始时刻到现在所走的秒数。

函数声明

time_t time (

time_t * timer

);

__time32_t _time32 (

__time32_t * timer

);

__time64_t _time64 (

__time64_t * timer

);

函数参数

_Time,[输出]:

存放从计算机起始时刻到现在所走的秒数的变量的内存指针,不需要就填为NULL。

返回值

正整数:从计算机起始时刻到现在所走的秒数。

-1:失败。

错误码

线程安全

原子操作

其他说明

本函数是直接获取的秒数,无论在哪个时区都是一样。

如果调用_time32()函数,则当前操作系统的时钟不能超过协调时的2038年1月19日 03:14:07,否则会返回失败。

如果调用_time64()函数,则当前操作系统的时钟不能超过协调时的3000年12月31日 23:59:59,否则会返回失败。

time()函数直接内联到_time64()函数,如果定义了_USE_32BIT_TIME_T宏,则内联到_time32()函数。

 

 

2.7.4.2   GetSystemTimeAsFileTime

函数名称

GetSystemTimeAsFileTime

头文件

#include <Windows.h>

库文件

#pragma comment(lib, "Kernel32.lib")

函数功能

获取当前系统时钟,并转换为文件时间结构体,获取到的是内存缓存时间,比实际时间大约相差1秒。

函数声明

VOID GetSystemTimeAsFileTime (

LPFILETIME lpSystemTimeAsFileTime

);

函数参数

lpSystemTimeAsFileTime,[输出]:

存放当前系统时间的文件时间结构体的内存指针。

返回值

错误码

线程安全

原子操作

其他说明

 

 

 

2.7.4.3   GetTickcount(未完成)

函数名称

GetTickcount

头文件

#include <Winbase.h>

库文件

#pragma comment(lib, "Kernel32.lib")

函数功能

获取从操作系统启动到现在走了多少毫秒,当关机、重启、达到最大值4294967295(约49.71天)后,该值会自动清0。

函数声明

DWORD GetTickCount (

void

);

函数参数

返回值

从操作系统启动到现在走了多少毫秒

错误码

线程安全

原子操作

其他说明

本函数获取的时长不是实时变化的,而是由操作系统每隔10ms至16ms更新一次。

如果担心达到最大值后清0,可以使用GetTickCount64()函数。

 

 

2.7.4.4   GetTickcount64(未完成)

函数名称

GetTickcount64

头文件

#include <Winbase.h>

库文件

#pragma comment(lib, "Kernel32.lib")

函数功能

获取从操作系统启动到现在走了多少毫秒,当关机、重启、达到最大值18446744073709551616(约213503982334.6天)后,该值会自动清0。

函数声明

ULONGLONG GetTickCount (

void

);

函数参数

返回值

从操作系统启动到现在走了多少毫秒

错误码

线程安全

原子操作

其他说明

本函数获取的时长不是实时变化的,而是由操作系统每隔10ms至16ms更新一次。

 

 

2.7.5 设置时钟

2.7.5.1   settimeofday

函数名称

settimeofday

头文件

#include <time.h>

函数功能

设置当前操作系统的时钟和时区。

函数声明

int settimeofday (const struct timeval * tv, const struct timezone * tz);

函数参数

tv,[输入]:将当前操作系统的时钟要设置的时间,从1970年1月1日00:00:00到要设置的时间一共走了多少秒,为NULL表示不设置。

tz,[输入]:要设置当前操作系统的时区信息,为NULL表示不设置。

返回值

0:成功。

-1:失败,并设置errno错误码变量。

线程安全

其他说明

调用此函数需要进程具有root权限。

 

 

2.7.6 时钟转换

2.7.6.1   localtime_s

函数名称

localtime_s

头文件

#include <time.h>

库文件

函数功能

把从本地时的计算机起始时刻到现在所走的秒数转换成日历,并存放到指定的日历结构体。

函数声明

errno_t localtime_s (

struct tm * _Tm,

const time_t * _Time

);

函数参数

_Tm,[输出]:

存放转换后的日历结构体的内存指针,不能为NULL。

_Time,[输入]:

存放秒数变量的内存指针,本地时的计算机起始时刻到现在所走的秒数,不能为NULL。

返回值

0:成功。

EINVAL:失败,日历结构体的内存指针或秒数变量的内存指针是无效的。

错误码

线程安全

原子操作

其他说明

本函数是转换成本地时的,转换成协调时用gmtime_s()函数。

 

 

2.7.6.2   gmtime_s

函数名称

gmtime_s

头文件

#include <time.h>

库文件

函数功能

把从协调时的计算机起始时刻到现在所走的秒数转换成日历,并存放到指定的日历结构体。

函数声明

errno_t gmtime_s (

struct tm * _tm,

const __time_t * time

);

函数参数

_tm,[输出]:

存放转换后日历结构体的内存指针,不能为NULL。

time,[输入]:

存放秒数变量的内存指针,协调时的计算机起始时刻到现在所走的秒数,不能为NULL。

返回值

0:成功。

EINVAL:失败,日历结构体的内存指针或秒数变量的内存指针是无效的。

错误码

线程安全

原子操作

其他说明

本函数是转换成协调时的,转换成本地时用localtime_s()函数。

 

 

2.7.6.3   mktime

函数名称

mktime

头文件

#include <time.h>

库文件

函数功能

把本地时的日历结构体转换为从计算机起始时刻到日历结构体描述的那一时刻所走的秒数。

函数声明

time_t mktime (

struct tm * timeptr

);

__time32_t _mktime32 (

struct tm * timeptr

);

__time64_t _mktime64 (

struct tm * timeptr

);

函数参数

timeptr,[输入]:

存放本地时日历结构体的内存指针,只根据日历结构体的tm_sec、tm_min、tm_hour、tm_mday、tm_mon成员变量转换,不能为NULL。

返回值

-1:失败,调用errno变量查看错误码。

其他:所走的秒数。

错误码

EINVAL:日历结构体的内存指针是无效的,或者要转换的日历超过了范围。

线程安全

原子操作

其他说明

本函数是根据本地时的日历转换的。

如果调用_mktime32()函数,则日历不能超过UTC时间2038年1月19日 03:14:07、CST时间2038年1月19日 11:14:07,否则会返回失败。

如果调用_mktime64()函数,则日历不能超过UTC时间3000年12月31日 23:59:59、CST时间3001年1月1日 7:59:59,否则会返回失败。

mktime()函数直接内联到_mktime64()函数,如果定义了_USE_32BIT_TIME_T宏,则内联到_mktime32()函数。

 

 

2.8 信号

2.8.1 signal(未完成)

函数名称

signal

头文件

#include < signal.h>

函数功能

对指定的信号设置捕捉函数,只会捕捉一次该信号。

函数声明

sighandler_t signal (

    int signum,

    sighandler_t handler

  );

函数参数

signum,[输入]:要捕捉的信号,可以是(选一至一个):

SIGINT:interrupt(Ctrl+C中断)

SIGILL:illegal instruction - invalid function image(非法指令)

SIGFPE:floating point exception(浮点异常)

SIGSEGV:segment violation(段错误)

SIGTERM:Software termination signal from kill(Kill发出的软件终止)

SIGBREAK:Ctrl-Break sequence(Ctrl+Break中断)

SIGABRT:abnormal termination triggered by abort call(Abort)

handler,[输入]:本参数可以是信号捕捉函数的指针,信号捕捉函数声明必须是void sighandler (int signum),信号捕捉函数第一个参数表示捕捉到的信号码,信号捕捉函数只会捕捉一次该信号,如果需要多次捕捉,可以考虑在信号捕捉函数里再次设置指定信号的捕捉函数;本参数也可以是(选一至一个):

SIG_DFL:此信号交由系统缺省捕捉处理,本进程不再捕捉。

SIG_IGN:忽略掉该信号而不做任何处理。

返回值

handler参数:成功。

SIG_ERR:失败,并设置errno。

错误码

EINVAL:参数错误。

线程安全

原子操作

其他说明

SIGKILL和SIGSTOP信号无法被阻塞、捕捉或忽略的。

SIGSEGV和SIGABRT信号捕捉函数是在主线程中执行的,执行时会中断主线程的执行,不会中断进程其他线程的执行,执行完后主线程又回到之前中断的位置继续执行。但是所有的SIGSEGV和SIGABRT信号捕捉函数都是在主线程中执行,如果信号捕捉函数在执行时,进程再次捕捉到SIGSEGV或SIGABRT信号,则立即暂停当前执行的信号捕捉函数,开始执行刚刚捕捉到的信号对应的信号捕捉函数,执行完后再回到之前被暂停的信号捕捉函数继续执行。如果进程再次捕捉到信号,以此类推。如果被暂停的信号捕捉函数非常多的时候,可能会导致堆栈溢出。

SIGINT和SIGBREAK信号捕捉函数是在新的线程中执行的,执行时不会中断进程其他线程的执行。但是所有的SIGINT和SIGBREAK信号捕捉函数都是在同一个线程中执行,如果信号捕捉函数在执行时,进程再次捕捉到SIGINT或SIGBREAK信号,则立即暂停当前执行的信号捕捉函数,开始执行刚刚捕捉到的信号对应的信号捕捉函数,执行完后再回到之前被暂停的信号捕捉函数继续执行。如果进程再次捕捉到信号,以此类推。如果被暂停的信号捕捉函数非常多的时候,可能会造成堆栈溢出。

Windows下不存在信号打断的问题。

 

 

2.9 套接字

2.9.1 WSAStartup(未完成)

函数名称

WSAStartup

头文件

#include <Ws2tcpip.h>

库文件

#pragma comment(lib, "Ws2_32.lib")

函数功能

函数主要功能说明。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.9.2 socket(未完成)

函数名称

socket

头文件

#include <Ws2tcpip.h>

库文件

#pragma comment(lib, "Ws2_32.lib")

函数功能

创建一个套接字句柄。

函数声明

SOCKET socket (

int af,

int type,

int protocol

);

函数参数

af,[输入]:

存放套接字使用的地址族的值,可以为(选一至一个):

AF_UNSPEC宏(0x0000):不指定ADDRESS FAMILY地址族,根据protocol协议参数确定地址族。

AF_INET宏(0x0002):IPv4地址族。

AF_IPX宏(0x0006):IPX/SPX地址族,要求系统必须安装了NWLink IPX/SPX NetBIOS兼容传输协议。Windows Vista及以后的系统都不支持本地址族。

AF_APPLETALK宏(0x0010):AppleTalk地址族,要求系统必须安装了AppleTalk协议。Windows Vista及以后的系统都不支持本地址族。

AF_NETBIOS宏(0x0011):NETBIOS地址族,要求系统必须安装了Windows Sockets provider for NetBIOS。Windows Sockets provider for NetBIOS仅支持32位系统,且32位系统被默认装上。Windows Sockets provider for NetBIOS不支持64位系统(包括Windows 7、Windows Server 2008、Windows Vista、Windows Server 2003、Windows XP)。使用本地址族的套接字协议必须为SOCK_DGRAM。Windows Sockets provider for NetBIOS没有直接关联到NetBIOS编程接口。NetBIOS编程接口在Windows Vista、Windows Server 2008及以后的系统都不支持。

AF_INET6宏(0x0017):IPv6地址族。

AF_IRDA宏(0x001A):红外数据组织(IrDA)地址族,要求操作系统必须安装了红外端口和驱动程序。

AF_BTH宏(0x0020):蓝牙地址族,要求操作系统必须安装了蓝牙适配器和驱动程序。Windows XP SP2及以后的系统才支持本地址族。

type,[输入]:

存放套接字使用的类型的值,可以为(选一至一个):

SOCK_STREAM宏(0x0001):提供有序的、可靠的、双向的、基于连接、并有带外数据的字节流传送机制,af地址族参数必须是AF_INET或AF_INET6,protocol协议参数必须是IPPROTO_TCP。

SOCK_DGRAM宏(0x0002):支持无连接的、不可靠的和使用固定大小(通常很小)缓冲区的数据报传送机制,af地址族参数必须是AF_INET或AF_INET6,protocol协议参数必须是IPPROTO_UDP。

SOCK_RAW宏(0x0003):A socket type that provides a raw socket that allows an application to manipulate the next upper-layer protocol header. To manipulate the IPv4 header, the IP_HDRINCL socket option must be set on the socket. To manipulate the IPv6 header, the IPV6_HDRINCL socket option must be set on the socket.

SOCK_RDM宏(0x0004):A socket type that provides a reliable message datagram. An example of this type is the Pragmatic General Multicast (PGM) multicast protocol implementation in Windows, often referred to as reliable multicast programming.

This type value is only supported if the Reliable Multicast Protocol is installed.

SOCK_SEQPACKET宏(0x0005):A socket type that provides a pseudo-stream packet based on datagrams.

protocol,[输入]:

存放套接字使用的协议的值,可以为(选一至一个):

IPPROTO_ICMP宏(0x0001):ICMP(Internet Control Message Protocol)网络控制消息协议。af地址族参数必须是AF_UNSPEC或AF_INET或AF_INET6,type类型参数必须是SOCK_RAW。Windows XP及以后的系统才支持本协议。

IPPROTO_IGMP宏(0x0002):IGMP(Internet Group Management Protocol)网络组管理协议。af地址族参数必须是AF_UNSPEC或AF_INET或AF_INET6,type类型参数必须是SOCK_RAW。Windows XP及以后的系统才支持本协议。

BTHPROTO_RFCOMM宏(0x0003):Bluetooth RFCOMM(Bluetooth Radio Frequency Communications)蓝牙射频通信协议。af地址族参数必须是AF_BTH,type类型参数必须是SOCK_STREAM。Windows XP SP2及以后的系统才支持本协议。

IPPROTO_TCP宏(0x0006):TCP(Transmission Control Protocol)传输控制协议。af地址族参数必须是AF_INET或AF_INET6,type类型参数必须是SOCK_STREAM。

IPPROTO_UDP宏(0x0011):UDP(User Datagram Protocol)用户数据报协议af地址族参数必须是AF_INET或AF_INET6,type类型参数必须是SOCK_DGRAM。

IPPROTO_ICMPV6宏(0x003A):ICMPv6(Internet Control Message Protocol Version 6)网络控制消息协议版本6。af地址族参数必须是AF_UNSPEC或AF_INET或AF_INET6,type类型参数必须是SOCK_RAW。Windows XP及以后的系统才支持本协议。

IPPROTO_PGM宏(0x0071):PGM(Pragmatic General Multicast Protocol)实际通用多播协议。af地址族参数必须是AF_INET,type类型参数必须是SOCK_RDM。系统需要先安装本协议才支持。

返回值

INVALID_SOCKET宏(-0x0001):失败,调用WSAGetLastError()函数查看错误码。

其他:成功,返回值就是套接字句柄。

错误码

WSANOTINITIALISED必须在调用WSAStartup()函数成功后才能调用本函数。

WSAENETDOWNThe network subsystem or the associated service provider has failed.

WSAEAFNOSUPPORTThe specified address family is not supported. For example, an application tried to create a socket for the AF_IRDA address family but an infrared adapter and device driver is not installed on the local computer.

WSAEINPROGRESSA blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.

WSAEMFILENo more socket descriptors are available.

WSAEINVALAn invalid argument was supplied. This error is returned if the af parameter is set to AF_UNSPEC and the type and protocol parameter are unspecified.

WSAENOBUFSNo buffer space is available. The socket cannot be created.

WSAEPROTONOSUPPORTThe specified protocol is not supported.

WSAEPROTOTYPEThe specified protocol is the wrong type for this socket.

WSAEPROVIDERFAILEDINITThe service provider failed to initialize. This error is returned if a layered service provider (LSP) or namespace provider was improperly installed or the provider fails to operate correctly.

WSAESOCKTNOSUPPORTThe specified socket type is not supported in this address family.

WSAINVALIDPROVIDERThe service provider returned a version other than 2.2.

WSAINVALIDPROCTABLEThe service provider returned an invalid or incomplete procedure table to the WSPStartup.

线程安全

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

 

 

 

2.9.3 accept(未完成)

函数名称

accept

头文件

#include <Winsock2.h>

库文件

#pragma comment(lib, "Ws2_32.lib")

函数功能

函数主要功能说明。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1:[输入|输出|输入&输出],参数说明。

参数2:[输入|输出|输入&输出],参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.9.4 connect(未完成)

函数名称

connect

头文件

#include <Winsock2.h>

库文件

#pragma comment(lib, "Ws2_32.lib")

函数功能

函数主要功能说明。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1:[输入|输出|输入&输出],参数说明。

参数2:[输入|输出|输入&输出],参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.9.5 recv(未完成)

函数名称

recv

头文件

#include <Winsock2.h>

库文件

#pragma comment(lib, "Ws2_32.lib")

函数功能

接收套接字的远端发送过来的数据。

函数声明

int recv(

SOCKET s,

char * buf,

int len,

int flags

);

函数参数

s,[输入]:

存放套接字句柄的值。

buf,[输出]:

存放接收远端发来的数据的内存指针。

len,[输出]:

存放接收远端发来的数据的内存长度,单位字节。

flags,[输出]:

存放其他功能标记的值,可以是(用'|'选零至多个):

MSG_PEEK(0x0002)

如果设置本标记,表示预读接收到的数据。将远端发来的数据复制到buf参数中,但不会将远端发来的数据从接收缓存区中删除。

如果不设置本标记,表示取出接收到的数据。将远端发来的数据复制到buf参数中,并从接收缓存区中删除。

MSG_OOB(0x0001)

如果设置本标记,表示处理OOB带外数据。

如果不设置本标记,表示不处理OOB带外数据。

MSG_WAITALL(0x0008)

如果设置本标记,表示本函数仅当以下事件发生时才返回:

1)   buf参数已经被完全填满。

2)   连接已经关闭。

3)   接收数据的请求已经取消,或有错误发生。

注意:如果操作系统不支持本标记、或套接字为非阻塞模式,则不能设置本标记,否则报WSAEOPNOTSUPP错误。Also, if MSG_WAITALL is specified along with MSG_OOB, MSG_PEEK, or MSG_PARTIAL, then this call will fail with WSAEOPNOTSUPP. This flag is not supported on datagram sockets or message-oriented sockets.

如果不设置本标记,阻塞模式下,表示本函数一旦接收到了数据就返回,非阻塞模式下,有没有接收到数据都返回。

返回值

0:失败,原因为套接字已正常关闭。

SOCKET_ERROR(-0x0001):失败,调用WSAGetLastError()查看错误码。

其他:接收到的数据的长度。

错误码

WSANOTINITIALISED(0x276D):应用程序没有调用WSAStartup()函数,或者WSAStartup()函数失败,因此必须在调用WSAStartup()函数成功后才能调用本函数。

WSAENETDOWN:The network subsystem has failed.

WSAEFAULT:The buf parameter is not completely contained in a valid part of the user address space.

WSAENOTCONN:The socket is not connected.

WSAEINTR:The (blocking) call was canceled through WSACancelBlockingCall.

WSAEINPROGRESS:A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.

WSAENETRESET:For a connection-oriented socket, this error indicates that the connection has been broken due to keep-alive activity that detected a failure while the operation was in progress. For a datagram socket, this error indicates that the time to live has expired.

WSAENOTSOCK:The descriptor is not a socket.

WSAEOPNOTSUPP(0x273D):参考的对象类型不支持尝试的操作。MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, OOB data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only send operations.

WSAESHUTDOWN:The socket has been shut down; it is not possible to receive on a socket after shutdown has been invoked with how set to SD_RECEIVE or SD_BOTH.

WSAEWOULDBLOCK:The socket is marked as nonblocking and the receive operation would block.

WSAEMSGSIZE:The message was too large to fit into the specified buffer and was truncated.

WSAEINVAL:The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled or (for byte stream sockets only) len was zero or negative.

WSAECONNABORTED:The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no longer usable.

WSAETIMEDOUT:The connection has been dropped because of a network failure or because the peer system failed to respond.

WSAECONNRESET:The virtual circuit was reset by the remote side executing a hard or abortive close. The application should close the socket as it is no longer usable. On a UDP-datagram socket, this error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message.

线程安全

原子操作

其他说明

本函数工作原理:

1、  如果是阻塞模式的TCP套接字:

1)   如果接收缓存区中有数据,本函数就会将接收缓存区中数据一次性尽可能多的读取出来,然后就返回成功。

2)   如果接收缓存区中没有数据,本函数就会一直等待到有数据,一次性尽可能多的读取出来,然后就返回成功。

3)   如果接收缓存区的长度为0,就将全部要发送的数据直接传给操作系统,等待操作系统处理完,然后就返回成功。

4)   发送缓存区的长度为0时,阻塞时间将明显增长,比发送缓存区的长度为1时要长很多。这么做可以提升发送数据的实时性,但会降低效率。

2、  如果是非阻塞模式的TCP套接字:

1)   如果发送缓存区能够容纳要发送的数据,本函数就会将要发送的数据一次性写入到发送缓存区,然后就返回成功。

2)   如果发送缓存区不够容纳要发送的数据,本函数就会先将一部分要发送的数据写入到发送缓存区,然后等待操作系统将发送缓存区中的数据取走,再将剩余的要发送的数据写入到发送缓存区,以此类推,直到将全部要发送的数据写入到发送缓存区,然后就返回成功。

但是,如果本函数发现不能在很短的时间内将全部要发送的数据写入到发送缓存区,就不会写入任何数据,然后就返回失败,并报WSAEWOULDBLOCK错误。

3)   如果发送缓存区的长度为0,就将全部要发送的数据直接传给操作系统,等待操作系统处理完,然后就返回成功。

4)   发送缓存区的长度为0时,非阻塞模式的TCP套接字也将阻塞,不会报WSAEWOULDBLOCK错误。这么做可以提升发送数据的实时性,但会降低效率。

 

 

2.9.6 send(未完成)

函数名称

send

头文件

#include <Winsock2.h>

库文件

#pragma comment(lib, "Ws2_32.lib")

函数功能

使用已连接的套接字发送数据给远端。

函数声明

int send (

SOCKET s,

const char * buf,

int len,

int flags

);

函数参数

s,[输入]:

存放套接字句柄的值。

buf,[输入]:

存放要发送的数据的内存指针。

len,[输入]:

存放要发送的数据的内存长度,单位字节。

flags,[输入]:存放发送数据时的标记,可以是(用'|'选零至多个):

MSG_DONTROUTE:Specifies that the data should not be subject to routing. A Windows Sockets service provider can choose to ignore this flag.

MSG_OOB:Sends OOB data (stream-style socket such as SOCK_STREAM only.

返回值

SOCKET_ERROR(-0x0001):失败,调用WSAGetLastError()函数查看错误码。

其他:已成功发送的数据的长度,单位字节,一般和len参数相同,也可能比len参数小。

错误码

WSANOTINITIALISED(0x276D):应用程序没有调用WSAStartup()函数,或者WSAStartup()函数失败,因此必须在调用WSAStartup()函数成功后才能调用本函数。

WSAENETDOWN(0x2742):套接字操作遇到了一个已死的网络。

WSAEACCES(0x271D):以一种访问权限不允许的方式做了一个访问套接字的尝试。The requested address is a broadcast address, but the appropriate flag was not set. Call setsockopt with the SO_BROADCAST socket option to enable use of the broadcast address.

WSAEINTR(0x2714):一个封锁操作被对WSACancelBlockingCall()函数的调用中断。A blocking Windows Sockets 1.1 call was canceled through WSACancelBlockingCall.

WSAEINPROGRESS(0x2734):目前正在执行一个阻止性操作。A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.

WSAEFAULT(0x271E):系统检测到在一个调用中尝试使用指针参数时的无效指针地址。The buf parameter is not completely contained in a valid part of the user address space.

WSAENETRESET(0x2744):当该操作在进行中,由于保持活动的操作检测到一个故障,该连接中断。The connection has been broken due to the keep-alive activity detecting a failure while the operation was in progress.

WSAENOBUFS(0x2747):由于系统缓冲区空间不足或队列已满,不能执行套接字上的操作。No buffer space is available.

WSAENOTCONN(0x2749):由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。The socket is not connected.

WSAENOTSOCK(0x2736):在一个非套接字上尝试了一个操作。The descriptor is not a socket.

WSAEOPNOTSUPP(0x273D):参考的对象类型不支持尝试的操作。MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, OOB data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only receive operations.

WSAESHUTDOWN(0x274A):由于以前的关闭调用,套接字在那个方向已经关闭,发送或接收数据的请求没有被接受。The socket has been shut down; it is not possible to send on a socket after shutdown has been invoked with how set to SD_SEND or SD_BOTH.

WSAEWOULDBLOCK(0x2733):无法立即完成一个非阻止性套接字操作。The socket is marked as nonblocking and the requested operation would block.

WSAEMSGSIZE(0x2738):一个在数据报套接字上发送的消息大于内部消息缓冲区或其他一些网络限制,或该用户用于接收数据报的缓冲区比数据报小。The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.

WSAEHOSTUNREACH(0x2751):套接字操作尝试一个无法连接的主机。The remote host cannot be reached from this host at this time.

WSAEINVAL(0x2726):提供了一个无效的参数。The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled.

WSAECONNABORTED(0x2745):你的主机中的软件中止了一个已建立的连接。The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no longer usable.

WSAECONNRESET(0x2746):远程主机强迫关闭了一个现有的连接。The virtual circuit was reset by the remote side executing a hard or abortive close. For UDP sockets, the remote host was unable to deliver a previously sent UDP datagram and responded with a "Port Unreachable" ICMP packet. The application should close the socket as it is no longer usable.

WSAETIMEDOUT(0x274C):由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。The connection has been dropped, because of a network failure or because the system on the other end went down without notice.

线程安全

原子操作

其他说明

本函数返回成功并不代表远端已经接收到数据,如果想保证对方能收到,建议让远端收到后给回执。

 

本函数工作原理:

1、  如果是阻塞模式的TCP套接字:

1)   如果发送缓存区能够容纳要发送的数据,本函数就会将要发送的数据一次性写入到发送缓存区,然后就返回成功。

2)   如果发送缓存区不够容纳要发送的数据,本函数就会先将一部分要发送的数据写入到发送缓存区,然后等待操作系统将发送缓存区中的数据取走,再将剩余的要发送的数据写入到发送缓存区,以此类推,直到将全部要发送的数据写入到发送缓存区,然后就返回成功。如果发送数据的超时时间已到,也会立即返回,返回值为已发送的数据长度。

3)   如果发送缓存区的长度为0,就将全部要发送的数据直接传给操作系统,等待操作系统处理完,然后就返回成功。如果发送数据的超时时间已到,也会立即返回,返回值为已发送的数据长度。

4)   发送缓存区的长度为0时,阻塞时间将明显增长,比发送缓存区的长度为1时要长很多。这么做可以提升发送数据的实时性,但会降低效率。

2、  如果是非阻塞模式的TCP套接字:

1)   如果发送缓存区能够容纳要发送的数据,本函数就会将要发送的数据一次性写入到发送缓存区,然后就返回成功。

2)   如果发送缓存区不够容纳要发送的数据,本函数就会先将一部分要发送的数据写入到发送缓存区,然后等待操作系统将发送缓存区中的数据取走,再将剩余的要发送的数据写入到发送缓存区,以此类推,直到将全部要发送的数据写入到发送缓存区,然后就返回成功。

但是,如果本函数发现不能在很短的时间内将全部要发送的数据写入到发送缓存区,就不会写入任何数据,然后就返回失败,并报WSAEWOULDBLOCK错误。

3)   如果发送缓存区的长度为0,就将全部要发送的数据直接传给操作系统,等待操作系统处理完,然后就返回成功。

4)   发送缓存区的长度为0时,非阻塞模式的TCP套接字也将阻塞,不会报WSAEWOULDBLOCK错误。这么做可以提升发送数据的实时性,但会降低效率。

 

 

2.9.7 getaddrinfo(未完成)

函数名称

getaddrinfo

头文件

#include <Ws2tcpip.h>

#pragma comment(lib, "Ws2_32.lib")

函数功能

根据指定的主机名和服务名或端口号获取多个地址信息。

函数声明

INT getaddrinfo (

PCSTR pNodeName,

PCSTR pServiceName,

const ADDRINFOA * pHints,

PADDRINFOA * ppResult

);

函数参数

参数1:[输入|输出|输入&输出],参数说明。

参数2:[输入|输出|输入&输出],参数说明。

……

返回值

0:成功。

非0:Windows套接字错误码,也可调用WSAGetLastError()查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

函数功能:

函数声明:int getaddrinfo (const char * node,

const char * service,

const struct addrinfo * hints,

struct addrinfo ** res);

函数参数:参数1:参数说明。

参数2:参数说明。

……

返回值  :0:成功。

EAI_ADDRFAMILY:The specified network host does not have any network addresses in the requested address family.

EAI_AGAIN:The name server returned a temporary failure indication.  Try again later.

EAI_BADFLAGS:ai_flags contains invalid flags.

EAI_FAIL:The name server returned a permanent failure indication.

EAI_FAMILY:The requested address family is not supported at all.

EAI_MEMORY:Out of memory.

EAI_NODATA:The specified network host exists, but does not have any network addresses defined.

EAI_NONAME:The node or service is not known; or both node and service are NULL; or AI_NUMERICSERV was specified in hints.ai_flags and service was not a numeric port-number string.

EAI_SERVICE:The requested service is not available for the requested socket type.  It may be available through another socket type.

EAI_SOCKTYPE:The requested socket type is not supported at all.

EAI_SYSTEM:Other system error, check errno for details.

线程安全:

注意事项:

……

……

 

 

2.9.8 getnameinfo(未完成)

头文件  :#include <sys/socket.h>

#include <netdb.h>

函数名称:getnameinfo

函数功能:函数主要功能说明。

函数声明:int getnameinfo (const struct sockaddr * sa,

socklen_t salen,

char *host,

size_t hostlen,

                           char *serv,

size_t servlen,

int flags);

函数参数:

 

返回值  :0:成功。

EAI_AGAIN:The name could not be resolved at this time.  Try again later.

EAI_BADFLAGS:The flags argument has an invalid value.

EAI_FAIL:A nonrecoverable error occurred.

EAI_FAMILY:The address family was not recognized, or the address length was invalid for the specified family.

EAI_MEMORY:Out of memory.

EAI_NONAME:The name does not resolve for the supplied arguments. NI_NAMEREQD is set and the host's name cannot be located, or neither hostname nor service name were requested.

EAI_OVERFLOW:The buffer pointed to by host or serv was too small.

EAI_SYSTEM:A system error occurred.  The error code can be found in errno.

线程安全:

注意事项:

 

 

 

2.9.9 getifaddrs(未完成)

头文件  :#include <sys/types.h>

#include <ifaddrs.h>

函数名称:getifaddrs

函数功能:获取网络设备的IP地址。

函数声明:int getifaddrs (struct ifaddrs ** ifap);

函数参数:0:成功。

-1:失败,并设置errno错误码变量。

返回值  :返回值1:返回值说明。

返回值2:返回值说明。

……

线程安全:是 或 否 或 未知

注意事项:

struct ifaddrs  

{  

  struct ifaddrs    * ifa_next;      //指向链表的下一个成员

  char              * ifa_name;      //网络设备名字符串

  unsigned int        ifa_flags;     //Flags from SIOCGIFFLAGS

  struct sockaddr   * ifa_addr;      //Address of interface

  struct sockaddr   * ifa_netmask;   //Netmask of interface

  union

  {

    struct sockaddr * ifu_broadaddr; // Broadcast address of interface

    struct sockaddr * ifu_dstaddr;   // Point-to-point destination address

  }ifa_ifu;

  #define             ifa_broadaddr ifa_ifu.ifu_broadaddr

  #define             ifa_dstaddr   ifa_ifu.ifu_dstaddr

  void              * ifa_data;      // Address-specific data

};

ifa_next指向链表的下一个成员;ifa_name是接口名称,以0结尾的字符串,比如eth0,lo;ifa_flags是接口的标识位(比如当IFF_BROADCAST或IFF_POINTOPOINT设置到此标识位时,影响联合体变量ifu_broadaddr存储广播地址或ifu_dstaddr记录点对点地址);ifa_netmask存储该接口的子网掩码;结构体变量存储广播地址或点对点地址(见括弧介绍ifa_flags);ifa_data存储了该接口协议族的特殊信息,它通常是NULL(一般不关注他)。

使用完后,必须使用freeifaddrs()函数释放内存。

 

 

2.9.10   select(未完成)

函数名称

select

头文件

#include <Winsock2.h>

库文件

#pragma comment(lib, "Ws2_32.lib")

函数功能

阻塞检查一个或多个套接字是否处于可读状态、可写状态、异常状态。

函数声明

int select (

int nfds,

fd_set * readfds,

fd_set * writefds,

fd_set * exceptfds,

const struct timeval * timeout

);

函数参数

nfds,[输入]:

本参数无意义,只是为了兼容伯克利套接字。

readfds,[输入]:

存放需要检查是否处于可读状态的套接字集,如果为NULL,表示不检查可读状态。

可读状态分为:

如果TCP服务端套接字处于监听状态,表示可以接受TCP连接请求,如果调用accept()函数会立即返回。

表示套接字可以接收数据,包括带外数据(如果打开SO_OOBINLINE选项),可以调用recv()、WSARecv()、WSARecvFrom()、recvfrom()函数接收到数据。

表示已经连接的TCP套接字已经被关闭、重置、或终止,如果调用recv()、WSARecv()、WSARecvFrom()、recvfrom()函数会立即返回。

writefds,[输入]:

存放需要检查是否处于可写状态的套接字集,如果为NULL,表示不检查可写状态。

可写状态分为:

如果套接字处于正在连接中(非阻塞套接字调用connect()函数后),表示连接成功,并可以调用send()、sendto()函数发送出数据。

表示套接字可以发送数据,可以调用send()、sendto()函数发送出数据。

exceptfds,[输入]:

存放需要检查是否处于异常状态的套接字集,如果为NULL,表示不检查异常状态。

异常状态分为:

表示套接字可以接收带外数据(如果关闭SO_OOBINLINE选项)。

如果套接字处于正在连接中(非阻塞套接字调用connect()函数后),表示连接失败。

表示已经连接的TCP套接字已经被关闭、重置、或终止。

timeout,[输入]:

存放阻塞检查的超时时间。

如果为0秒0毫秒,表示不阻塞立即完成。

如果为NULL,表示不限制超时时间。

返回值

SOCKET_ERROR宏(-0x0001):失败,并清空所有套接字集,调用WSAGetLastError()函数查看错误码。

0:成功,不清空任何套接字集,但在阻塞检查的超时时间内没有任何套接字处于需要检查的状态。

大于0:成功,三个套接字集一共有多少个套接字处于需要检查的状态,并把每个套接字集中不处于需要检查的状态的套接字删除掉,只保留处于需要检查的状态的套接字,调用FD_ISSET()宏函数判断。

错误码

WSANOTINITIALISED:必须在调用WSAStartup()函数成功后才能调用本函数。

WSAEFAULT:The Windows Sockets implementation was unable to allocate needed resources for its internal operations, or the readfds, writefds, exceptfds, or timeval parameters are not part of the user address space.

WSAENETDOWN:The network subsystem has failed.

WSAEINVAL:The time-out value is not valid, or all three descriptor parameters were null.

WSAEINTR:A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.

WSAEINPROGRESS:A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.

WSAENOTSOCK:One of the descriptor sets contains an entry that is not a socket.

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

套接字集使用方法:

FD_SETSIZE:定义一个套接字集结构体变量最多容纳多少个套接字,默认为64,如果需要修改本宏,应在定义套接字集结构体变量前修改。

fd_set stFdset;:定义套接字集结构体变量。

FD_ZERO (fd_set * fdset) 宏函数:清空fdset套接字集内的所有套接字。

FD_SET (int fd, fd_set * fdset) 宏函数:向fdset套接字集内添加一个fd套接字。

FD_CLR (int fd, fd_set * fdset) 宏函数:从fdset套接字集内删除一个fd套接字。

FD_ISSET (int fd, fd_set * fdset) 宏函数:判断fdset套接字集内是否存在fd套接字,返回值为非0表示存在,为0表示不存在。

 

 

2.9.11   getsockopt(未完成)

函数名称

getsockopt

头文件

#include <Winsock2.h>

库文件

#pragma comment(lib, "Ws2_32.lib")

函数功能

获取指定的套接字选项的值。

函数声明

int getsockopt(

SOCKET s,

int level,

int optname,

char FAR * optval,

int FAR * optlen

);

函数参数

s,[输入]:

存放套接字句柄。

level,[输入]:

存放套接字选项的等级。

optname,[输入]:

存放套接字选项的名称。

optval,[输出]:

存放获取到的套接字选项的值的变量的内存指针。

optlen,[输入&输出]:

输入时,存放获取到的套接字选项的值的变量的内存长度的变量的内存指针。

输出时,存放实际获取到的套接字选项的值的变量的内存长度。

返回值

0:成功。

SOCKET_ERROR:失败,调用WSAGetLastError()函数查看错误码。

错误码

WSANOTINITIALISED:应用程序没有调用WSAStartup()函数,或者WSAStartup()函数失败,因此必须在调用WSAStartup()函数成功后才能调用本函数。

WSAENETDOWN:Note  The network subsystem has failed.

WSAEFAULT:One of the optval or the optlen parameters is not a valid part of the user address space, or the optlen parameter is too small.

WSAEINPROGRESS:A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.

WSAEINVAL:套接字选项的等级是未知的或无效的。

WSAENOPROTOOPT:在指定的套接字选项在套接字选项的等级中是未知的或不支持的。

WSAENOTSOCK:指定的不是一个套接字句柄。

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.9.12   WSAGetLastError(未完成)

函数名称

WSAGetLastError

头文件

#include <Winsock2.h>

库文件

#pragma comment(lib, "Ws2_32.lib")

函数功能

获取当前线程最近一次Winsock套接字操作的错误码。

函数声明

int WSAGetLastError(

void

);

函数参数

返回值

当前线程最近一次Winsock套接字操作的错误码。

错误码

线程安全

原子操作

其他说明

 

 

 

2.9.13   WSASetLastError(未完成)

函数名称

WSASetLastError

头文件

#include <Winsock2.h>

库文件

#pragma comment(lib, "Ws2_32.lib")

函数功能

设置当前线程最近一次Winsock套接字操作的错误码。

函数声明

int WSASetLastError(

int iError

);

函数参数

iError,[输入]:

存放Winsock套接字操作的错误码。

返回值

错误码

WSANOTINITIALISED:应用程序没有调用WSAStartup()函数,或者WSAStartup()函数失败,因此必须在调用WSAStartup()函数成功后才能调用本函数。

线程安全

原子操作

其他说明

通过本函数设置后,后续的Winsock套接字操作可能会再次修改错误码。

 

 

2.10  软硬件设备

2.10.1   通用

2.10.1.1 DeviceIoControl(未完成)

函数名称

DeviceIoControl

头文件

#include <Windows.h>

函数功能

直接发送控制代码到指定的设备,让该设备来执行相应的操作。

函数声明

BOOL DeviceIoControl (

HANDLE hDevice,

DWORD dwIoControlCode,

LPVOID lpInBuffer,

DWORD nInBufferSize,

LPVOID lpOutBuffer,

DWORD nOutBufferSize,

LPDWORD lpBytesReturned,

LPOVERLAPPED lpOverlapped

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.10.1.2 NtQuerySystemInformation(未完成)

函数名称

NtQuerySystemInformation

头文件

#include <Winternl.h>

#include <Ntstatus.h>

库文件

#pragma comment(lib, "Ntdll.lib")

函数功能

函数主要功能说明。

函数声明

NTSTATUS NtQuerySystemInformation (

SYSTEM_INFORMATION_CLASS SystemInformationClass,

PVOID SystemInformation,

ULONG SystemInformationLength,

PULONG ReturnLength

);

函数参数

SystemInformationClass,[输入]:

存放要获取什么类型的系统信息的标记,可以为(选一至一个):

SystemBasicInformation枚举(0):

Returns the number of processors in the system in a SYSTEM_BASIC_INFORMATION structure. Use the GetSystemInfo function instead.

SystemPerformanceInformation枚举(2)

Returns an opaque SYSTEM_PERFORMANCE_INFORMATION structure that can be used to generate an unpredictable seed for a random number generator. Use the CryptGenRandom function instead.

SystemTimeOfDayInformation枚举(3)

Returns an opaque SYSTEM_TIMEOFDAY_INFORMATION structure that can be used to generate an unpredictable seed for a random number generator. Use the CryptGenRandom function instead.

SystemProcessInformation枚举(5)

获取所有进程的进程信息,并存放到SYSTEM_PROCESS_INFORMATION结构体数组中,用结构体的NextEntryOffset成员变量遍历数组。

进程信息包括进程使用的处理数、峰值页面文件的使用量以及进程已分配的内存页的数量等。

SystemProcessorPerformanceInformation枚举(8)

获取每个CPU处理器核心的的当前累计的空闲时间、内核时间、用户时间,并存放到SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION结构体数组中。

用本函数ReturnLength参数返回的长度除以单个SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION结构体的长度,就是SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION结构体数组的元素个数,也就是CPU核心总数。

SystemInterruptInformation枚举(23)

Returns an opaque SYSTEM_INTERRUPT_INFORMATION structure that can be used to generate an unpredictable seed for a random number generator. Use the CryptGenRandom function instead.

SystemExceptionInformation枚举(33):

Returns an opaque SYSTEM_EXCEPTION_INFORMATION structure that can be used to generate an unpredictable seed for a random number generator. Use the CryptGenRandom function instead.

SystemRegistryQuotaInformation枚举(37)

Returns a SYSTEM_REGISTRY_QUOTA_INFORMATION structure.

SystemLookasideInformation枚举(45)

Returns an opaque SYSTEM_LOOKASIDE_INFORMATION structure that can be used to generate an unpredictable seed for a random number generator. Use the CryptGenRandom function instead.

SystemQueryPerformanceCounterInformation枚举(134)

Returns a SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION structure that can be used to determine whether the system requires a kernel transition to retrieve the high-resolution performance counter information through a QueryPerformanceCounter function call.

SystemInformation,[输入&输出]:

参数说明。

SystemInformationLength,[输入]:

存放指定的信息结构体的内存长度,单位字节。

ReturnLength,[输出]:

存放写入了多少字节的数据到指定的信息结构体。如果指定的信息结构体的长度不够放下实际的数据,则不会写入任何数据到指定的信息结构体,但本参数还是会返回需要写入多少字节的数据。

返回值

大于等于0:成功,返回值就是成功码。

小于0:失败,返回值就是错误码。

错误码

STATUS_SUCCESS宏(0x0):成功。

STATUS_INFO_LENGTH_MISMATCH宏(0xC0000004):指定的信息结构体的长度不够放下实际的数据。

……

线程安全

原子操作

其他说明

 

 

 

2.10.2   CPU处理器

系统在使用CPU处理器时,分为几个模式使用,当没有任何进程要使用时,系统就让CPU处理器执行空闲线程,此时CPU处理器就处于空闲状态,当有进程在用户模式下执行时,CPU处理器就处于用户状态下,当有进程在内核模式下运行时,CPU处理器就处于内核状态下。

空闲状态、用户状态、内核状态所占用的时间,就叫空闲时间、用户时间、内核时间。

2.10.2.1 GetSystemTimes(未完成)

函数名称

GetSystemTimes

头文件

#include <Windows.h>

函数功能

获取CPU处理器的当前累计的空闲时间、内核时间、用户时间。

函数声明

BOOL GetSystemTimes (

LPFILETIME lpIdleTime,

LPFILETIME lpKernelTime,

LPFILETIME lpUserTime

);

函数参数

lpIdleTime,[输出]:

存放当前累计的空闲时间。

lpKernelTime,[输出]:

存放当前累计的空闲时间与内核时间之和。

lpUserTime,[输出]:

存放当前累计的用户时间。

返回值

非0:成功。

0:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

本函数获取到的时间都是FILETIME结构体,如果需要浮点型的数值,需要进行转换。

如果要计算CPU处理器的使用率,就是100 - 空闲时间 / (用户时间 + 空闲时间 + 内核时间) * 100.0。

 

 

2.10.3   MEM内存

2.10.3.1 内存概念

2.10.3.1.1    进程的内存

 

图一

对于系统中的每一个进程而言,都有 4GB 的 "内存空间"。也就是每个进程都认为自己有 4GB 的内存可以使用。

系统将每个进程的 4GB 地址空间,从逻辑上划分为两大部分:

1) 蓝色的用户空间,此空间是被用户程序所使用的。比如我在代码中写“分配100MB内存”,其实占用的就是这一部分。

2) 红色的内核空间,此空间是被用作操作系统执行必要的线程切换以及从用户态函数进入内核态执行功能所保留的内存地址. 应用程序无法操作此区域。

2.10.3.1.2    Intel x86 体系内存管理

Intel 规定, 一个在计算机内部, 可以使用 "分页机制" 对硬件内存进行 "虚拟化". 其核心技术如下图:

 

图二

首先, 在程序中的一个地址 0x1234, 5678 被计算机的页部件(硬件)经过 1,2,3 步, 从线性地址(程序中的地址) 转变为真正机器上的物理地址(即实际内存的硬件地址). 每个线性地址都被分成 "页目录索引(PDE, 10-bit)", "页表索引(PTE, 10-bit)", "页内偏移(offset, 12-bit)" 三部分.

1) 在页目录中根据 PDE 找到页表的位置, 即通过 0x48 找到 0xa000, 0000.

2) 根据页表中的 PTE 找到页地址, 即通过 0x345 找到 0x4000, 0000.

3) 根据偏移, 在页中找到我们要的具体地址, 即已知页位于 0x4000, 0000, 我们需要存取其 0x678 偏移处的数据, 则我们所需要操作的真是物理地址就是 0x4000, 0678.

2.10.3.1.3    基于 x86 的 Windows 内存管理

 

图 3

首先澄清两个概念:

  1. 一个进程中的内存有三种分类, 空闲, 保留, 提交. 具体的含义可以在 图 3 中找到说明. 这三种类型的内存在某一时刻可能位于内存中, 也可能位于交换文件中.

  2. 工作集定义: The working set of a process is the set of pages in the virtual address space of the process that are currently resident in physical memory. 即: 实际在物理内存中的大小.

结合实际系统, 以我家安装的 win8.1 为例, 打开任务管理器, 可见如下:

 

                         图 4

工作集(内存): 可以这么理解, 此值就是该进程所占用的总物理内存. 但是这个值是由两部分组成, 即 '专用工作集' + '共享工作集'.

内存(专用工作集): 这对于一个进程是最重要的, 它代表了一个进程独占用了多少内存. 

内存(共享工作集): 这是该进程和别的进程共享的内存量. 通常, 这是加载一个 dll 所占用的内存. 

提交大小: 属于 Committed 那一类. 但是不一定在物理内存中, 有些可能位于交换文件中. 如果有一个程序, 原本占 500MB 内存, 但是绝大多数内存都不使用, 则可以通过 `EmptyWorkingSet` 向操作系统发送请求, 将此进程的不常用的内容从物理内存中换出到换页文件中保存, 如下图:

 

                  图 5

2.10.3.1.4    写在最后

0. 工作集, 即在物理内存中的数据的集合.

1. 工作集 = 专用 + 共享

2. 将所有的 "工作集" 相加后的值会大于任务管理器中内存占用的百分比, 因为百分比对共享内存进行排重了.

3. "提交大小" 和 "工作集" 是两个层面的概念, 大部分活跃进程的 "工作集" 会大于 "提交大小", 而大部分非活跃的进程 "工作集" 会小于 "提交大小", 但是两者没有绝对关系.

4. 虚拟内存: 就是换页文件.

2.10.3.2 GlobalMemoryStatus(未完成)

函数名称

GlobalMemoryStatus

头文件

#include <Windows.h>

函数功能

获取系统当前物理内存和虚拟内存的相关信息。

函数声明

void GlobalMemoryStatus (

LPMEMORYSTATUS lpBuffer

);

函数参数

lpBuffer,[输出]:

存放物理内存和虚拟内存的相关信息的结构体的内存指针。

返回值

错误码

线程安全

原子操作

其他说明

本函数只能获取内存大小不超过4GB的相关信息,如果要获取内存大小超过4GB的相关信息,可以调用GlobalMemoryStatusEx()函数。

 

 

2.10.4   网络接口和网络适配器

GetIfEntry() 获取本机一个指定网络接口或网络设备的索引序号的信息。

类型为PPP协议的宽带连接的网络适配器,在没有连接时,操作状态为已禁用。

2.10.4.1 GetIfTAble(未完成)

函数名称

GetIfTAble

头文件

#include <Iphlpapi.h>

#pragma comment(lib, "Iphlpapi.lib")

函数功能

获取本机所有网络接口和网络适配器的状态信息。

函数声明

DWORD GetIfTable (

PMIB_IFTABLE pIfTable,

PULONG pdwSize,

BOOL bOrder

);

函数参数

pIfTable,[输出]:

存放MIB_IFTABLE结构体数组的内存指针。

本参数用于存放本机所有网络接口和网络适配器的状态信息,本参数应该是先由程序调用malloc()等函数分配的内存。

pdwSize,[输入&输出]:

输入时,存放pIfTable参数指定的MIB_IFTABLE结构体数组的内存长度的变量的内存指针,单位字节。

输出时,存放输出了多少长度的数据到pIfTable参数指定的MIB_IFTABLE结构体数组里,如果MIB_IFTABLE结构体数组的内存长度不够,则不会输出任何数据到MIB_IFTABLE结构体数组里,但本参数任然会在输出时存放MIB_IFTABLE结构体数组的内存最小长度。

bOrder,[输入]:

存放是否需要根据网络设备的索引序号将MIB_IFTABLE结构体数组里的状态信息排序。

非0表示排序,0表示不排序。

返回值

ERROR_SUCCESS宏(0):成功。

ERROR_INSUFFICIENT_BUFFER宏(122):失败,MIB_IFTABLE结构体的内存长度不够,查看pdwSize参数获取最小长度。

ERROR_INVALID_PARAMETER宏(87):失败,错误的参数,pdwSize参数为NULL,或本函数的调用进程无法读写pIfTable参数或pdwSize参数指定的内存。

ERROR_NOT_SUPPORTED宏(50):失败,操作系统不受支持。

错误码

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

本函数一般需要调用两次,第一次pIfTable参数填NULL,pdwSize参数填的存放内存长度的变量为0。然后本函数返回后,再根据pdwSize参数存放的内存最小长度分配pIfTable参数指定的内存,最后再调用本函数就能成功。也有可能第二次调用的时候情况发生了变化,导致分配的内存长度还是不够,就需要不停的重新分配内存,直到本函数调用成功为止。如果是其他错误,则应该报错跳出循环。

 

 

2.10.4.2 GetAdaptersInfo(未完成)

函数名称

GetAdaptersInfo

头文件

#include <Iphlpapi.h>

#pragma comment(lib, "Iphlpapi.lib")

函数功能

获取本机所有网络适配器的配置信息。

只获取已启用的网络适配器,不获取已禁用的网络适配器。

不获取网络接口、回环网络适配器。

函数声明

DWORD GetAdaptersInfo (

PIP_ADAPTER_INFO pIfTable,

PULONG dwOutBufLen

);

函数参数

pIfTable,[输出]:

存放IP_ADAPTER_INFO结构体链表的内存指针。

本参数用于存放本机所有网络适配器的配置信息,本参数应该是先由程序调用malloc()等函数分配的内存。

dwOutBufLen,[输入&输出]:

输入时,存放pIfTable参数指定的IP_ADAPTER_INFO结构体链表的内存长度的变量的内存指针,单位字节。

输出时,存放输出了多少长度的数据到pIfTable参数指定的IP_ADAPTER_INFO结构体链表里,如果IP_ADAPTER_INFO结构体链表的内存长度不够,则不会输出任何数据到IP_ADAPTER_INFO结构体链表里,但本参数任然会在输出时存放IP_ADAPTER_INFO结构体链表的内存最小长度。

返回值

ERROR_SUCCESS宏(0):成功。

ERROR_BUFFER_OVERFLOW宏(111):失败,MIB_IFTABLE结构体的内存长度不够,查看dwOutBufLen参数获取最小长度。

ERROR_INVALID_DATA宏(13):失败,本函数获取到的网络适配器信息是无效的。

ERROR_INVALID_PARAMETER宏(87):失败,错误的参数,dwOutBufLen参数为NULL,或本函数的调用进程无法读写pIfTable参数或dwOutBufLen参数指向的内存。

ERROR_NO_DATA宏(232):失败,本机没有任何已启用的网络适配器。

ERROR_NOT_SUPPORTED宏(50):失败,操作系统不受支持。

其他:通过调用FormatMessage()函数查看错误提示信息。

错误码

见返回值

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

本函数一般需要调用两次,第一次pIfTable参数填NULL,pdwSize参数填的存放内存长度的变量为0。然后本函数返回后,再根据pdwSize参数存放的内存最小长度分配pIfTable参数指定的内存,最后再调用本函数就能成功。也有可能第二次调用的时候情况发生了变化,导致分配的内存长度还是不够,就需要不停的重新分配内存,直到本函数调用成功为止。如果是其他错误,则应该报错跳出循环。

 

 

2.10.4.3 GetInterfaceInfo(未完成)

函数名称

GetInterfaceInfo

头文件

#include <Iphlpapi.h>

#pragma comment(lib, "Iphlpapi.lib")

函数功能

获取本机所有启用了IPv4协议的物理和虚拟的网络适配器的名称和索引序号,不获取任何其他信息。

只获取已启用的网络适配器,不获取已禁用的网络适配器。

不获取回环网络适配器。

只获取安装并启用了IPv4协议的网络适配器,不获取安装了但未启用IPv4协议的网络适配器。

函数声明

DWORD GetInterfaceInfo (

PIP_INTERFACE_INFO pIfTable,

PULONG dwOutBufLen

);

函数参数

pIfTable,[输入]:

存放IP_INTERFACE_INFO动态结构体的内存指针。

本参数用于存放本机所有启用了IPv4协议的物理和虚拟的网络适配器的名称和索引序号,本参数应该是先由程序调用malloc()等函数分配的内存。

dwOutBufLen,[输入&输出]:

输入时,存放pIfTable参数指定的IP_INTERFACE_INFO动态结构体的内存长度的变量的内存指针,单位字节。

输出时,存放输出了多少长度的数据到pIfTable参数指定的IP_INTERFACE_INFO动态结构体里,如果IP_INTERFACE_INFO动态结构体的内存长度不够,则不会输出任何数据到IP_INTERFACE_INFO动态结构体里,但本参数任然会在输出时存放IP_INTERFACE_INFO动态结构体的内存最小长度。

返回值

ERROR_SUCCESS宏(0):成功。

ERROR_INSUFFICIENT_BUFFER宏(122):失败,IP_INTERFACE_INFO结构体的内存长度不够,查看dwOutBufLen参数获取最小长度。

ERROR_INVALID_PARAMETER宏(87):失败,错误的参数,dwOutBufLen参数为NULL,或本函数的调用进程无法读写pIfTable参数或dwOutBufLen参数指定的内存。

ERROR_NO_DATA宏(232):失败,本机没有任何已启用的网络适配器。

ERROR_NOT_SUPPORTED宏(50):失败,操作系统不受支持。

其他:通过调用FormatMessage()函数查看错误提示信息。

错误码

见返回值

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

本函数一般需要调用两次,第一次pIfTable参数填NULL,pdwSize参数填的存放内存长度的变量为0。然后本函数返回后,再根据pdwSize参数存放的内存最小长度分配pIfTable参数指定的内存,最后再调用本函数就能成功。也有可能第二次调用的时候情况发生了变化,导致分配的内存长度还是不够,就需要不停的重新分配内存,直到本函数调用成功为止。如果是其他错误,则应该报错跳出循环。

 

 

2.10.5   性能计数器

Performance Counters性能计数器可以统计硬件设备的各项性能指标。在Windows 2000及以上系统中,可以在“控制面板-〉管理-〉性能”中看到该程序,在绘图界面上点击鼠标右击,选择“添加计数器”就有可能看到所有可统计的项目。

性能计数器可以实时统计硬件设备的各项性能指标,常常在论坛里看到一些新朋友问如何自己实现任务管理器,及如何实时获得每个进程的CPU使用率,内存使用...等等,那么使用系统性能计数器应该是最佳选择。

MSDN:http://msdn.microsoft.com/en-us/library/windows/desktop/aa373078(v=vs.85).aspx

 

使用性能计数器的基本步骤:

1.创建计数器PdhOpenQuery()。

3.把感兴趣的计数器添加进来PdhAddCounter()。

4.收集数据PdhCollectQueryData()。

5.得到计数器的数值PdhGetFormattedCounterValue()。

6.关闭计数器PdhCloseQuery()。

 

CPU性能计数器:

\Processor(_Total)\% Processor Time

\Processor(_Total)\% User Time

\Processor(_Total)\% Privileged Time

\Processor(_Total)\Interrupts/sec

\Processor(_Total)\% DPC Time

\Processor(_Total)\% Interrupt Time

\Processor(_Total)\DPCs Queued/sec

\Processor(_Total)\DPC Rate

\Processor(_Total)\% Idle Time

 

内存性能计数器:

\Memory\Page Faults/sec

\Memory\Available Bytes

\Memory\Pages/sec

\Memory\Pages Input/sec

\Memory\Page Reads/sec

\Memory\Pages Output/sec

\Memory\Page Writes/sec

\Memory\Cache Bytes

\Memory\System Code Total Bytes

\Memory\Available MBytes

 

网络性能计数器:

\Network Interface(Realtek RTL8139 Family PCI Fast Ethernet NIC)\Bytes Received/sec

\Network Interface(Realtek RTL8139 Family PCI Fast Ethernet NIC)\Bytes Sent/sec

\Network Interface(Realtek RTL8139 Family PCI Fast Ethernet NIC)\Bytes Total/sec

 

逻辑分区性能计数器:

\LogicalDisk(_Total)\Disk Reads/sec         分区每秒读取次数

\LogicalDisk(_Total)\Disk Read Bytes/sec    分区每秒读取字节数

\LogicalDisk(_Total)\Disk Writes/sec        分区每秒写入次数

\LogicalDisk(_Total)\Disk Write Bytes/sec   分区每秒写入字节数

 

物理硬盘性能计数器:

\PhysicalDisk(_Total)\% Disk Time           硬盘使用率

\PhysicalDisk(_Total)\Disk Reads/sec        硬盘每秒读取次数

\PhysicalDisk(_Total)\Disk Read Bytes/sec   硬盘每秒读取字节数

\PhysicalDisk(_Total)\Disk Writes/sec       硬盘每秒写入次数

\PhysicalDisk(_Total)\Disk Write Bytes/sec  硬盘每秒写入字节数

 

 

2.10.5.1 PdhOpenQuery(未完成)

函数名称

PdhOpenQuery

头文件

#include <Pdh.h>

#pragma comment(lib, "Pdh.lib")

函数功能

创建一个性能计数器的查询句柄,查询句柄用于统一管理各项性能指标的数值。

函数声明

PDH_STATUS PdhOpenQuery (

LPCTSTR szDataSource,

DWORD_PTR dwUserData,

PDH_HQUERY * phQuery

);

函数参数

szDataSource,[输入]:

存放性能计数器的日志文件路径,该日志里存放着各项性能指标的数值。

如果为NULL,表示直接从实时数据源获取各项性能指标的数值。

dwUserData,[输入]:

User-defined value to associate with this query. To retrieve the user data later, call PdhGetCounterInfo and access the dwQueryUserData member of PDH_COUNTER_INFO.

可以为NULL。

phQuery,[输出]:

存放性能计数器的查询句柄,后续用于管理各项性能指标的数值。

返回值

ERROR_SUCCESS:成功。

其他:失败,返回值就是错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.10.5.2 PdhAddCounter(未完成)

函数名称

PdhAddCounter

头文件

#include <Pdh.h>

#pragma comment(lib, "Pdh.lib")

函数功能

创建一个计数器,并添加到查询句柄。

计数器用于表示要查询哪项性能指标,添加到查询句柄后,由查询句柄统一收集该查询句柄下的所有计数器的数值。

函数声明

PDH_STATUS PdhAddCounter (

PDH_HQUERY hQuery,

LPCTSTR szFullCounterPath,

DWORD_PTR dwUserData,

PDH_HCOUNTER * phCounter

);

函数参数

hQuery,[输入]:

存放查询句柄的值。

szFullCounterPath,[输入]:

存放计数器路径字符串的内存指针。

格式:"\\Computer\PerfObject(ParentInstance/ObjectInstance#InstanceIndex)\Counter"。

dwUserData,[输入]:

User-defined value. This value becomes part of the counter information. To retrieve this value later, call the PdhGetCounterInfo function and access the dwUserData member of the PDH_COUNTER_INFO structure.

可以为NULL。

phCounter,[输出]:

存放计数器句柄的内存指针。

返回值

ERROR_SUCCESS:成功。

其他:失败,返回值就是错误码。

错误码

PDH_CSTATUS_BAD_COUNTERNAME宏:计数器路径字符串无法解析或解释.

PDH_CSTATUS_NO_COUNTER宏:在指定的计算机或性能计数器的日志文件里,未被找到指定的计数器。

PDH_CSTATUS_NO_COUNTERNAME宏:计数器路径字符串是空的。

PDH_CSTATUS_NO_MACHINE宏:The path did not contain a computer name, and the function was unable to retrieve the local computer name.

PDH_CSTATUS_NO_OBJECTUnable to find the specified object on the computer or in the log file.

PDH_FUNCTION_NOT_FOUNDUnable to determine the calculation function to use for this counter.

PDH_INVALID_ARGUMENT宏:一个或多个参数是无效的。

PDH_INVALID_HANDLE宏:查询句柄是无效的。

PDH_MEMORY_ALLOCATION_FAILURE宏:无法分配足够的内存来完成本函数的操作。

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

同一个查询句柄可以添加多个计数器。

 

 

2.10.5.3 PdhRemoveCounter(未完成)

函数名称

PdhRemoveCounter

头文件

#include <Pdh.h>

#pragma comment(lib, "Pdh.lib")

函数功能

从查询句柄里移除一个计数器,并关闭该计数器。

移除后该计数器句柄会变成无效句柄,且不能再被使用。

函数声明

PDH_STATUS PdhRemoveCounter (

PDH_HCOUNTER hCounter

);

函数参数

hCounter,[输入]:

存放计数器句柄的值。

返回值

ERROR_SUCCESS:成功。

其他:失败,返回值就是错误码。

错误码

PDH_INVALID_HANDLE:计数器句柄是无效的。

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.10.5.4 PdhCollectQueryData(未完成)

函数名称

PdhCollectQueryData

头文件

#include <Pdh.h>

#pragma comment(lib, "Pdh.lib")

函数功能

收集一个查询句柄里所有计数器的数值。收集完后,需要调用PdhGetFormattedCounterValue()函数来获取指定计数器的数值。

函数声明

PDH_STATUS PdhCollectQueryData (

PDH_HQUERY hQuery

);

函数参数

hQuery,[输入]:

存放查询句柄的值。

返回值

ERROR_SUCCESS:成功。

其他:失败,返回值就是错误码。

错误码

PDH_INVALID_HANDLE:无效的查询句柄。

PDH_NO_DATA:查询句柄没有添加任何计数器,或者没有收集到任何计数器的数值,可能因为权限不足。

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

有些计数器的数值是对比上一次的数值统计出来的,这类计数器只收集一次数值是无效的,需要再次调用本函数才能收集到有效的数值,因为这类计数器是统计一段时间内的性能指标变化,每一次收集到的计数器的数值都是对比上一次收集的数值统计出来的,例如每秒的CPU使用率,那么第一次调用本函数后,需要等待一秒,然后再次调用本函数,才能收集到这一秒的CPU使用率。

 

 

2.10.5.5 PdhGetFormattedCounterValue(未完成)

函数名称

PdhGetFormattedCounterValue

头文件

#include <Pdh.h>

#pragma comment(lib, "Pdh.lib")

函数功能

从一个已经收集过数值的计数器里获取数值。

函数声明

PDH_STATUS PdhGetFormattedCounterValue (

PDH_HCOUNTER hCounter,

DWORD dwFormat,

LPDWORD lpdwType,

PPDH_FMT_COUNTERVALUE pValue

);

函数参数

hCounter,[输入]:

存放计数器句柄的值。

dwFormat,[输入]:

存放获取计数器的数值的格式标记,可以为(选一至一个):

PDH_FMT_DOUBLE

以DOUBLE双精度型获取计数器的数值。

PDH_FMT_LARGE

以LONGLONG型获取计数器的数值。

PDH_FMT_LONG

以LONG型获取计数器的数值。

 

还可以为(用"|"选零至多个):

PDH_FMT_NOSCALE

不使用计数器的默认缩放因子。

PDH_FMT_NOCAP100

如果设置本标记,则计数器的百分比数值的上限可以大于100,例如:多个处理器的使用率。

如果不设置本标记,则计数器的百分比数值的上限为100。

PDH_FMT_1000

如果设置本标记,则计数器的数值乘以1000。

如果不设置本标记,则计数器的数值不会乘以1000。

lpdwType,[输出]:

Receives the counter type. For a list of counter types, see the Counter Types section of the OnlineWindows Server 2003 Deployment Kit.

可以为NULL。

pValue,[输出]:

存放用于存放计数器数值的计数器数值结构体的内存指针。

返回值

ERROR_SUCCESS:成功。

其他:失败,返回值就是错误码。

错误码

PDH_INVALID_ARGUMENT:有一个参数是无效的,或格式不正确。

PDH_INVALID_DATA:计数器句柄里没有收集到有效数值,或一个成功的状态码。

PDH_INVALID_HANDLE:计数器句柄是无效的。

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.10.5.6 PdhCloseQuery(未完成)

函数名称

PdhCloseQuery

头文件

#include <Pdh.h>

#pragma comment(lib, "Pdh.lib")

函数功能

关闭性能计数器的查询句柄。

函数声明

PDH_STATUS PdhCloseQuery (

PDH_HQUERY hQuery

);

函数参数

hQuery,[输入]:

存放查询句柄的值。

返回值

ERROR_SUCCESS:成功。

其他:失败,返回值就是错误码。

错误码

PDH_INVALID_HANDLE:查询句柄是无效的。

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.11  多进程

一个可执行程序被执行前,操作系统会先为该可执行程序分配相关资源以供执行(如:CPU、内存、套接字等),这一系列的资源组合起来称为进程,也可以称为是一个可执行程序的实例、实体。一个进程只能对应一个可执行程序。

一个进程刚开始执行时,只有一条执行流程,这个流程称为主线程。如果一个进程需要多条执行流程,就可以在主线程里创建多个子线程。

大多数处理器至少支持两种执行模式:内核模式、用户模式。内核模式下,可以执行很多和系统硬件相关的操作。用户模式下,则不能直接操作硬件。当线程在执行操作系统相关的函数时,线程就处于内核模式,当线程在执行非操作系统相关的函数时,线程就处于用户模式。这样可以保护操作系统的内核不会被任何线程破坏。

每一个进程都有一个全操作系统唯一的句柄和标识。

2.11.1   进程操作

2.11.1.1 CreateProcess(未完成)

函数名称

CreateProcess

头文件

#include <Windows.h>

函数功能

创建一个新进程。

函数声明

BOOL CreateProcess (

LPCSTR lpApplicationName,

LPSTR lpCommandLine,

LPSECURITY_ATTRIBUTES lpProcessAttributes,

LPSECURITY_ATTRIBUTES lpThreadAttributes,

BOOL bInheritHandles,

DWORD dwCreationFlags,

LPVOID lpEnvironment,

LPCSTR lpCurrentDirectory,

LPSTARTUPINFOA lpStartupInfo,

LPPROCESS_INFORMATION lpProcessInformation

);

函数参数

lpApplicationName,[输入] :

存放可执行文件路径字符串的内存指针。

路径可以为相对或绝对路径,不支持通配符,文件后缀名不能省略, 路径后面不能加命令行参数,加了也自动忽略,命令行参数必须通过lpCommandLine参数传递。

如果本参数为相对路径,不会自动搜索任何其他目录,例如Windows系统目录,Path环境变量目录等。

如果本参数为NULL,则lpCommandLine参数最前面必须包含可执行文件路径,并由空格符与后面的字符分开。

如果要执行BAT批处理文件,此参数必须为"cmd.exe",且lpCommandLine参数必须为"/C  BAT批处理文件路径"。

如果要执行16位可执行文件,此参数必须为NULL,且在lpCommandLine参数里包含可执行文件路径及参数。

lpCommandLine,[输入]:

存放执行可执行文件时传递的命令行参数字符串的内存指针,包括'\0'结束符最大长度为32768字节。

如果lpApplicationName参数为NULL,此参数的可执行文件路径字符串部分的长度不能超过MAX_PATH宏。

如果不需要传递命令行参数,此参数的参数字符串部分就为NULL。

如果本参数不为NULL,则此参数不能为常量,因为Unicode版的CreateProcess()函数内部会更改参数字符串的内容,但在CreateProcess()函数返回之前,它会将该字符串恢复原样,ANSI版的不受此限制。

lpProcessAttributes,[输入]:

存放进程属性结构体的内存指针,一般为NULL。

lpThreadAttributes,[输入]:

存放线程属性结构体的内存指针,一般为NULL。

bInheritHandles:,[输入]:

指示新进程是否从调用进程处继承了句柄。

如果本参数为非0,表示调用进程中的每一个可继承的打开句柄都将被子进程继承,被继承的句柄与原进程拥有完全相同的值和访问权限。

如果本参数为0,表示不继承。

dwCreationFlags,[输入]:

存放创建进程时使用的标记。可以为(用'|'选零至多个):

CREATE_DEFAULT_ERROR_MODE

新的进程不继承调用进程的错误模式。CreateProcess函数赋予新进程当前的默认错误模式作为替代。应用程序可以调用SetErrorMode函数设置当前的默认错误模式。

这个标志对于那些运行在没有硬件错误环境下的多线程外壳程序是十分有用的。

对于CreateProcess函数,默认的行为是为新进程继承调用者的错误模式。设置这个标志以改变默认的处理方式。

CREATE_NEW_CONSOLE

如果设置此标记,则新进程将使用一个新控制台,而不是继承调用进程的控制台。

如果不设置此标记,则这个新进程将与调用进程使用同一个控制台。

如果新进程不是控制台程序,则此标记无意义。

此标志不能与DETACHED_PROCESS标记同时设置。

CREATE_NEW_PROCESS_GROUP

新进程将是一个进程树的根进程。

进程树中的全部进程都是根进程的子进程。

新进程树的用户标识符与这个进程的标识符是相同的,由lpProcessInformation参数返回。

进程树经常使用GenerateConsoleCtrlEvent函数允许发送CTRL+C或CTRL+BREAK信号到一组控制台进程。

CREATE_SEPARATE_WOW_VDM

如果设置此标记,新进程将会在一个私有的虚拟DOS机(VDM)中运行。另外,默认情况下所有的16位Windows应用程序都会在同一个共享的VDM中以线程的方式运行。单独运行一个16位程序的优点是一个应用程序的崩溃只会结束这一个VDM的运行;其他那些在不同VDM中运行的程序会继续正常的运行。同样的,在不同VDM中运行的16位Windows应用程序拥有不同的输入队列,这意味着如果一个程序暂时失去响应,在独立的VDM中的应用程序能够继续获得输入。

CREATE_SHARED_WOW_VDM

如果WIN.INI中的Windows段的DefaultSeparateVDM选项被设置为真,这个标识使得CreateProcess函数越过这个选项并在共享的虚拟DOS机中运行新进程。

CREATE_SUSPENDED

新进程的主线程会以暂停的状态被创建,直到调用ResumeThread()函数被调用时才运行。

CREATE_UNICODE_ENVIRONMENT

如果设置此标记,由lpEnvironment参数指定的环境变量内存块使用Unicode字符集。

如果不设置此标记,由lpEnvironment参数指定的环境变量内存块使用ANSI字符集。

DEBUG_PROCESS

如果设置此标记,调用进程将被当做一个调试程序,并且新进程会被当做被调试的进程。系统把被调试程序发生的所有调试事件通知给调试器,且只有本函数调用进程可以调用WaitForDebugEvent()函数。

DEBUG_ONLY_THIS_PROCESS

如果此标志没有被设置且调用进程正在被调试,新进程将成为调试调用进程的调试器的另一个调试对象。

如果调用进程没有被调试,有关调试的行为就不会产生。

DETACHED_PROCESS

对于控制台进程,新进程没有访问父进程控制台的权限。

新进程可以通过AllocConsole函数自己创建一个新的控制台。

如果新进程不是控制台程序,则此标记无意义。

此标记不能与CREATE_NEW_CONSOLE标志同时设置。

CREATE_NO_WINDOW

如果设置此标记,则新进程不显示控制台窗口。

如果不设置此标记,则新进程会显示控制台窗口。

如果新进程不是控制台程序,则此标记无意义。

 

以下是进程优先级标记,可以为(选零至一个):

HIGH_PRIORITY_CLASS

指示这个进程将执行时间临界的任务,所以它必须被立即运行以保证正确。这个优先级的程序优先于正常优先级或空闲优先级的程序。一个例子是Windows任务列表,为了保证当用户调用时可以立刻响应,放弃了对系统负荷的考虑。确保在使用高优先级时应该足够谨慎,因为一个高优先级的CPU关联应用程序可以占用几乎全部的CPU可用时间。

IDLE_PRIORITY_CLASS

指示这个进程的线程只有在系统空闲时才会运行并且可以被任何高优先级的任务打断。例如屏幕保护程序。空闲优先级会被子进程继承。

NORMAL_PRIORITY_CLASS

指示这个进程没有特殊的任务调度要求。

REALTIME_PRIORITY_CLASS

指示这个进程拥有可用的最高优先级。一个拥有实时优先级的进程的线程可以打断所有其他进程线程的执行,包括正在执行重要任务的系统进程。例如,一个执行时间稍长一点的实时进程可能导致磁盘缓存不足或鼠标反映迟钝。

lpEnvironment,[输入]:

存放新进程的环境变量内存块的内存指针,如果为NULL,表示继承本函数调用进程的环境变量。环境变量内存块的格式为"name1=value1\0name2=value2\0name3=value3\0……"。

lpCurrentDirectory,[输入]:

存放新进程的当前活动目录字符串的内存指针,可以为UNC格式。

如果为NULL,表示和调用进程使用一样的当前活动目录。

lpStartupInfo,[输入]:

存放一个用于决定新进程的主窗体如何显示的STARTUPINFO结构体的内存指针,不能为NULL。

lpProcessInformation,[输出]:

存放一个用来接收新进程的识别信息的PROCESS_INFORMATION结构体的内存指针,不能为NULL。

详见

返回值

非0:成功。

0:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

调用完本函数后,新进程需要先初始化完毕后才能开始运行,本函数是启动新进程成功后就立即返回成功,不会等待新进程初始化完毕后才返回,未初始化完毕的新进程的进程和线程的句柄和标识是无效的,如果要操作新进程,必须等待初始化完毕后才能操作,否则会报ERROR_INVALID_THREAD_ID错误的线程标识等错误。

如果新进程是窗口程序,可以通过调用WaitForInputIdle()函数等待新进程初始化完毕。

如果新进程是控制台程序或没有线程消息队列,可以考虑通过不停的调用PostThreadMessage()函数,直到成功为止,因为对未初始化完毕的线程寄送消息是会报ERROR_INVALID_THREAD_ID错误的,当初始化完毕后,寄送消息就会成功。

 

 

2.12  多线程

每一个线程都有一个全操作系统唯一的句柄和标识。

2.12.1   线程操作

2.12.1.1 CreateThread(未完成)

函数名称

CreateThread

头文件

#include <Windows.h>

函数功能

为本进程创建一个新的线程,并返回线程的句柄。

函数声明

HANDLE CreateThread (

LPSECURITY_ATTRIBUTES lpThreadAttributes,

DWORD dwStackSize,

LPTHREAD_START_ROUTINE lpStartAddress,

LPVOID lpParameter,

DWORD dwCreationFlags,

LPDWORD lpThreadId

);

函数参数

lpThreadAttributes,[输入]:

指向一个 SECURITY_ATTRIBUTES 结构的指针,该结构决定了线程的安全属性,一般置为 NULL。

dwStackSize,[输入]:

指定了线程的堆栈长度,一般都设置为0。

lpStartAddress,[输入]:

表示新线程开始执行的主函数指针。线程主函数的声明必须是DWORD WINAPI ThreadFunc (LPVOID lpThreadParameter),ThreadFunc是线程主函数名(名称可以修改),lpThreadParameter为参数名(名称可以修改),线程主函数只能有一个参数。

lpParameter,[输入]:

指定传给线程主函数的参数,不传就为NULL。

dwCreationFlags,[输入]:

线程创建后是否立即执行线程主函数。

如果本参数为0,表示立即执行。

如果本参数为CREATE_SUSPENDED宏,则线程创建后,挂起状态,并不马上执行,以后可以调用ResumeThread()函数唤醒线程。

lpThreadId,[输出]:

存放新线程ID的变量的内存指针,不需要就为NULL。

返回值

非NULL:新线程的句柄。

NULL:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

……

……

 

 

2.12.1.2 SuspendThread

DWORD SuspendThread(HANDLE hThread);

该函数用于挂起指定的线程,如果函数执行成功,则线程的执行被终止。

 

2.12.1.3 ResumeThread

DWORD ResumeThread(HANDLE hThread);

该函数用于结束线程的挂起状态,执行线程。 也就是恢复指定的线程

 

2.12.1.4 ExitThread

VOID ExitThread(DWORD dwExitCode);

该函数用于线程终结自身的执行,主要在线程的执行函数中被调用。其中参数dwExitCode用来设置线程的退出码。

 

2.12.1.5 TerminateThread

BOOL TerminateThread(HANDLE hThread,DWORD dwExitCode);

一般情况下,线程运行结束之后,线程函数正常返回,但是应用程序可以调用TerminateThread强行终止某一线程的执行。各参数含义如下:hThread:将被终结的线程的句柄;

dwExitCode:用于指定线程的退出码。

使用TerminateThread()终止某个线程的执行是不安全的,可能会引起系统不稳定;虽然该函数立即终止线程的执行,但并不释放线程所占用的资源。因此,一般不建议使用该函数。

2.12.1.6 GetExitCodeThread(未完成)

函数名称

GetExitCodeThread

头文件

#include <Windows.h>

函数功能

判断指定的线程是否终止运行,如果已经终止,就获取该线程的退出代码。

函数声明

BOOL GetExitCodeThread(

HANDLE hThread,

LPDWORD lpExitCode

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.12.1.7 GetCurrentThreadId

GetCurrentThreadId()

获取当前线程ID。

 

 

2.12.2   临界区

在用户模式工作,适用于保护线程间共享资源,一个线程可以多次Lock不会出错。不支持在多进程之间工作。

#include <Windows.h>

 

CRITICAL_SECTION  Section;

  

   InitializeCriticalSection(&Section);//初始化临界区

 

   线程中使用

   EnterCriticalSection(&Section);//进入临界区

   {

   }

   LeaveCriticalSection(&Section);//退出临界区

2.12.3   互斥锁

在内核模式工作,除了支持临界区的功能,还可以为互斥量命名,以便在多进程中工作。互斥量比临界区耗资源。

 

1

#include <Windows.h>

HANDLE hMutex;

 

hMutex = CreateMutex(NULL , false, "mutex");

 

 

线程函数使用:

WaitForSingleObject(hMutex,INFINITE);

{

}

ReleaseMutex(hMutex);

 

2

CMutex Section;

线程函数中使用

CsingleLock singlelock;

singlelock(&Section);

singlelock.lock();

singlelock.Unlock();

 

 

2.12.4   事件

事件对象就像一个开关:它只有两种状态---开和关。当一个事件处于”开”状态,我们称其为”有信号”否则称为”无信号”。可以在一个线程的执行函数中创建一个事件对象,然后观察它的状态,如果是”无信号”就让该线程睡眠,这样该线程占用的CPU时间就比较少。

产生事件对象的函数如下:

 

HANDLE     CreateEvent(

        LPSECURITY_ATTRIBUTES     lpEventAttributes,     //     SD  

        BOOL     bManualReset,                                                 //     reset     type  

        BOOL     bInitialState,                                                      //     initial     state  

        LPCTSTR     lpName                                                       //     object     name  

    );  

    该函数创建一个Event同步对象,如果CreateEvent调用成功的话,会返回新生成的对象的句柄,否则返回NULL。

 

参数说明:

    lpEventAttributes     一般为NULL  

 

    bManualReset          创建的Event是自动复位还是人工复位.如果true,人工复位,   一旦该Event被设置为有信号,则它一直会等到ResetEvent()API被调用时才会恢复 为无信号.     如果为false,Event被设置为有信号,则当有一个wait到它的Thread时,  该Event就会自动复位,变成无信号.   如果想 在每次调用WaitForSingleObject 后让WINDOWS为您自动地把事件地状态恢复为”无信号”状态,必须把该参数设为FALSE,否则,您必须每次调用ResetEvent函数来清除事件 的信号。

 

 

    bInitialState             初始状态,true,有信号,false无信号  

    lpName                  事件对象的名称。您在OpenEvent函数中可能使用。

 

注释:

    一个Event被创建以后,可以用OpenEvent()API来获得它的Handle,用CloseHandle()来关闭它,用SetEvent()或PulseEvent()来设置它使其有信号,用ResetEvent()来使其无信号,用WaitForSingleObject()或WaitForMultipleObjects()来等待其变为有信号。

    PulseEvent()是一个比较有意思的使用方法,正如这个API的名字,它使一个Event 对象的状态发生一次脉冲变化,从无信号变成有信号再变成无信号,而整个操作是原子的。

    对自动复位的Event对象,它仅释放第一个等到该事件的thread(如果有),而对于人工复位的Event对象,它释放所有等待的thread。

这里有两个API函数用来修改事件对象的信号状态:SetEvent和ResetEvent。前者把事件对象设为”有信号”状态,而后者正好相反。

在事件对象生成后,必须调用WaitForSingleObject来让线程进入等待状态,该函数的语法如下:

 

WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)

 

hHandle-->指向同步对象的指针。事件对象其实是同步对象的一种。

dwMilliseconds--> 等待同步对象变成”有信号”前等待的时间,以毫秒计。当等待的时间超过该值后无信号同步对象仍处于”无信号”状态,线程不再等待, WaitForSingleObject函数会返回。如果想要线程一直等待,请把该参数设为INFINITE(该值等于0xffffffff)。

 

 

2.13  服务

2.13.1   OpenSCManager(未完成)

函数名称

OpenSCManager

头文件

#include <Winsvc.h>

库文件

#pragma comment(lib, "Advapi32.lib")

函数功能

打开服务控制管理数据库,并返回服务控制管理数据库句柄。

函数声明

SC_HANDLE WINAPI OpenSCManager (

LPCTSTR lpMachineName,

LPCTSTR lpDatabaseName,

DWORD dwDesiredAccess

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.13.2   CloseServiceHandle(未完成)

函数名称

CloseServiceHandle

头文件

#include <Winsvc.h>

库文件

#pragma comment(lib, "Advapi32.lib")

函数功能

关闭服务控制管理数据库句柄。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.13.3   CreateService(未完成)

函数名称

CreateService

头文件

#include <Winsvc.h>

库文件

#pragma comment(lib, "Advapi32.lib")

函数功能

创建一个服务对象,并将其添加到指定的服务控制管理器数据库。

函数声明

SC_HANDLE WINAPI CreateService (

SC_HANDLE hSCManager,

LPCTSTR lpServiceName,

LPCTSTR lpDisplayName,

DWORD dwDesiredAccess,

DWORD dwServiceType,

DWORD dwStartType,

DWORD dwErrorControl,

LPCTSTR lpBinaryPathName,

LPCTSTR lpLoadOrderGroup,

LPDWORD lpdwTagId,

LPCTSTR lpDependencies,

LPCTSTR lpServiceStartName,

LPCTSTR lpPassword

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.13.4   QueryServiceStatus(未完成)

函数名称

QueryServiceStatus

头文件

#include <Winsvc.h>

库文件

#pragma comment(lib, "Advapi32.lib")

函数功能

函数主要功能说明。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.13.5   ControlService(未完成)

函数名称

ControlService

头文件

#include <Winsvc.h>

库文件

#pragma comment(lib, "Advapi32.lib")

函数功能

函数主要功能说明。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.14  可视化窗口

每个窗口都有一个三维坐标,X轴表示窗口在屏幕的横坐标位置,最左边为0,依次向右每一个像素递增一,Y轴表示窗口在屏幕的纵坐标位置,最上边为0,依次向下每一个像素递增一,Z轴表示窗口挡在其他窗口的前面还是躲在后面,从远往近看,Z轴坐标越大的就会挡在其他的控件或窗口的前面。

 

控件

MFC

描述

动画

CAnimateCtrl

显示连续的AVI视频剪辑

按钮

CButton

用来产生某种行为的按钮,以及复选框、单选钮和组框

组合框

CComboBox

编辑框和列表框的组合

编辑框

CEdit

用于键入文本

标题头

CHeaderCtrl

位于某一行文本之上的按钮,可用来控制显示文件的宽度

热键

CHotKeyCtrl

用于通过按下某一组合键来很快的执行某些常用的操作

图象列表

CImageList

一系列图象(典型情况下是一系列图标或位图)的集合。图象列表本身不是一种控件,它常常是和其它控件一起工作,为其它控件提供所用的图象列表

列表

CListCtrl

显示文本及其图标列表的窗口

列表框

CListBox

包括一系列字符串的列表

进度

CProgressCtrl

用于在一较长操作中提示用户所完成的进度

多格式文本编辑

CRichEditCtrl

提供可设置字符和段落格式的文本编辑的窗口

滚动条

CScrollBar

为对话框提供控件形式的滚动条

滑块

CSliderCtrl

包括一个有可选标记的滑块的窗口

旋转按钮

CSpinButtonCtrl

提供一对可用于增减某个值的箭头

静态文本

CStatic

常用于为其它控件提供标签

状态条

CStatusBarCtrl

用于显示状态信息的窗口,同MFC类CStatusBar类似

选项卡

CTabCtrl

在选项卡对话框或属性页中提供具有类似笔记本中使用的分隔标签的外观的选项卡

工具条

CToolBarCtrl

具有一系列命令生成按钮的窗口,同MFC类CToolBar类似

工具提示

CToolTipCtrl

一个小的弹出式窗口,用于提供对工具条按钮或其它控件功能的简单描述

CTreeCtrl

用于显示一系列的项的继承结构

 

2.14.1   窗口位置、窗口大小

2.14.1.1 GetWindowRect(未完成)

函数名称

GetWindowRect

头文件

#include <Windows.h>

函数功能

获取指定的窗口的左边、顶边、右边、底边在屏幕上的位置。

函数声明

BOOL GetWindowRect (

HWND hWnd,

LPRECT lpRect

);

函数参数

hWnd,[输入]:

存放要获取哪个窗口句柄的位置,不能为NULL。

lpRect,[输出]:

存放位置结构体的内存指针,用于存放指定的窗口在屏幕上的位置。

返回值

非0:成功

0:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.14.1.2 SetWindowPos(未完成)

函数名称

SetWindowPos

头文件

#include <Windows.h>

函数功能

改变一个窗口的Z轴顺序、位置、尺寸、样式。

函数声明

BOOL SetWindowPos (

HWND hWnd,

HWND hWndInsertAfter,

int X,

int Y,

int cx,

int cy,

UINT uFlags

);

函数参数

hWnd,[输入]:

存放要改变的窗口的句柄。

hWndInsertAfter,[输入]:

存放要将hWnd参数指定的窗口定位在哪些窗口句柄的前面。

如果不想定位窗口,就在uFlags参数中设置SWP_NOZORDER标记,则本参数将被忽略,否则本参数不能为NULL。

此参数也可以为(选一至一个):

HWND_BOTTOM(1):

如果hWnd参数指定的窗口是当前激活窗口,将此窗口定位在Z轴顺序的底部,也就是所有窗口的后面,且如果此窗口是置顶窗口,就变成非置顶窗口。

如果hWnd参数指定的窗口不是当前激活窗口,则不做任何定位,无论此窗口是置顶窗口,还是非置顶窗口。

HWND_NOTOPMOST(-2):

如果hWnd参数指定的窗口是置顶窗口,且是当前激活窗口,就变成非置顶窗口,并定位在所有非置顶窗口的前面,及在所有置顶窗口的后面。

如果hWnd参数指定的窗口已经是一个非置顶窗口,或不是当前激活窗口,则不做任何定位。

HWND_TOP(0):

如果hWnd参数指定的窗口是非置顶窗口,且是当前激活窗口,将窗口定位在所有非置顶窗口的前面,及在所有置顶窗口的后面。

如果hWnd参数指定的窗口已经是一个置顶窗口,或不是当前激活窗口,则不做任何定位。

HWND_TOPMOST(-1):

将hWnd参数指定的窗口定位在所有非置顶窗口和置顶窗口的前面,并将窗口变成置顶窗口,无论此窗口是不是当前激活窗口。

如果hWnd参数指定的窗口在置顶后,又有其他窗口被置顶,则此窗口将被定位在其他置顶窗口的后面。

如果要一直保持某个窗口的置顶位置,需要每隔一段时间就设置一次置顶,才能保证不被其他窗口盖住。

X,[输入]:

存放将hWnd参数指定的窗口的左边移动到屏幕的哪个像素。

如果不想移动窗口,就在uFlags参数中设置SWP_NOMOVE标记,则本参数将被忽略。

Y,[输入]:

存放将hWnd参数指定的窗口的顶边移动到屏幕的哪个像素。

如果不想移动窗口,就在uFlags参数中设置SWP_NOMOVE标记,则本参数将被忽略。

cx,[输入]:

存放将hWnd参数指定的窗口的左边至右边的长度改为多少个像素。

如果不想修改窗口尺寸,就在uFlags参数中设置SWP_NOSIZE标记,则本参数将被忽略。

注意:本参数是边框长度,不是像素位置。

cy,[输入]:

存放将hWnd参数指定的窗口的顶边至低边的长度改为多少个像素。

如果不想修改窗口尺寸,就在uFlags参数中设置SWP_NOSIZE标记,则本参数将被忽略。

注意:本参数是边框长度,不是像素位置。

uFlags,[输入]:

存放操作窗口的位置和大小的标记,可以为(用'|'选零至多个):

SWP_DRAWFRAME

Draws a frame (defined when the window was created) around the window.

SWP_FRAMECHANGED

Sends a WM_NCCALCSIZE message to the window, even if the window's size is not being changed. If this flag is not specified, WM_NCCALCSIZE is sent only when the window's size is being changed.

SWP_HIDEWINDOW

Hides the window.

SWP_SHOWWINDOW

Displays the window.

SWP_NOACTIVATE

Does not activate the window. If this flag is not set, the window is activated and moved to the top of either the topmost or the non-topmost group (depending on the setting of the pWndInsertAfter parameter).

SWP_NOCOPYBITS

Discards the entire contents of the client area. If this flag is not specified, the valid contents of the client area are saved and copied back into the client area after the window is sized or repositioned.

SWP_NOOWNERZORDER

Does not change the owner window's position in the Z-order.

SWP_NOREDRAW

Does not redraw changes. If this flag is set, no repainting of any kind occurs. This applies to the client area, the nonclient area (including the title and scroll bars), and any part of the parent window uncovered as a result of the moved window. When this flag is set, the application must explicitly invalidate or redraw any parts of the window and parent window that must be redrawn.

SWP_NOREPOSITION

Same as SWP_NOOWNERZORDER.

SWP_NOSENDCHANGING

Prevents the window from receiving the WM_WINDOWPOSCHANGING message.

SWP_NOMOVE

如果设置本标记,表示不改变窗口的左边、顶边的位置,并忽略X参数、Y参数。

如果不设置本标记,表示需要改变窗口的左边、顶边的位置,并使X参数、Y参数有效。

SWP_NOSIZE

如果设置本标记,表示不改变窗口的左右、上下的大小,并忽略cx参数、cy参数。

如果不设置本标记,表示需要改变窗口的左右、上下的大小,并使cx参数、cy参数有效。

SWP_NOZORDER

如果设置本标记,表示不改变窗口的Z轴顺序,并忽略hWndInsertAfter参数。

如果不设置本标记,表示需要改变窗口的Z轴顺序,并使hWndInsertAfter参数有效。

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.14.2   MessageBox(未完成)

函数名称

MessageBox

头文件

#include <Windows.h>

函数功能

显示一个消息对话框,其中包含一组按钮、一个系统图标和一句消息,如状态或错误的消息。

消息对话框中返回一个整数值,该值指示用户单击了哪个按钮。

函数声明

int MessageBox (

HWND hWnd,

LPCTSTR lpText,

LPCTSTR lpCaption,

UINT uType

);

函数参数

hWnd,[输入]:

存放消息对话框的父窗口。

如果为NULL,表示消息框框没有父窗口。

lpText,[输入]:

存放消息对话框的消息字符串。

lpCaption,[输入]:

存放消息对话框的标题字符串。

如果为NULL,默认就是“错误”。

uType,[输入]:

存放出现在消息对话框的行为标记,用'|'选按钮、图标、窗体和其他标记。

按钮,默认为MB_OK标记,可以是(选零至一个):

MB_OK:只有“确定”按钮。

MB_YESNO:有“是”和“否”按钮。

MB_ABORTRETRYIGNORE:有“放弃”,“重试”和“忽略”按钮。

MB_YESNOCANCEL:有“是”,“否”和“取消”按钮。

MB_RETRYCANCEL:有“重试”和“取消”按钮。

MB_OKCANCEL:有“确定”和“取消”按钮。

MB_CANCELTRYCONTINUE:有“取消”,“重试”和“继续”按钮。

 

默认按钮,默认为MB_DEFBUTTON1标记,可以是(选零至一个):

MB_DEFBUTTON1:第一个按钮是默认按钮。

MB_DEFBUTTON2:第二个按钮是默认按钮。

MB_DEFBUTTON3:第三个按钮是默认按钮。

MB_DEFBUTTON4:第四个按钮是默认按钮。

 

图标,默认没有图标,可以是(选零至一个):

MB_ICONEXCLAMATION:惊叹号警告图标,黄色三角形中间一个感叹号。

MB_ICONWARNING:同MB_ICONEXCLAMATION标记。

MB_ICONINFORMATION:提示信息图标,圆圈中小写字母i组成的图标。

MB_ICONASTERISK:同MB_ICONINFORMATION标记。

MB_ICONQUESTION:问题标记图标。

MB_ICONSTOP:错误停止图标。

MB_ICONERROR:同MB_ICONSTOP标记。

MB_ICONHAND:同MB_ICONSTOP标记。

 

窗体,默认为MB_APPLMODAL标记,可以是(选零至一个):

MB_APPLMODAL:消息对话框显示在父窗口之上,用户必须单击消息对话框的按钮后才能使用父窗口,不影响其他窗口使用。

MB_SYSTEMMODAL:消息对话框显示在系统所有窗口之上,用户必须单击消息对话框的按钮后才能使用父窗口,不影响其他窗口使用。

MB_TASKMODAL:消息对话框显示在本进程所有窗口之上,用户必须单击消息对话框的按钮后才能使用本进程其他窗口,不影响其他进程窗口使用。

 

其他,可以是(选零至多个):

MB_DEFAULT_DESKTOP_ONLY:接收输入的当前桌面一定是一个缺省桌面。否则,函数调用失败。缺省桌面是一个在用户已经纪录且以后应用程序在此上面运行的桌面。

MB_HELP:把一个帮助按钮增加到消息对话框。用户单击帮助按钮或按F1键后产生一个WM_HELPINFO消息。

MB_RIGHT:如果设置此标记,消息对话框的消息字符串向右对齐。如果不设置此标记,消息对话框的消息字符串向左对齐。

MB_RTLREADING:用在Hebrew和Arabic系统中从右到左的顺序显示消息和大写文本。

MB_SETFOREGROUND:消息对话框设置为活动窗口,本函数会在内部调用SetForegroundWindow()函数。

MB_TOPMOSI:消息对话框用WS_EX_TOPMOST窗口类型来创建,也就是显示在系统所有窗口之上。

MB_SERVICE_NOTIFICATION

MB_SERVICE_NOTIFICATION_NT3X

返回值

0:失败,调用GetlastError()函数查看错误码。

IDABORT:用户单击了“放弃”按钮。

IDCANCEL:用户单击了“取消”按钮。

IDCONTINUE:用户单击了“继续”按钮。

IDIGNORE:用户单击了“忽略”按钮。

IDNO:用户单击了“否”按钮。

IDOK:用户单击了“是”按钮。

IDRETRY:用户单击了“重试”按钮。

IDYES:用户单击了“确定”按钮。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

 

 

 

2.14.3   FindWindow(未完成)

函数名称

FindWindow

头文件

#include <xxx.h>

#include <xxx.h>

库文件

#pragma comment(lib, "xxx.lib")

函数功能

函数主要功能说明。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.14.4   样式

2.14.4.1 ModifyStyle(未完成)

函数名称

ModifyStyle

头文件

#include <Windows.h>

函数功能

根据指定的窗口句柄,动态添加并删除该窗口的普通样式,并立即生效。

函数声明

BOOL ModifyStyle (

HWND hWnd,

DWORD dwRemove,

DWORD dwAdd,

  UINT nFlags

);

函数参数

hWnd,[输入]:

存放要修改样式的窗口的句柄的值,该窗口必须已经创建。

dwRemove,[输入]:

存放要删除的普通样式的值,一般为该窗口的样式宏。

如果不需要删除,本参数填0。

例如:列表控件的大图标视图样式的宏定义为LVS_ICON。

dwAdd,[输入]:

存放要添加的普通样式的值,一般为该窗口的样式宏。

如果不需要添加,本参数填0。

例如:列表控件的大图标视图样式的宏定义为LVS_ICON。

nFlags,[输入]:

存放需要调用SetWindowPos()函数修改的样式,不需要就填0,本参数可以为(用'|'选零至多个):

SWP_NOSIZE

保持当前大小。

SWP_NOMOVE

保持当前位置。

SWP_NOZORDER

保持当前的Z次序。

SWP_NOACTIVATE

不激活该窗口。

返回值

非0:成功。

0:失败。

错误码

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

有些窗口的普通样式是冲突的,需要同时删除旧样式,并添加新样式,否则会导致失败。

有些窗口的普通样式是不可以动态添加或删除的,否则会导致失败。

本函数只能修改普通样式,不能修改扩展样式,修改扩展样式需调用ModifyStyleEx()函数。

 

 

2.14.5   CDC图形设备环境类

CDC类是在显示数据,或者使用图形,或者使用文本中必不可少的。Windows使用与设备无关的图形设备环境(DC:Device Context)进行显示。MFC基础类库定义了图形设备环境类----CDC类。

2.14.5.1 CDC::GetTextExtent(未完成)

函数名称

GetTextExtent

头文件

#include <Windows.h>

函数功能

根据本类对象设置的字体,计算一个字符串显示在窗口上的像素尺寸。

函数声明

CSize GetTextExtent (

const CString & str

);

 

CSize GetTextExtent (

LPCTSTR lpszString,

int nCount

);

函数参数

str,[输入]:

存放要计算像素尺寸的字符串的CString字符串类对象。

lpszString,[输入]:

存放要计算像素尺寸的字符串的内存指针。

nCount,[输入]:

存放要计算像素尺寸的字符串的内存长度的值。

返回值

字符串的上下和左右的像素尺寸

错误码

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

设置本类对象的字体可以调用CDC::SelectObject()函数。

 

 

2.14.6   CFont字体类

CFont类封装了一个Windows图形设备接口(GDI)字体,并为操作字体提供了成员函数。

Windows提供了多种与设备无关的不同尺寸的字体。有效地使用这些Windows字体,不用在编程时下很大功夫,就可以明显地增强各种应用程序的功能。字体是Windows GDI必要的组成部分,这意味字体的使用与其他GDI对象一样。它们可以缩放和剪切,可以像选取画笔或者画刷一样选取设备环境。所有关于撤消选中和删除的GDI规则都适用于字体。

2.14.6.1 CFont::CreatePointFont(未完成)

函数名称

CreatePointFont

头文件

#include <Windows.h>

函数功能

修改本字体类对象的字体。

函数声明

BOOL CreatePointFont (

int nPointSize,

LPCTSTR lpszFaceName,

CDC* pDC

);

函数参数

nPointSize,[输入]:

存放新字体的大小的值,该值要在实际大小上再乘以10,例如字体大小为11,则本参数就填110。

lpszFaceName,[输入]:

存放字体名称字符串的内存指针,例如字体为宋体,则本参数就填"宋体"。

pDC,[输入]:

Pointer to the CDC object to be used to convert the height in nPointSize to logical units. If NULL, a screen device context is used for the conversion.

返回值

非0:成功。

0:失败。

错误码

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

如果本类对象的字体不再使用了,应该调用DeleteObject()函数释放本类对象的字体资源,在本类对象被释放时,会自动释放字体资源。

 

 

2.14.7   CWnd窗口基类

CWnd类是MFC窗口类的基类,提供了微软基础类库中所有窗口类的基本功能。

2.14.7.1 CWnd::SetFont

函数名称

SetFont

头文件

#include <Windows.h>

函数功能

设置本窗口类对象的字体。

函数声明

void SetFont (

CFont * pFont,

BOOL bRedraw

);

函数参数

pFont,[输入]:

存放字体类对象的内存指针。

创建字体类对象可以参考CFont::CreatePointFont()函数。

bRedraw,[输入]:

存放是否要在设置完字体后立即重绘窗口,非0表示需要立即重绘,0表示不需要立即重绘。

返回值

错误码

线程安全

原子操作

其他说明

本函数实际上是对本窗口类对象发送WM_SETFONT消息,如果本窗口类对象没有处理该消息,则本函数无效。

 

 

2.14.8   CListCtrl列表控件类

列表控件分为四种视图:图标视图、小图标视图、列表视图、报表视图。

图标视图: ,小图标视图:

列表视图: ,报表视图:

 

列表控件中每一行为一个项目,每一个项目都有一至多个字段,每个字段都有图标和标签。

图标视图、小图标视图、列表视图直接可以插入项目,但是只能显示每个项目的第一个字段的图标和标签,即使插入了其他的字段也不能显示。

报表视图必须先插入字段头,然后才能插入项目,要不然插入的项目不会显示。报表视图中可以同时显示每个项目的每个字段的图标和标签。

项目索引号是每个项目的唯一标识,用于操作项目时起定位作用,项目索引号始终是连续的,且第一个项目的索引号始终为0,第二个项目的索引号始终为1,以此类推。

字段索引号是某一项目的每个字段的唯一标识,用于操作项目的字段时起定位作用,字段索引号始终是连续的,且每个项目的第一个字段的索引号始终为0,每个项目的第二个字段的索引号始终为1,以此类推。

 

 

2.14.8.1 CListCtrl::InsertItem(未完成)

函数名称

InsertItem

头文件

#include <afxcmn.h>

库文件

函数功能

向列表控件中插入一个新项目。

函数声明

int InsertItem (

const LVITEM * pItem

);

int InsertItem (

int nItem,

LPCTSTR lpszItem

);

int InsertItem (

int nItem,

LPCTSTR lpszItem,

int nImage

);

int InsertItem (

UINT nMask,

int nItem,

LPCTSTR lpszItem,

UINT nState,

UINT nStateMask,

int nImage,

LPARAM lParam

);

函数参数

pItem,[输入]:

存放LVITEM结构体的内存指针,新项目的各种参数都在该结构体中。

nItem,[输入]:

存放新项目的索引号,本参数只能大于等于0。

lpszItem,[输入]:

存放新项目的主项目的标签字符串的内存指针。

如果本参数为LPSTR_TEXTCALLBACK宏,表示项目的标签为虚拟标签,详情请参考LVITEM结构体的pszText成员变量。

nImage,[输入]:

Index of the item's image, or I_IMAGECALLBACK if the item is a callback item. For information on callback items, see CListCtrl::GetCallbackMask.

nMask,[输入]:

存放本函数有哪些参数有效的标记,可以为(用'|'选零至多个):

 

nState,[输入]:

参数说明。

nStateMask,[输入]:

参数说明。

lParam,[输入]:

参数说明。

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

如果新项目的索引号在列表控件中已经存在,则该索引号的项目及以后的项目全部加一,新项目插入到该索引号对应位置。

如果新项目的索引号在列表控件中不存在,则新项目就插入到列表控件的最后一行,并把新项目的索引号修改为插入前最后一个项目的索引号加一,如果列表控件中没有任何项目,则新项目就在第一行,且索引号为0。

 

 

2.14.8.2 CListCtrl::DeleteItem(未完成)

函数名称

DeleteItem

头文件

#include <afxcmn.h>

库文件

函数功能

删除列表控件中某个项目。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.14.8.3 CListCtrl::DeleteAllItems(未完成)

函数名称

DeleteAllItems

头文件

#include <afxcmn.h>

库文件

函数功能

删除列表控件中所有的项目。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.14.8.4 CListCtrl::InsertColumn(未完成)

函数名称

InsertColumn

头文件

#include <afxcmn.h>

库文件

函数功能

向列表控件中插入一个新字段头。

函数声明

int InsertColumn (

int nCol,

const LVCOLUMN * pColumn

);

int InsertColumn (

int nCol,

LPCTSTR lpszColumnHeading,

int nFormat = LVCFMT_LEFT,

int nWidth = -1,

int nSubItem = -1

);

函数参数

nCol,[输入]:

存放新字段头的索引号,本参数只能大于等于0。

pColumn,[输入]:

参数说明。

lpszColumnHeading,[输入]:

存放新字段头的标签字符串的内存指针,不能为NULL。

nFormat,[输入]:

存放新字段头的标签、及每个项目的在新字段的标签的对齐方式的值,可以为(选一至一个):

LVCFMT_LEFT(0x0000)

向左对齐。

LVCFMT_RIGHT(0x0001)

向右对齐。

LVCFMT_CENTER(0x0002)

居中对齐。

注意:如果新字段头的索引号为0,则本参数将忽略。

如果要设置索引号为0的字段的对齐方式,有以下几种方法:

1、可以先插入索引号为1的字段,然后再调用CListCtrl::DeleteColumn()函数删除索引号为0的字段。

2、插入索引号为0的字段后,再调用CListCtrl::SetColumn()函数修改字段的对齐方式。

nWidth,[输入]:

存放新字段头的初始宽度的值,单位像素。

如果本参数为-1,表示使用默认宽度,一般为10。

如果本参数为0或小于-1,表示宽度为0。

nSubItem,[输入]:

Index of the subitem associated with the column. If this parameter is -1, no subitem is associated with the column.

返回值

-1:失败。

其他:新字段的实际索引号。

错误码

线程安全

原子操作

其他说明

只有报表视图才能显示字段头,且报表视图必须插入字段头才能显示列表控件中的项目。

如果新字段头的索引号在列表控件中已经存在,则该索引号的字段头及以后的字段头全部加一,新字段头插入到该索引号对应位置。

如果新字段头的索引号在列表控件中不存在,则新字段头就插入到列表控件的最后一个,并把新字段头的索引号修改为插入前最后一个字段头的索引号加一,如果列表控件中没有任何字段头,则新字段头就在第一个,且索引号为0。

 

 

2.14.8.5 CListCtrl::DeleteColumn

函数名称

DeleteColumn

头文件

#include <afxcmn.h>

库文件

函数功能

从列表控件中删除一个字段头。

函数声明

BOOL DeleteColumn (

int nCol

);

函数参数

nCol,[输入]:

存放要删除的字段头的索引号,本参数只能大于等于0。

返回值

非0:成功。

0:失败,要删除的字段头的索引号不存在。

错误码

线程安全

原子操作

其他说明

如果要删除的字段头后面还有字段头,则后面的字段头的索引号全部将减一。

 

 

2.14.8.6 CListCtrl::GetColumnWidth(未完成)

函数名称

GetColumnWidth

头文件

#include <afxcmn.h>

库文件

函数功能

获取列表控件中某个字段头的宽度,单位像素。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.14.8.7 CListCtrl::SetColumnWidth(未完成)

函数名称

SetColumnWidth

头文件

#include <afxcmn.h>

库文件

函数功能

设置列表控件中某个字段头的宽度,单位像素。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.14.8.8 CListCtrl::GetExtendedStyle(未完成)

函数名称

GetExtendedStyle

头文件

#include <Windows.h>

库文件

函数功能

获取列表控件对象的扩展样式。

函数声明

DWORD GetExtendedStyle (

);

函数参数

返回值

扩展样式的标记值,可以为(用'|'选零至多个):

LVS_EX_GRIDLINES(0x00000001):

在报表视图中,如果设置本标记,表示显示网格线,如果不设置本标记,表示隐藏网格线。

LVS_EX_SUBITEMIMAGES(0x00000002):

在报表视图中,如果设置本标记,表示每个项目的每个字段都可以显示图标,如果不设置本标记,表示每个项目只有第一个字段才能显示图标,隐藏其他字段的图标。

LVS_EX_CHECKBOXES(0x00000004):

在任何视图中,如果设置本标记,表示每个项目都带复选框,如果不设置本标记,表示每个项目都不带复选框。

注意:可以调用CListCtrl::GetCheck()函数获取复选框状态,调用CListCtrl::SetCheck()函数设置复选框状态。

LVS_EX_TRACKSELECT(0x00000008):

在任何视图中,如果设置本标记,表示鼠标在某项目上悬停一段时间后自动选中该项目,如果不设置本标记,表示不会自动选中项目。

LVS_EX_HEADERDRAGDROP(0x00000010):

在报表视图中,如果设置本标记,表示每列报表头可以拖动顺序,但每列序号不变,如果不设置本标记,表示每列报表头顺序固定。

LVS_EX_FULLROWSELECT(0x00000020):

在报表视图中,如果设置本标记,表示在每个项目的整行所有字段都可以选中该项目,如果不设置本标记,表示只能在每个项目的第一字段选中该项目。

LVS_EX_ONECLICKACTIVATE(0x00000040):

在任何视图中,如果设置本标记,表示单击任何项目即可选中该项目,并向父窗口发送LVN_ITEMACTIVATE项目激活消息,如果不设置本标记,表示单击任何项目都不发送LVN_ITEMACTIVATE项目激活消息。

LVS_EX_TWOCLICKACTIVATE(0x00000080):

在任何视图中,如果设置本标记,表示单击任何已选中的项目,会向父窗口发送LVN_ITEMACTIVATE项目激活消息,如果不设置本标记,表示单击任何已选中的项目都不发送LVN_ITEMACTIVATE项目激活消息。

LVS_EX_FLATSB(0x00000100):

在任何视图中,如果设置本标记,表示使用扁平化风格显示滚动条,如果不设置本标记,表示使用普通风格显示滚动条。

LVS_EX_REGIONAL(0x00000200):

在图标视图中,如果设置本标记,表示只显示每个项目的图标和文本,隐藏列表控件的边框、背景、滚动条、复选框等,如果不设置本标记,表示正常显示。

LVS_EX_INFOTIP(0x00000400):

在任何视图中,如果设置本标记,表示当某个项目需要显示Tooltip工具提示控件时,向父窗口发送LVN_GETINFOTIP消息,如果不设置本标记,表示不显示Tooltip工具提示控件,也不向父窗口发送LVN_GETINFOTIP消息。

LVS_EX_UNDERLINEHOT(0x00000800):

在任何视图中,如果设置本标记,表示在鼠标悬停的项目上显示下划线,如果不设置本标记,表示在鼠标悬停的项目上不显示下划线。

LVS_EX_UNDERLINECOLD(0x00001000):

在任何视图中,如果设置本标记,表示在鼠标未悬停的项目上显示下划线,如果不设置本标记,表示在鼠标未悬停的项目上不显示下划线。

LVS_EX_MULTIWORKAREAS(0x00002000):多工作区。

LVS_EX_LABELTIP(0x00004000):

LVS_EX_BORDERSELECT(0x00008000):

在任何视图中,如果设置本标记,表示通过改变边框颜色方式来显示已选中的项目,如果不设置本标记,表示通过高亮方式来显示已选中的项目。

以下标记需要XP及以后的系统才支持:

LVS_EX_DOUBLEBUFFER(0x00010000):

在任何视图中,如果设置本标记,表示本控件使用双缓冲方式来进行重绘,双缓冲方式下可以减少频繁重绘时控件的闪烁,如果不设置本标记,表示本控件使用正常方式进行重绘,正常方式下频繁重绘可能导致控件闪烁。

LVS_EX_HIDELABELS(0x00020000):

LVS_EX_SINGLEROW(0x00040000):

LVS_EX_SNAPTOGRID(0x00080000):

LVS_EX_SIMPLESELECT(0x00100000):

以下标记需要VISTA及以后的系统才支持:

LVS_EX_JUSTIFYCOLUMNS(0x00200000):

LVS_EX_TRANSPARENTBKGND(0x00400000):

LVS_EX_TRANSPARENTSHADOWTEXT(0x00800000):

LVS_EX_AUTOAUTOARRANGE(0x01000000):

LVS_EX_HEADERINALLVIEWS(0x02000000):

LVS_EX_AUTOCHECKSELECT(0x08000000):

LVS_EX_AUTOSIZECOLUMNS(0x10000000):

LVS_EX_COLUMNSNAPPOINTS(0x40000000):

LVS_EX_COLUMNOVERFLOW(0x80000000):

错误码

线程安全

原子操作

其他说明

 

 

 

2.14.8.9 CListCtrl::SetExtendedStyle

函数名称

SetExtendedStyle

头文件

#include <Windows.h>

库文件

函数功能

设置列表控件对象的扩展样式。

函数声明

DWORD SetExtendedStyle (

DWORD dwNewStyle

);

函数参数

dwNewStyle,[输入]:

存放新的扩展样式的值,参考CListCtrl::GetExtendedStyle()函数的返回值。

返回值

成功设置了哪些扩展样式到列表控件

错误码

线程安全

原子操作

其他说明

 

 

 

2.14.8.10    CListCtrl::GetItemText(未完成)

函数名称

GetItemText

头文件

#include <afxcmn.h>

库文件

函数功能

获取列表控件中某个项目的某个字段的标签。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.14.8.11    CListCtrl::SetItemText(未完成)

函数名称

SetItemText

头文件

#include <afxcmn.h>

库文件

函数功能

设置列表控件中某个项目的某个字段的标签。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.14.8.12    CListCtrl::GetCheck

函数名称

GetCheck

头文件

#include <afxcmn.h>

库文件

函数功能

获取某个项目的复选框的状态。

函数声明

BOOL GetCheck (

int nItem

);

函数参数

nItem,[输入]:

存放项目的索引号的值,项目的索引号从0开始。

返回值

-1项目没有带复选框,或指定的项目不存在。

1:复选框处于选中状态。

0:复选框处于未选中状态。

错误码

线程安全

原子操作

其他说明

使用本函数前,需要列表控件具有LVS_EX_CHECKBOXES扩展样式。

 

 

2.14.8.13    CListCtrl::SetCheck

函数名称

SetCheck

头文件

#include <afxcmn.h>

库文件

函数功能

设置某个项目的复选框的状态。

函数声明

BOOL SetCheck (

int nItem,

BOOL fCheck = TRUE

);

函数参数

nItem,[输入]:

存放项目的索引号的值,项目的索引号从0开始。

fCheck,[输入]:

存放项目的复选框要设置的状态,非0表示选中,0表示未选中。

返回值

1:成功,或项目没有带复选框。

0:失败,可能是指定的项目不存在。

错误码

线程安全

原子操作

其他说明

 

 

 

2.14.8.14    CListCtrl::GetBkColor(未完成)

函数名称

GetBkColor

头文件

#include <afxcmn.h>

库文件

函数功能

获取列表控件的背景色。

函数声明

COLORREF GetBkColor (

void

);

函数参数

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

 

 

 

2.14.8.15    CListCtrl::SetBkColor(未完成)

函数名称

SetBkColor

头文件

#include <afxcmn.h>

库文件

函数功能

设置列表控件的背景色。

函数声明

BOOL SetBkColor (

COLORREF cr

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

 

 

 

2.14.8.16    CListCtrl::GetTextBkColor(未完成)

函数名称

GetTextBkColor

头文件

#include <afxcmn.h>

库文件

函数功能

获取列表控件的全部项目的背景色。

函数声明

COLORREF GetTextBkColor (

void

);

函数参数

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

 

 

 

2.14.8.17    CListCtrl::SetTextBkColor(未完成)

函数名称

SetTextBkColor

头文件

#include <afxcmn.h>

库文件

函数功能

设置列表控件的全部项目的背景色。

函数声明

BOOL SetTextBkColor (

COLORREF cr

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

 

 

 

2.14.8.18    CListCtrl::GetTextColor(未完成)

函数名称

GetTextColor

头文件

#include <afxcmn.h>

库文件

函数功能

获取列表控件的全部项目的标签的颜色。

函数声明

COLORREF GetTextColor (

void

);

函数参数

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

 

 

 

2.14.8.19    CListCtrl::SetTextColor(未完成)

函数名称

SetTextColor

头文件

#include <afxcmn.h>

库文件

函数功能

设置列表控件的全部项目的标签的颜色。

函数声明

BOOL SetTextColor (

COLORREF cr

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

 

 

 

2.14.8.20    CListCtrl::GetSelectedCount(未完成)

函数名称

GetSelectedCount

头文件

#include <afxcmn.h>

库文件

函数功能

获取列表控件中被选中的项目总数。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.14.8.21    LVN_GETDISPINFO(未完成)

消息名称

LVN_GETDISPINFO

函数名称

OnLvnGetdispinfo

头文件

#include <Windows.h>

产生条件

当列表控件中的某个项目的某个字段的虚拟标签重绘时,且列表控件响应了本消息,就会立即产生本消息。

函数声明

void CListCtrl::OnLvnGetdispinfo (

NMHDR * pNMHDR,

LRESULT * pResult

)

函数参数

pNMHDR,[输入&输出]:

输入时,存放当前重绘的某个项目的某个字段的信息。

输出时,存放当前重绘的某个项目的某个字段的虚拟标签。

注意:如果要修改虚拟标签字符串的内容,需要先调用CListCtrl::SetItemText()函数,然后再在本函数内修改。如果不先调用CListCtrl::SetItemText()函数,直接就在本函数内修改,有可能会导致列表控件显示出来的标签内容错误。

pResult,[输入]:

本参数无意义,直接填0即可。

返回值

错误码

线程安全

原子操作

其他说明

例子:

void CListCtrl:: OnLvnGetdispinfo(NMHDR *pNMHDR, LRESULT *pResult)

{

    NMLVDISPINFO * pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);

   

    pDispInfo->item.pszText = "这是虚拟标签的内容";

   

    *pResult = 0;

}

 

本消息需要项目的标签设置成LPSTR_TEXTCALLBACK宏才能产生。

 

 

2.14.9   CIPAddressCtrl IP地址控件类

2.14.9.1 CIPAddressCtrl::GetAddress(未完成)

函数名称

GetAddress

头文件

#include <xxx.h>

#include <xxx.h>

库文件

#pragma comment(lib, "xxx.lib")

函数功能

函数主要功能说明。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.15  消息机制

Windows下的应用程序如果要接收消息,首先需要调用GetMessage()函数或PeekMessage()函数来创建一个线程消息队列,用来存放该线程接收到的各种消息。

消息分两种,一种是进队消息,一种是不进队消息。

进队消息是指会被放入线程消息队列的消息。例如PostMessage()函数和PostThreadMesssge()函数发送的消息,应用程序需要调用GetMessage()函数或PeekMessage()函数来获取。

不进队消息是指操作系统直接调用窗口过程函数所处理的消息,不会被放入线程消息队列,没有窗口的线程是收不到这类消息的。例如,调用SendMessage()函数发送的消息,调用CreateWindow()函数创建窗口时自动发送的WM_CREATE消息,调用UpdateWindow()函数更新窗口时自动发送的WM_PAINT消息,调用DestroyWindow()函数销毁窗口时自动发送的WM_DESTROY消息等都是不进队消息。

 

UIPI是指User Interface Privilege Isolation(用户界面特权隔离),是Windows NT 6.0后(即Vista)引入的一种新的安全特性,是整个UAC机制的有机组成部分,主要用于拦截接受对自身进程MIC等级还低的进程发来的消息。

根据Windows开发规范,用户自定义消息都是大于WM_USER的。UIPI的默认规则是:一个进程如果向高于自己MIC等级的进程发送高于WM_USER的消息都会失败,而系统自定义消息则会进行选择性的过滤,某些容易引起危险的信息也会被过滤,比如WM_DROPFILES消息。

上面提到UIPI是基于进程的MIC等级的,而在Windows NT6.0以后的系统里面,由低到高一共分为六个等级:

SECURITY_MANDATORY_UNTRUSTED_RID            不信任的MIC等级

SECURITY_MANDATORY_LOW_RID                  低MIC等级,如IE浏览器进程

SECURITY_MANDATORY_MEDIUM_RID               中MIC等级,如Explorer桌面进程

SECURITY_MANDATORY_HIGH_RID                 高MIC等级,以管理员身份运行的都是这个等级

SECURITY_MANDATORY_SYSTEM_RID               系统MIC等级,服务应用程序

SECURITY_MANDATORY_PROTECTED_PROCESS_RID    受保护进程的MIC等级

这里可以看到IE是低MIC等级的,主要是为了在一定程度上解决IE的安全性问题,即使很多病毒通过IE下来,但是由于本身是通过IE系统,相应的MIC等级过低,可以防止他对其他进程造成不良影响。

UIPI的引进可以比较有效的解决一些和窗口消息相关的安全性问题,比如窗口粉碎攻击,恶意窗口信息等,但也带来了一定的兼容性问题:

1.以往通过窗口消息进行进程通信的程序很容易碰到这样那样的问题。

2.运行在高MIC等级上的进程无法接受一些常用的系统信息,如前面提到的文件拖曳消息。

 

 

2.15.1   消息发送

2.15.1.1 SendMessage(未完成)

函数名称

SendMessage

头文件

#include <Windows.h>

函数功能

函数主要功能说明。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.15.1.2 PostMessage(未完成)

函数名称

PostMessage

头文件

#include <Windows.h>

函数功能

函数主要功能说明。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

当发送的消息被UIPI用户界面特权隔离阻止了,本函数会返回失败,并设置错误码为5(拒绝访问)。

默认情况下消息队列的最大长度为10000条,如果有程序收到的消息条数超过了该限制,需要考虑重新设计程序,或者修改以下注册表项:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Windows\USERPostMessageLimit

消息队列的最大长度至少为4000。

 

 

2.15.1.3 PostThreadMessage(未完成)

函数名称

PostThreadMessage

头文件

#include <Windows.h>

函数功能

发送一个消息到指定的线程标识对应的线程消息队列,并立即返回,不会等待消息接收方处理完毕再返回。

函数声明

BOOL PostThreadMessage (

DWORD idThread,

UINT Msg,

WPARAM wParam,

LPARAM lParam

);

函数参数

idThread,[输入]:

存放消息接收方的线程标识,接收方的线程必须已经创建了线程消息队列,否则本函数返回失败。

Msg,[输入]:

存放消息值。

wParam,[输入]:

存放消息的第一个参数。

lParam,[输入]:

存放消息的第二个参数。

返回值

非0:成功。

0:失败,调用GetLastError()函数查看错误码。

错误码

ERROR_INVALID_THREAD_ID:接收方的线程标识是无效的,或者没有创建线程消息队列。

ERROR_NOT_ENOUGH_QUOTA:接收方的消息队列已达到最大值。

线程安全

原子操作

其他说明

 

 

 

2.15.2   消息获取

2.15.2.1 GetMessage(未完成)

函数名称

GetMessage

头文件

#include <Windows.h>

函数功能

本函数是从调用线程的线程消息队列里取得一个消息并将其存放到指定的消息结构体,获取消息成功后,将从消息队列中删除该消息。

如果调用线程没有消息队列,本函数就会自动创建。

此函数可以指定接收一定范围的消息值。

此函数不能接收其他线程消息队列里的消息。

此函数会一直阻塞等待直到有消息到来才返回。

函数声明

BOOL GetMessage (

LPMSG lpMsg,

HWND hWnd,

UINT wMsgFilterMin,

UINT wMsgFilterMax

);

函数参数

lpMsg,[输出]:

存放用于存放消息的消息结构体的内存指针,参考MSG

hWnd,[输入]:

存放要接收哪个窗口的窗口消息的窗口句柄,只能是调用线程创建的窗口,不能是其他线程创建的。

如果为NULL,表示接收窗口消息或者线程消息,不只接收窗口消息。

如果为-1,表示只接收线程消息,不接收窗口消息。

wMsgFilterMin,[输入]:

存放要接收的最小消息值。

如果最小消息值和最大消息值都为0,就表示获取所有消息。

例如:键盘消息的最小消息值为WM_KEYFIRST(0x0100),鼠标消息的最小消息值为WM_MOUSEFIRST (0x0200),如果只想获取WM_INPUT消息,就把最小消息值和最大消息值都设置为WM_INPUT(0x00FF)。

wMsgFilterMax,[输入]:

存放要接收的最大的消息值。

如果最小消息值和最大消息值都为0,就表示获取所有消息。

例如:键盘消息的最大消息值为WM_KEYLAST(0x0109),鼠标消息的最小消息值为WM_MOUSELAST(0x020E),如果只想获取WM_INPUT消息,就把最小消息值和最大消息值都设置为WM_INPUT(0x00FF)。

返回值

非0:成功,接收到非WM_QUIT消息。

0:成功,接收到WM_QUIT消息。

-1:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

 

 

 

2.15.2.2 PeekMessage

函数名称

PeekMessage

头文件

#include <Windows.h>

函数功能

本函数是从调用线程的线程消息队列里取得一个消息并将其存放到指定的消息结构体,获取消息成功后,可以指定是否从消息队列中删除该消息。

如果调用线程没有消息队列,本函数就会自动创建。

本函数可以指定接收一定范围的消息值。

本函数不能接收其他线程消息队列里的消息。

本函数不会阻塞等待消息到来,如果线程消息队列里没有符合条件的消息,本函数立即返回失败。

函数声明

BOOL PeekMessage (

LPMSG lpMsg,

HWND hWnd,

UINT wMsgFilterMin,

UINT wMsgFilterMax,

UINT wRemoveMsg

);

函数参数

lpMsg,[输出]:

存放用于存放消息的消息结构体的内存指针。详见MSG结构体详解。

hWnd,[输入]:

存放要接收哪个窗口的窗口消息的窗口句柄,只能是调用线程创建的窗口,不能是其他线程创建的。

如果为NULL,表示接收窗口消息或者线程消息,不只接收窗口消息。

如果为-1,表示只接收线程消息,不接收窗口消息。

wMsgFilterMin,[输入]:

存放要接收的最小消息值。

如果最小消息值和最大消息值都为0,就表示获取所有消息。

例如:键盘消息的最小消息值为WM_KEYFIRST(0x0100),鼠标消息的最小消息值为WM_MOUSEFIRST (0x0200),如果只想获取WM_INPUT消息,就把最小消息值和最大消息值都设置为WM_INPUT(0x00FF)。

wMsgFilterMax,[输入]:

存放要接收的最大的消息值。

如果最小消息值和最大消息值都为0,就表示获取所有消息。

例如:键盘消息的最大消息值为WM_KEYLAST(0x0109),鼠标消息的最小消息值为WM_MOUSELAST(0x020E),如果只想获取WM_INPUT消息,就把最小消息值和最大消息值都设置为WM_INPUT(0x00FF)。

wRemoveMsg,[输入]:

存放要如何接收消息的标记。可以为(用'|'选零至多个):

PM_NOREMOVE(0):

本函数接收到消息后,不从队列里删除该消息。

本标记不能与PM_REMOVE标记同时使用。

PM_REMOVE(1):

本函数接收到消息后,要从队列里删除该消息。

本标记不能与PM_NOREMOVE标记同时使用。

PM_NOYIELD(2):

本标志使系统不释放等待调用程序空闲的线程。

可将本标记随意组合到PM_NOREMOVE或PM_REMOVE标记。

 

默认情况下,本函数接收所有消息,也可以指定一下类型进行接收(用'|'选零至多个)

PM_QS_INPUT

接收鼠标和键盘消息。

PM_QS_PAINT

接收画图消息。

PM_QS_POSTMESSAGE

接收所有Post寄送方式发送的消息,包括WM_TIMER计时器和WM_HOTKEY热键。

PM_QS_SENDMESSAGE

接收所有Send发送方式发送的消息。

返回值

非0:成功。

0:失败,没有获取到符合条件的消息。

错误码

无。

线程安全

原子操作

其他说明

 

 

 

2.15.2.3 WaitMessage(未完成)

函数名称

WaitMessage

头文件

#include <Winuser.h>

库文件

#pragma comment(lib, "User32.lib")

函数功能

当一个线程没有消息在其消息队列中的时候,线程放弃控制权给其他的线程。WaitMessage函数挂起线程,直到一个新的消息被放入线程的消息队列中才返回。

函数声明

BOOL WaitMessage (

void

);

函数参数

返回值

非0:成功。

0:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

线程在调用一个函数核查线程消息队列后,如果消息队列中没有可读的消息,WaitMessage函数不会返回。这是因为PeekMessage、GetMessage、GetQueueStatus、WaitMessage、 MsgWaitForMultipleObjects和MsgWaitForMultipleObjectsEx这样的函数核对消息队列,改变队列的状态信息这样输入不再被认为是新的。如果连续调用WaitMessage将等到指定类型的新输入到达后才返回。已存在的未读过的输入(在上次线程检查队列之前接收的)被忽略。

 

 

2.15.3   消息处理

2.15.3.1 鼠标

2.15.3.1.1    WM_MOUSEMOVE

消息名称

WM_MOUSEMOVE(0x0200)

函数名称

OnMouseMove

头文件

#include <Windows.h>

产生条件

当鼠标在窗口的客户区上方移动时,就会立即产生本消息。

当鼠标在窗口的标题栏上方移动时,则不产生本消息。

当鼠标停留在窗口上不移动时,则不产生本消息。

当鼠标在其他窗口上移动时,则不产生本消息。

函数声明

void OnMouseLeave (

UINT nFlags,

CPoint point

);

函数参数

nFlags,[输出]:

存放产生本消息时各个虚拟键有没有被按下,可能包含多个下列值:

MK_CONTROL(0x0008):

CTRL键被按下。

MK_LBUTTON(0x0001):

鼠标左键被按下。

MK_MBUTTON(0x0010):

鼠标中键被按下。

MK_RBUTTON(0x0002):

鼠标右键被按下。

MK_SHIFT(0x0004):

SHIFT键被按下。

MK_XBUTTON1(0x0020):

第一个X按钮被按下。

MK_XBUTTON2(0x0040):

第二个X按钮被按下。

point,[输出]:

存放产生本条消息时的鼠标位置的结构体,不是接收本消息时的坐标,因为从消息的发送到接收是需要时间的。

返回值

其他说明

鼠标是否在窗口的客户区,是根据WM_NCHITTEST消息处理后的返回值来判断的,如果WM_NCHITTEST消息处理不好,有可能会导致窗口接收不到本消息。

 

 

2.15.3.1.2    WM_MOUSELEAVE

消息名称

WM_MOUSELEAVE(0x02A3)

函数名称

OnMouseLeave

头文件

#include <Windows.h>

产生条件

首先需要调用TrackMouseEvent()函数将窗口设置为需要接收本消息,当鼠标不在窗口上方时,就会立即产生本消息,无论鼠标是否是从窗口上移动出去的。

函数声明

void OnMouseLeave (

void

);

函数参数

返回值

其他说明

调用TrackMouseEvent()函数将窗口设置为需要处理本消息。例子:

TRACKMOUSEEVENT stTME;

stTME.cbSize = sizeof (stTME);//指定TRACKMOUSEEVENT结构体大小

stTME.dwFlags = TME_LEAVE;//指定需要处理WM_MOUSELEAVE消息

stTME.hwndTrack = m_hWnd;//指定要处理消息的窗口句柄

TrackMouseEvent (&stTME);//设置WM_MOUSELEAVE消息需要被处理

本消息在处理后,就不会再产生了,需要再次调用TrackMouseEvent()函数将窗口设置为需要处理本消息。

建议在WM_MOUSEMOVE消息处理函数中调用TrackMouseEvent()函数,因为这个时候正好鼠标在窗口上方,一旦鼠标移动出去,就会产生本消息。

不建议在本消息处理函数中调用TrackMouseEvent()函数,因为一旦鼠标不在窗口上方时,就会不停的产生本消息,并且即使鼠标再移动到窗口上方,还是会不停的产生本消息。

 

 

2.15.3.1.3    WM_LBUTTONDOWN

消息名称

WM_LBUTTONDOWN(0x0201)

函数名称

OnLButtonDown

头文件

#include <Windows.h>

产生条件

当鼠标在窗口的客户区上方按下左键时,就会立即产生本消息,不是左键弹起时。

函数声明

void OnLButtonDown (

UINT nFlags,

CPoint point

);

函数参数

nFlags,[输出]:

存放产生本消息时各个虚拟键有没有被按下,可能包含多个下列值:

MK_CONTROL(0x0008):

CTRL键被按下。

MK_LBUTTON(0x0001):

鼠标左键被按下。

MK_MBUTTON(0x0010):

鼠标中键被按下。

MK_RBUTTON(0x0002):

鼠标右键被按下。

MK_SHIFT(0x0004):

SHIFT键被按下。

MK_XBUTTON1(0x0020):

第一个X按钮被按下。

MK_XBUTTON2(0x0040):

第二个X按钮被按下。

point,[输出]:

存放产生本条消息时的鼠标位置的结构体,不是接收本消息时的坐标,因为从消息的发送到接收是需要时间的。

返回值

其他说明

左键弹起的时候会产生WM_LBUTTONUP消息。

 

2.15.3.2 注销、重启、关机

2.15.3.2.1    WM_QUERYENDSESSION

消息名称

WM_QUERYENDSESSION(0x0011)

函数名称

OnQueryEndSession

头文件

#include <Windows.h>

产生条件

当系统在注销、重启、关机之前,就会立即产生本消息。

本消息主要用于系统询问各个进程,系统是否能继续进行注销、重启、关机。

函数声明

BOOL OnQueryEndSession(

);

函数参数

返回值

非0:同意系统继续进行注销、重启、关机。

0:不同意系统继续进行注销、重启、关机。

其他说明

如果当前所有进程处理本消息后全部返回非0值,则系统的注销、重起、关机将继续下去,并且向所有进程再发送WM_ENDSESSION消息,并且消息参数bEnding为TRUE。

如果当前有一个进程处理本消息后返回0值,则系统的注销、重起、关机将被终止,并且不再继续对剩余的进程发送本消息,而是向已经发送过本消息的进程发送WM_ENDSESSION消息,并且消息参数bEnding为FALSE。

如果要判断系统是否真的要注销、重起、关机,只要处理WM_ENDSESSION消息,并在根据消息参数bEnding是否为TRUE,来判断系统是否真的要注销、重起、关机,然后做出相应的处理。

 

 

2.15.3.3 分辨率

2.15.3.3.1    WM_DISPLAYCHANGE

消息名称

WM_DISPLAYCHANGE(0x007E)

函数名称

WindowProc

头文件

#include <Windows.h>

产生条件

当系统改变屏幕的分辨率后,就会立即产生本消息。

本消息只能在重载的WindowProc()函数中进行处理。

函数声明

函数参数

wParam,[输出]:

存放每个像素所占的颜色位数的值,例如:24表示24位色,32表示32位色。

lParam,[输出]:

存放新分辨率的水平和垂直长度的值,低字节部分为新的水平分辨率,高字节部分为的新的垂直分辨率。

返回值

其他说明

 

 

 

2.15.3.4 窗口位置、窗口大小

2.15.3.4.1    WM_SIZING

消息名称

WM_SIZING(0x0214)

函数名称

OnSizing

头文件

#include <Windows.h>

产生条件

当窗口的左边、顶边、右边、底边的长度将要改变但还没有改变时,就会立即产生本消息,当整个窗口被移动时,则不产生。

一般是用户正在拖动窗口的边框时,就会立即产生本消息。

函数声明

void OnSizing (

UINT fwSide,

LPRECT pRect

);

函数参数

fwSide,[输出]:

存放产生本消息时窗口的哪条边或哪个角被拖动,可以为(选一至一个):

WMSZ_BOTTOM(0x0006):

底边被拖动。

WMSZ_BOTTOMLEFT(0x0007):

底边和左边被拖动,也就是左下角。

WMSZ_BOTTOMRIGHT(0x0008):

底边和右边被拖动,也就是右下角。

WMSZ_LEFT(0x0001):

左边被拖动。

WMSZ_RIGHT(0x0002):

右边被拖动。

WMSZ_TOP(0x0003):

顶边被拖动。

WMSZ_TOPLEFT(0x0004):

顶边和左边被拖动,也就是左上角。

WMSZ_TOPRIGHT(0x0005):

顶边和右边被拖动,也就是右上角。

pRect,[输入&输出]:

输入时,存放产生本条消息时,窗口大小将要改变后的位置结构体的内存指针。

输出时,存放产生本条消息后,窗口大小实际改变后的位置结构体的内存指针。

注意:程序可以修改本参数达到控制窗口大小的目的。

返回值

其他说明

产生本消息时,窗口大小实际还没有改变,调用GetWindowRect()函数获取到的还是没有改变时的大小。

 

 

2.15.3.5 计时器

2.15.3.5.1    WM_TIMER(未完成)

消息名称

WM_TIMER(0x0113)

函数名称

OnTimer

头文件

#include <Windows.h>

产生条件

当某个计时器的超时时间已过,就会立即产生本消息。

函数声明

void OnTimer (

UINT_PTR nIDEvent

)

函数参数

nIDEvent,[输出]:

存放超时时间已过的计时器的标识。

返回值

其他说明

要触发本消息,需要先调用SetTimer()函数。

由于本消息不是操作系统产生的,而是程序在调用GetMessage()函数和PeekMessage()函数时产生的,所以如果某个计时器的超时时间已过,但是程序没有来得及调用GetMessage()函数和PeekMessage()函数,则将不会产生本消息。

GetMessage()函数和PeekMessage()函数产生本消息的原理就是,当发现某个计时器的超时时间点已过,然后就产生本消息,并把超时时间点设置成未来的一个时刻,这个时刻与启动该计时器的时刻保持倍数于超时时间的增加。

 

 

2.16  WinINet(Windows Internet)互联网协议

WinINet互联网协议API主要支持三种协议:HTTP(Hypertext Transfer Protocol)万维网的超文本传输协议、FTP(File Transfer Protocol)文件传输协议和GopherGopher信息查找协议。

本API只能用于客户端连接服务端,不支持搭建服务器。

WinINet函数内置有简单却灵活的缓冲支持。从网络接收到的任何数据都会缓存到硬盘中,然后在后续请求中被获取。应用程序可以控制每个请求的缓存。对于来自服务器的HTTP请求,大多数收到的头部也被缓存。当从缓存中为HTTP请求获取响应时,也会把缓存的头部数据返回给调用者。这使得数据下载对于用户是透明的,无论数据是来自缓存还是来自网络。使用永久URL缓存函数时,应用程序必须正确地分配缓冲区以得到想要的结果。

2.16.1   解析

2.16.1.1 InternetCrackUrl(未完成)

函数名称

InternetCrackUrl

头文件

#include <Windows.h>

#include <Wininet.h>

#pragma comment(lib, "wininet.lib")

函数功能

解析一个URL统一资源定位器字符串,分别获得协议、用户名、密码、服务器地址、端口号、路径、额外信息。

函数声明

BOOL InternetCrackUrl (

LPCTSTR lpszUrl,

DWORD dwUrlLength,

DWORD dwFlags,

LPURL_COMPONENTS lpUrlComponents

);

函数参数

lpszUrl,[输入]:

存放URL统一资源定位器字符串的内存指针。

dwUrlLength,[输入]:

存放URL统一资源定位器字符串的内存长度。如果lpszUrl参数以'\0'结束,该参数可以为0。

dwFlags:[输入|输出|输入&输出],

参数说明。

lpUrlComponents,[输出]:

存放URL_COMPONENTS结构体的内存指针,解析后的各项信息就存放在此结构体里。

返回值

TRUE:成功。

FLASE:失败,调用GetlastError()函数获取错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

 

 

 

2.16.2   连接

2.16.2.1 InternetOpen(未完成)

函数名称

InternetOpen

头文件

#include <Windows.h>

#include <Wininet.h>

#pragma comment(lib, "wininet.lib")

函数功能

初始化WinINet,指定连接服务器的方式,然后返回HINTERNET句柄。返回的HINTERNET句柄用于创建对指定服务器的指定服务的连接。

函数声明

HINTERNET InternetOpen (

    LPCSTR lpszAgent,

    DWORD dwAccessType,

    LPCSTR lpszProxy,

    LPCSTR lpszProxyBypass,

    DWORD dwFlags

  );

函数参数

lpszAgent,[输入]:

指向一个字符串,该字符串指定应用程序或实体调用WinInet函数的名称。此名称用作HTTP协议用户代理,不需要就为NULL。

dwAccessType,[输入]:

连接服务器使用的方式,可以是(选一至一个):

INTERNET_OPEN_TYPE_DIRECT

解析所有本地主机,可以理解为直连。

INTERNET_OPEN_TYPE_PRECONFIG

返回注册表中代理或直接的配置。

INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY

返回注册表中代理或直接的配置,并防止对Microsoft Jscript 或 INS文件的使用。

INTERNET_OPEN_TYPE_PROXY

为代理传递请求,除非代理提供了旁路列表且解析的名字可以绕过代理;此时,函数使用INTERNET_OPEN_TYPE_DIRECT。

lpszProxy,[输入]:

指定了当dwAccessType参数为INTERNET_OPEN_TYPE_PROXY时,此参数表示代理服务器的名字。不要使用一个空的字符串,因为,该函数将使用它作为代理的名字。WinINet函数仅能识别OERN类型的代理和TIS网关。如果有安装IE,这些函数也同样支持SOCKS代理。FTP请求可由CERN类型代理或转换为HTTP请求,或使用InternetOpenUrl函数实现。如果dwAccessType参数未被设置为INTERNET_OPEN_TYPE_PROXY,本参数无意义,直接填NULL。

lpszProxyBypass,[输入]:

指向一个字符串,它指定一个可选的主机名列表或IP地址,列表可包括未知元素。如果dwAccessType参数未被设置为INTERNET_OPEN_TYPE_PROXY,本参数无意义,直接填NULL。

dwFlags,[输入]:

其他功能标记,可以是(用'|'选零至多个):

INTERNET_FLAG_ASYNC

仅能用于作用在该函数返回的句柄的子句柄上的异步请求。

INTERNET_FLAG_FROM_CACHE

不做网络请求。所有的实体都由缓存返回。如果请求条目不在缓存中,一个适当的错误将返回。

INTERNET_FLAG_OFFLINE

与INTERNET_FLAG_FROM_CACHE标记一样。

返回值

非NULL:HINTERNET句柄。

NULL:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

使用完此函数返回的HINTERNET句柄后,需要调用InternetCloseHandle()函数释放句柄资源。

 

 

2.16.2.2 InternetConnect(未完成)

函数名称

InternetConnect

头文件

#include <Windows.h>

#include <Wininet.h>

#pragma comment(lib, "wininet.lib")

函数功能

使用InternetOpen()函数获得的HINTERNET句柄来连接指定的服务器的指定的服务,然后返回HINTERNET句柄。返回的HINTERNET句柄用于和服务器之间的具体操作。

函数声明

HINTERNET InternetConnect (

    HINTERNET hInternet,

    LPCSTR lpszServerName,

    INTERNET_PORT nServerPort,

    LPCSTR lpszUserName,

    LPCSTR lpszPassword,

    DWORD dwService,

    DWORD dwFlags,

    DWORD_PTR dwContext

  );

函数参数

hInternet,[输入]:

调用InternetOpen()函数获得的HINTERNET句柄。

lpszServerName,[输入]:

要连接的服务器的IP地址或者域名。

nServerPort,[输入]:

要连接的服务器的端口号,可以自由指定,也可以是(选一至一个):

INTERNET_DEFAULT_FTP_PORT

使用默认的FTP文件传输协议服务器端口21。

INTERNET_DEFAULT_GOPHER_PORT

使用默认的Gopher信息查找系统服务器端口70。注意:仅适用于Windows XP和Windows Server 2003 R2及更早的操作系统。

INTERNET_DEFAULT_HTTP_PORT

使用默认的HTTP超文本传输协议服务器端口80。

INTERNET_DEFAULT_HTTPS_PORT

使用默认的HTTPS安全超文本传输协议服务器端口443。

INTERNET_DEFAULT_SOCKS_PORT

使用默认的SOCKS防火墙安全会话转换协议服务器端口1080。

INTERNET_INVALID_PORT_NUMBER

使用dwService参数指定的服务器使用的默认端口。

lpszUserName,[输入]:

连接服务器使用的用户名字符串。如果为NULL,则使用默认的匿名用户。

lpszPassword,[输入]:

连接服务器使用的用户名对应的密码字符串。如果lpszUserName参数和此参数都为NULL,则使用默认的匿名用户的密码。如果lpszUserName参数不为NULL,但此参数为NULL,则使用空密码。

dwService,[输入]:

使用什么协议连接服务器,可以是(选一至一个):

INTERNET_SERVICE_FTP

FTP文件传输协议。

INTERNET_SERVICE_GOPHER

Gopher信息查找系统。

注意:本标记仅适用于Windows XP和Windows Server 2003 R2及更早的操作系统。

INTERNET_SERVICE_HTTP

HTTP超文本传输协议。

dwFlags,[输入]:

其他功能标记。可以是(用'|'选零至多个):

INTERNET_FLAG_PASSIVE

如果使用FTP文件传输协议协议,且使用此标记,表示使用被动模式连接。如果使用FTP文件传输协议协议,但不使用此标记,表示使用主动模式连接。如果不是使用FTP文件传输协议协议,此标记无意义。

INTERNET_FLAG_EXISTING_CONNECT

如果使用相同的必须属性创建连接,会尝试使用现有的InternetConnect句柄。这仅仅是使用FTP操作时非常有用,因为FTP是,通常在同一会话中执行多个操作的唯一协议。缓存的WinINet一个连接句柄句柄InternetOpen生成的每个HINTERNET 。在InternetOpenUrl中和InternetConnect函数使用这个标记用于HTTP和FTP连接。

dwContext,[输入]:

Pointer to a variable that contains an application-defined value that is used to identify the application context for the returned handle in callbacks.

不需要就填NULL。

返回值

非NULL:HINTERNET句柄。

NULL:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

使用完此函数返回的HINTERNET句柄后,需要调用InternetCloseHandle()函数断开连接,并释放句柄资源。

如果使用HTTP协议连接,此时不会真正建立TCP套接字连接,只有在调用HttpSendRequest()函数后才会建立。

 

 

2.16.3   选项

2.16.3.1 InternetSetOption(未完成)

函数名称

InternetSetOption

头文件

#include <Windows.h>

#include <Wininet.h>

#pragma comment(lib, "wininet.lib")

函数功能

设置一个调用InternetOpen()或InternetConnect()函数获取的HINTERNET句柄的选项的值。

函数声明

BOOL InternetSetOption (

HINTERNET hInternet,

DWORD dwOption,

LPVOID lpBuffer,

DWORD dwBufferLength

);

函数参数

hInternet,[输入]:

存放调用InternetOpen()或InternetConnect()函数获取的HINTERNET句柄的值。

dwOption,[输入]:

要设置选项,可以是(选一至一个):

INTERNET_OPTION_CONNECT_TIMEOUT

连接远端时的超时间间,单位毫秒,默认为60000毫秒,lpBuffer参数为unsigned long类型。

INTERNET_OPTION_SEND_TIMEOUT

发送数据时的超时时间,单位毫秒,默认为30000毫秒,lpBuffer参数为unsigned long类型。

INTERNET_OPTION_RECEIVE_TIMEOUT

接收数据时的超时间间,单位毫秒,默认为30000毫秒,lpBuffer参数为unsigned long类型。

更多选项参考http://technet.microsoft.com/zh-cn/sysinternals/aa385328

lpBuffer,[输入]:

存放要设置的选项的值的内存指针,具体类型根据dwOption参数而定。

dwBufferLength,[输入]:

存放选项的值的内存长度,单位字节。

返回值

TRUE:成功。

FALSE:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

 

 

 

2.16.3.2 InternetQueryOption(未完成)

函数名称

InternetQueryOption

头文件

#include <Windows.h>

#include <Wininet.h>

#pragma comment(lib, "wininet.lib")

函数功能

查看一个调用InternetOpen()或InternetConnect()函数获取的HINTERNET句柄的选项的值。

函数声明

BOOL InternetQueryOption (

HINTERNET hInternet,

DWORD dwOption,

LPVOID lpBuffer,

LPDWORD lpdwBufferLength

);

函数参数

参数1:[输入|输出|输入&输出],参数说明。

参数2:[输入|输出|输入&输出],参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.16.4   FTP文件传输协议

2.16.4.1 目录操作

FtpCreateDirectory在FTP服务器上建立目录, 需要InternetConnect返回的会话句柄

FtpRemoveDirectory在FTP服务器上删除目录, 需要InternetConnect返回的会话句柄

FtpGetCurrentDirectory获取当前在FTP服务器上的工作目录, 需要InternetConnect返回的会话句柄

FtpSetCurrentDirectory设置在FTP服务器上的工作目录, 需要InternetConnect返回的会话句柄

 

 

2.16.4.2 文件操作

2.16.4.2.1    FtpGetFile(未完成)

函数名称

FtpGetFile

头文件

#include <Windows.h>

#include <Wininet.h>

#pragma comment(lib, "wininet.lib")

函数功能

从FTP服务器上下载指定文件到本地的指定文件。

函数声明

BOOL FtpGetFile(

HINTERNET hConnect,

LPCTSTR lpszRemoteFile,

LPCTSTR lpszNewFile,

BOOL fFailIfExists,

DWORD dwFlagsAndAttributes,

DWORD dwFlags,

DWORD_PTR dwContext

);

函数参数

hConnect,[输入]:

存放调用InternetConnect()函数返回的FTP服务器连接句柄。

lpszRemoteFile,[输入]:

存放要从FTP服务器上下载的指定文件的路径字符串的内存指针。

lpszNewFile,[输入]:

存放要下载文件到本地的指定文件的路径字符串的内存指针。

fFailIfExists,[输入]:

存放当本地的指定文件已存在时是否失败的值。

如果为非0,表示不替换已存在的文件,返回失败。

如果为0,表示替换已存在的文件。

dwFlagsAndAttributes,[输入]:

存放本地的指定文件的文件属性,可以是FILE_ATTRIBUTE_*宏。

dwFlags,[输入]:

存放下载文件时的标记。

以下是传输模式的标记,可以是(选一至一个):

FTP_TRANSFER_TYPE_UNKNOWN宏(0x0000)

用未知模式传输文件,其实就是二进制模式。

FTP_TRANSFER_TYPE_ASCII宏(0x0001):

用ASCII模式传输文件,将文件中的回车换行符转换为本机的字符。例如:UNIX系统的回车换行符为'\n',而Windows系统的回车换行符为'\r\n',用此模式可以自动转换这些字符。

FTP_TRANSFER_TYPE_BINARY宏(0x0002)

用二进制模式传输文件,不将文件中的任何字符进行转换,保证文件的内容不会改变。

INTERNET_FLAG_TRANSFER_ASCII宏(0x0001):

用ASCII模式传输文件,同FTP_TRANSFER_TYPE_ASCII宏。

INTERNET_FLAG_TRANSFER_BINARY宏(0x0002)

用二进制模式传输文件,同FTP_TRANSFER_TYPE_BINARY宏。

 

以下是传输方式的标记,可以是(用'|'选零至多个):

INTERNET_FLAG_NEED_FILE宏(0x0010)

如果文件不能被缓存,则创建一个临时文件。

INTERNET_FLAG_HYPERLINK宏(0x0400)

当决定何时从网络重载时,如果服务器没有返回Expires time和LastModified,那么强制重载。

INTERNET_FLAG_RESYNCHRONIZE宏(0x0800)

有条件地从互联网下载请求的资源。

如果缓存中的数据就是当前版本,则使用缓存中的数据;否则,重新从服务器下载资源。

INTERNET_FLAG_RELOAD宏(0x80000000)

强制程序直接从互联网获取请求的资源,不从缓存中获取,下载的信息又将重新被保存到缓存中。

注意:如果允许从缓存中获取的资源,可能会导致获取到的资源和服务器上的资源不一致。

dwContext,[输入]:

存放用于接收状态信息的回调函数的函数指针。

不需要就填NULL。

返回值

非0:成功。

0:失败,调用GetlastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

网络不好的情况下本函数有可能出现卡住不返回的情况,设置超时时间可能可以解决。

本函数存在下载成功,但实际下载的文件的长度与FTP上的文件的长度不同的情况,出现后,如果立即重新下载此文件很有可能文件长度还是不同,所以建议先删除损坏的文件,继续下载其他文件,等下载完后,断开连接,再重连,再下载。

 

 

2.16.4.2.2    FtpPutFile(未完成)

函数名称

FtpPutFile

头文件

#include <Wininet.h>

库文件

#pragma comment(lib, "Wininet.lib")

函数功能

把本地的指定文件上传到FTP服务器的指定文件。

函数声明

BOOL FtpPutFile (

HINTERNET hConnect,

LPCTSTR lpszLocalFile,

LPCTSTR lpszNewRemoteFile,

DWORD dwFlags,

DWORD_PTR dwContext

);

函数参数

hConnect,[输入]:

存放调用InternetConnect()函数返回的FTP服务器连接句柄。

lpszLocalFile,[输入]:

存放上传前本地的指定文件的路径字符串的内存指针,包括文件名。

lpszNewRemoteFile,[输入]:

存放上传后FTP服务器的指定文件的路径字符串的内存指针,包括文件名。

dwFlags,[输入]:

存放上传文件时的标记。

以下是传输模式的标记,可以是(选一至一个):

FTP_TRANSFER_TYPE_UNKNOWN宏(0x0000)

用未知模式传输文件,就是二进制模式。

FTP_TRANSFER_TYPE_ASCII宏(0x0001):

用ASCII模式传输文件,将文件中的回车换行符转换为本机的字符。例如:UNIX系统的回车换行符为'\n',而Windows系统的回车换行符为'\r\n',用此模式可以自动转换这些字符。

FTP_TRANSFER_TYPE_BINARY宏(0x0002)

用二进制模式传输文件,不将文件中的任何字符进行转换,保证文件的内容不会改变。

INTERNET_FLAG_TRANSFER_ASCII宏(0x0001):

用ASCII模式传输文件,同FTP_TRANSFER_TYPE_ASCII。

INTERNET_FLAG_TRANSFER_BINARY宏(0x0002)

用二进制模式传输文件,同FTP_TRANSFER_TYPE_BINARY。

 

以下是传输方式的标记,可以是(用'|'选零至多个):

INTERNET_FLAG_NEED_FILE宏(0x0010)

如果文件不能被缓存,则创建一个临时文件。

INTERNET_FLAG_HYPERLINK宏(0x0400)

当决定何时从网络重载时,如果服务器没有返回Expires time和LastModified,那么强制重载。

INTERNET_FLAG_RESYNCHRONIZE宏(0x0800)

有条件地从互联网下载请求的资源。

如果缓存中的数据就是当前版本,则使用缓存中的数据;否则,重新从服务器下载资源。

INTERNET_FLAG_RELOAD宏(0x80000000)

强制程序直接从互联网获取请求的资源,不从缓存中获取,下载的信息又将重新被保存到缓存中。

注意:从缓存中获取的资源,可能会和服务器上的资源不一致。

dwContext,[输入]:

Pointer to a variable that contains the application-defined value that associates this search with any application data. This parameter is used only if the application has already called InternetSetStatusCallback to set up a status callback.

不需要就填NULL。

返回值

非0:成功。

0:失败,调用GetlastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.16.4.2.3    FtpDeleteFile(未完成)

函数名称

FtpDeleteFile

头文件

#include <Windows.h>

#include <Wininet.h>

#pragma comment(lib, "wininet.lib")

函数功能

在FTP服务器上删除指定的文件。

函数声明

BOOL FtpDeleteFile (

HINTERNET hConnect,

LPCTSTR lpszFileName

);

函数参数

hConnect,[输入]:

存放调用InternetConnect()函数返回的FTP服务器连接句柄。

lpszFileName,[输入]:

存放要删除的文件的路径字符串的内存指针。

返回值

非0:成功。

0:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

 

 

 

FtpFindFirstFile在FTP服务器上查找符合条件的文件或目录,需要InternetConnect返回的会话句柄

InternetFindNextFile在FTP服务器上继续查找下一个符合条件的文件或目录,需要FtpFindFirstFile返回的会话句柄

FtpGetFileEx

FtpDeleteFile在FTP服务器上删除一个文件,需要InternetConnect返回的会话句柄

FtpRenameFile在FTP服务器上更改一个文件的名字,需要InternetConnect返回的会话句柄

FtpOpenFile在FTP服务器上打开一个文件, 需要InternetConnect返回的会话句柄

InternetReadFile直接在FTP服务器上读取文件,需要FtpOpenFile返回的会话句柄

InternetWriteFile直接在FTP服务器上写入文件,需要FtpOpenFile返回的会话句柄

 

 

2.16.5   HTTP超文本传输协议

2.16.5.1 HttpOpenRequest(未完成)

函数名称

HttpOpenRequest

头文件

#include <Windows.h>

#include <Wininet.h>

#pragma comment(lib, "wininet.lib")

函数功能

创建一个HTTP请求,返回该HTTP请求的HINTERNET句柄。

函数声明

HINTERNET HttpOpenRequest (

HINTERNET hConnect,

LPCTSTR lpszVerb,

LPCTSTR lpszObjectName,

LPCTSTR lpszVersion,

LPCTSTR lpszReferer,

LPCTSTR * lplpszAcceptTypes,

DWORD dwFlags,

DWORD_PTR dwContext

);

函数参数

hConnect,[输入]:存放调用InternetConnect()函数连接HTTP服务器后,返回的HINTERNET句柄。

lpszVerb,[输入]:存放请求名称字符串的内存指针,为NULL就表示GET请求。例如:"GET","POST"等。

lpszObjectName,[输入]:存放请求的目标对象的名称字符串的内存指针。一般是一个网页文件路径,一个可执行模块名称,一个搜索说明符等。

lpszVersion,[输入]:存放请求使用的HTTP协议版本字符串的内存指针,为NULL就表示HTTP/1.1版本。例如:"HTTP/1.0","HTTP/1.1"。

lpszReferer,[输入]:存放HTTP Referer的URL统一资源定位器字符串的内存指针。HTTP Referer是指当浏览器向HTTP服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器借此可以获得一些信息用于处理。比如从我主页上链接到一个朋友那里,他的HTTP服务器就能够从HTTP Referer中统计出每天有多少用户单击我主页上的链接访问他的网站。

lplpszAcceptTypes,[输入]:存放本次请求可以接收的文件类型列表,为表示只接收文本文件。例如:"*/*"表示可以接收所有的文件类型,"text/*"表示只接收文本文件。

dwFlags,[输入]:存放请求使用的一些标记,可以是(用'|'选零至多个):

INTERNET_FLAG_CACHE_IF_NET_FAIL:Returns the resource from the cache if the network request for the resource fails due to an ERROR_INTERNET_CONNECTION_RESET (the connection with the server has been reset) or ERROR_INTERNET_CANNOT_CONNECT (the attempt to connect to the server failed).

INTERNET_FLAG_HYPERLINK:Forces a reload if there was no Expires time and no LastModified time returned from the server when determining whether to reload the item from the network.

INTERNET_FLAG_IGNORE_CERT_CN_INVALID:Disables checking of SSL/PCT-based certificates that are returned from the server against the host name given in the request. WinINet functions use a simple check against certificates by comparing for matching host names and simple wildcarding rules.

INTERNET_FLAG_IGNORE_CERT_DATE_INVALID:Disables checking of SSL/PCT-based certificates for proper validity dates.

INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP:Disables detection of this special type of redirect. When this flag is used, WinINet functions transparently allow redirects from HTTPS to HTTP URLs.

INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS:Disables detection of this special type of redirect. When this flag is used, WinINet functions transparently allow redirects from HTTP to HTTPS URLs.

INTERNET_FLAG_KEEP_CONNECTION:Uses keep-alive semantics, if available, for the connection. This flag is required for Microsoft Network (MSN), NT LAN Manager (NTLM), and other types of authentication.

INTERNET_FLAG_NEED_FILE:Causes a temporary file to be created if the file cannot be cached.

INTERNET_FLAG_NO_AUTH:Does not attempt authentication automatically.

INTERNET_FLAG_NO_AUTO_REDIRECT:Does not automatically handle redirection in HttpSendRequest.

INTERNET_FLAG_NO_CACHE_WRITE:Does not add the returned entity to the cache.

INTERNET_FLAG_NO_COOKIES:Does not automatically add cookie headers to requests, and does not automatically add returned cookies to the cookie database.

INTERNET_FLAG_NO_UI:Disables the cookie dialog box.

INTERNET_FLAG_PRAGMA_NOCACHE:Forces the request to be resolved by the origin server, even if a cached copy exists on the proxy.

INTERNET_FLAG_RELOAD:Forces a download of the requested file, object, or directory listing from the origin server, not from the cache.

INTERNET_FLAG_RESYNCHRONIZE:Reloads HTTP resources if the resource has been modified since the last time it was downloaded. All FTP resources are reloaded.

Windows XP and Windows Server 2003 R2 and earlier:Gopher resources are also reloaded.

INTERNET_FLAG_SECURE:Uses secure transaction semantics. This translates to using Secure Sockets Layer/Private Communications Technology (SSL/PCT) and is only meaningful in HTTP requests.

dwContext,[输入]:参数说明。

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

本函数只是创建HTTP请求,并没有将HTTP请求发送到HTTP服务器,需要调用HttpSendRequest()完成发送。

 

 

2.16.5.2 HttpSendRequest(未完成)

函数名称

HttpSendRequest

头文件

#include <Windows.h>

#include <Wininet.h>

#pragma comment(lib, "wininet.lib")

函数功能

根据调用HttpOpenRequest()函数获取的HTTP请求的HINTERNET句柄,发送该HTTP请求到HTTP服务器。

函数声明

BOOL HttpSendRequest (

HINTERNET hRequest,

LPCTSTR lpszHeaders,

DWORD dwHeadersLength,

LPVOID lpOptional,

DWORD dwOptionalLength

);

函数参数

参数1:[输入|输出|输入&输出],参数说明。

参数2:[输入|输出|输入&输出],参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.16.6   断开

2.16.6.1 InternetCloseHandle(未完成)

函数名称

InternetCloseHandle

头文件

#include <Windows.h>

#include <Wininet.h>

#pragma comment(lib, "wininet.lib")

函数功能

断开与服务器的连接,并释放调用InternetOpen()函数或InternetConnect()函数获得的HINTERNE句柄资源。

函数声明

BOOL InternetCloseHandle (

HINTERNET hInternet

);

函数参数

hInternet,[输入]:

存放调用InternetOpen()函数或InternetConnect()函数获得的HINTERNET句柄。

返回值

0:失败,调用GetLastError()函数查看错误码。

非0:成功。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

 

 

 

2.17  INI配置文件

2.17.1   INI配置文件简介

为什么要用INI文件?如果我们程序没有任何配置文件时,这样的程序对外是全封闭的,一旦程序需要修改一些参数必须要修改程序代码本身并重新编译,这样很不好,所以要用配置文件,让程序出厂后还能根据需要进行必要的配置;配置文件有很多如INI配置文件,XML配置文件,还有就是可以使用系统注册表等。

本文主要是为读者在实现读写INI配置文件模块之前,提供有关INI文件的格式信息。

在早期的windows桌面系统中主要是用INI文件作为系统的配置文件,从win95以后开始转向使用注册表,但是还有很多系统配置是使用INI文件的。其实INI文件就是简单的text文件,只不过这种txt文件要遵循一定的INI文件格式。现在的WINCE系统上也常常用INI文件作为配置文件,这次研究INI文件的目的就是为了我的GPS定位系统客户端写个系统配置文件。“.INI ”就是英文 “initialization”的头三个字母的缩写;当然INI file的后缀名也不一定是".ini"也可以是".cfg",".conf ”或者是".txt"。

经典格式:

INI文件的格式很简单,最基本的三个要素是:parameters,sections和comments。

什么是parameters元素?

INI所包含的最基本的“元素”就是parameter;每一个parameter都有一个name和一个value,name和value是由等号“=”隔开。name在等号的左边。

如:

name = value

什么是sections章节?

所有的parameters都是以sections为单位结合在一起的。所有的section名称都是独占一行,并且sections名字都被方括号包围着([ and ])。在section声明后的所有parameters都是属于该section。对于一个section没有明显的结束标志符,一个section的开始就是上一个section的结束,或者是end of the file。Sections一般情况下不能被nested,当然特殊情况下也可以实现sections的嵌套。

section如下所示:

[section]

什么是comments注释?

在INI文件中注释语句是以分号“;”开始的。所有的所有的注释语句不管多长都是独占一行直到结束的。在分号和行结束符之间的所有内容都是被忽略的。

注释实例如下:

; comments text

当然,上面讲的都是最经典的INI文件格式,随着使用的需求INI文件的格式也出现了很多变种;

INI实例:

; last modified 1 April 2001 by John Doe 

[owner]  name=John Doe 

organization=Acme Products    

[database] 

server=192.0.2.42

; use IP address in case network name resolution is not working 

port=143 

file = "acme payroll.dat" 

2.17.2   WritePrivateProfileString(未完成)

函数名称

WritePrivateProfileString

头文件

#include <Windows.h>

函数功能

向指定的INI配置文件的指定章节下的指定节点写入指定的字符串值,本系列函数支持多线程同时读写同一个INI配置文件。

函数声明

BOOL WritePrivateProfileString (

LPCSTR lpAppName,

LPCSTR lpKeyName,

LPCSTR lpString,

LPCSTR lpFileName

);

函数参数

lpAppName,[输入]:

存放章节名称字符串的内存指针。

如果指定的章节不存在,会自动在INI配置文件末尾添加。

lpKeyName,[输入]:

存放节点名称字符串的内存指针。

节点名称中不能出现等于符号,因为每行的第一个等于符合为节点名称和值的分隔符,且值的内容可以出现等于符号。

如果指定的节点不存在,会自动在章节末尾添加。

如果本参数为NULL,则会删除指定的章节和章节下的所有节点。

lpString,[输入]:

存放值的字符串的指针。

如果指定的节点已存在,会自动替换以前的值。

如果本参数为NULL,则会删除指定的章节下的指定的节点。

lpFileName,[输入]:

存放INI配置文件的路径字符串的内存指针。

可以是相对或绝对路径,包括文件名。

如果INI配置文件不存在,会自动创建。

返回值

非0:成功。

0:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

是,只在调用本系列函数时。

其他说明

 

 

 

2.17.3   WritePrivateProfileSection(未完成)

函数名称

WritePrivateProfileSection

头文件

#include <Windows.h>

函数功能

向指定的INI配置文件的指定章节下替换所有节点为指定的节点,本系列函数支持多线程同时读写同一个INI配置文件。

函数声明

BOOL WritePrivateProfileSection (

LPCSTR lpAppName,

LPCSTR lpString,

LPCSTR lpFileName

);

函数参数

lpAppName,[输入]:

存放章节名称字符串的内存指针,如果指定的章节不存在,会自动在INI配置文件末尾添加。

lpString,[输入]:

存放多个节点名称字符串的内存指针,节点之间用'\0'字符分隔,最后一个节点用'\0\0'结束。

例如:"key1=value1\0key2=value2\0\0"。

lpFileName,[输入]:

存放INI配置文件的路径字符串的内存指针,可以是相对或绝对路径,路径字符串必须包含文件名。

如果INI配置文件不存在,会自动创建。

返回值

非0:成功。

0:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

是,只在调用本系列函数时。

其他说明

 

 

 

2.17.4   WritePrivateProfileStruct(未完成)

函数名称

WritePrivateProfileStruct

头文件

#include <Windows.h>

函数功能

向指定的INI配置文件的指定章节下的指定节点写入指定的结构体值,用本函数写入的结构体值只能用GetPrivateProfileStruct()函数读取出来,本系列函数支持多线程同时读写同一个INI配置文件。

函数声明

BOOL WritePrivateProfileStruct (

LPCSTR lpszSection,

LPCSTR lpszKey,

LPVOID lpStruct,

UINT uSizeStruct,

LPCSTR szFile

);

函数参数

lpszSection,[输入]:

存放章节名称字符串的内存指针。

如果指定的章节不存在,会自动在INI配置文件末尾添加。

lpszKey,[输入]:

存放节点名称字符串的内存指针。

节点名称中不能出现等于符号,因为每行的第一个等于符合为节点名称和值的分隔符,且值的内容可以出现等于符号。

如果指定的节点不存在,会自动在章节末尾添加。

如果本参数为NULL,则会删除指定的章节和章节下的所有节点。

不能为""空字符串,否则会内存读写错误。

lpStruct,[输入]:

存放结构体值的内存指针。

如果指定的节点已存在,会自动替换以前的值。

如果本参数为NULL,则会删除指定的章节下的指定的节点。

uSizeStruct,[输入]:

存放结构体值的内存的长度。

szFile,[输入]:

存放INI配置文件的路径字符串的内存指针,可以是相对或绝对路径,包括文件名。

返回值

非0:成功。

0:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

是,只在调用本系列函数时。

其他说明

 

 

 

2.17.5   GetPrivateProfileSectionNames(未完成)

函数名称

GetPrivateProfileSectionNames

头文件

#include <Windows.h>

函数功能

从指定的INI配置文件的读取所有的章节名称字符串,本系列函数支持多线程同时读写同一个INI配置文件。

函数声明

DWORD GetPrivateProfileSectionNames (

LPSTR lpszReturnBuffer,

DWORD nSize,

LPCSTR lpFileName

);

函数参数

lpszReturnBuffer,[输出]:

存放所有的章节名称字符串的内存指针,节点之间用'\0'字符分隔,最后一个章节用'\0\0'结束。

例如:"Section1\0Section2\0…SectionN\0\0"。

nSize,[输入]:

存放所有的章节名称字符串的内存的长度。

lpFileName,[输入]:

存放INI配置文件的路径字符串的内存指针,可以是相对或绝对路径,包括文件名。

返回值

输出了多少字节到存放所有的章节名称字符串的内存,包括每个章节名称的'\0'结束符,不包括最后一个'\0'结束符。

错误码

线程安全

原子操作

是,只在调用本系列函数时。

其他说明

 

 

 

2.17.6   GetPrivateProfileSection(未完成)

函数名称

GetPrivateProfileSection

头文件

#include <Windows.h>

函数功能

从指定的INI配置文件的指定章节下读取所有的节点名称和值字符串,本系列函数支持多线程同时读写同一个INI配置文件。

函数声明

DWORD GetPrivateProfileSection (

LPCWSTR lpAppName,

LPWSTR lpReturnedString,

DWORD nSize,

LPCWSTR lpFileName

);

函数参数

lpAppName,[输入]:

存放指定的章节名称字符串的内存指针,字符串中不区分大小写字母。

lpszReturnBuffer,[输出]:

存放所有的节点名称和值字符串的内存指针,节点之间用'\0'字符分隔,最后一个节点用'\0\0'结束,例如:"Key1=Value1\0Key2=Value2\0…KeyN=ValueN\0\0"。

nSize,[输入]:

存放所有的节点名称和值字符串的内存的长度。

lpFileName,[输入]:

存放INI配置文件的路径字符串的内存指针,可以是相对或绝对路径,包括文件名。

返回值

非0:所有的节点名称和值字符串的长度,包括所有的分隔符'\0',不包括最后的'\0'结束符。如果存放所有的节点名称和值字符串的内存不够长,返回值就是内存的长度减2。

0:失败,或存放所有的节点名称和值字符串的内存的长度小于等于2。

错误码

线程安全

原子操作

是,只在调用本系列函数时。

其他说明

 

 

 

2.17.7   GetPrivateProfileString(未完成)

函数名称

GetPrivateProfileString

头文件

#include <Windows.h>

函数功能

从指定的INI配置文件的指定章节下的指定节点读取字符串值到指定的内存,本系列函数支持多线程同时读写同一个INI配置文件。

函数声明

DWORD GetPrivateProfileString (

LPCSTR lpAppName,

LPCSTR lpKeyName,

LPCSTR lpDefault,

LPSTR lpReturnedString,

DWORD nSize,

LPCTSTR lpFileName

);

函数参数

lpAppName,[输入]:

存放指定的章节名称字符串的内存指针,字符串中不区分大小写字母。

lpKeyName,[输入]:

存放指定的节点名称字符串的内存指针,字符串中不区分大小写字母。

节点名称中不能出现等于符号,因为每行的第一个等于符合为节点名称和值的分隔符,且值的内容可以出现等于符号。

lpDefault,[输入]:

存放缺省值的内存指针。如果指定的INI配置文件或章节或节点未找到,那么就强制用缺省值代替。

如果本参数为NULL,就表示""空字符串。

lpReturnedString,[输出]:

存放指定节点的字符串值的内存指针。

nSize,[输入]:

存放指定节点的字符串值的内存长度。

lpFileName,[输入]:

存放INI配置文件的路径字符串的内存指针,可以是相对或绝对路径,包括文件名。

返回值

字符串值的长度,不包括'\0'结束符。

如果读取失败,返回值为0,且存放字符串值的内存的第一个字节会设置成'\0'。

错误码

线程安全

原子操作

是,只在调用本系列函数时。

其他说明

章节名称、节点名称、节点值前后的无意义空格在查找和获取时都将自动去掉,例如:[Section]、[  Section]、[Section  ]都表示是Section章节,key=value、key  =value  、  key  =  value  都表示key节点的值为value。

 

 

2.17.8   GetPrivateProfileInt(未完成)

函数名称

GetPrivateProfileInt

头文件

#include <Windows.h>

函数功能

从指定的INI配置文件的指定章节下的指定节点读取非负整数值到指定的内存,本系列函数支持多线程同时读写同一个INI配置文件。

函数声明

UINT GetPrivateProfileInt (

LPCSTR lpAppName,

LPCSTR lpKeyName,

INT nDefault,

LPCSTR lpFileName

);

函数参数

lpAppName,[输入]:

存放指定的章节名称字符串的内存指针,字符串中不区分大小写字母。

lpKeyName,[输入]:

存放指定的节点名称字符串的内存指针,字符串中不区分大小写字母。

节点名称中不能出现等于符号,因为每行的第一个等于符合为节点名称和值的分隔符,且值的内容可以出现等于符号。

nDefault,[输入]:

存放缺省值的内存指针。

如果指定的INI配置文件或指定的章节或指定的节点未找到,那么就强制用缺省值代替。

lpFileName,[输入]:

存放INI配置文件的路径字符串的内存指针,可以是相对或绝对路径,包括文件名。

返回值

读取到的非负整数值

错误码

线程安全

原子操作

是,只在调用本系列函数时。

其他说明

章节名称、节点名称、节点值前后的无意义空格在查找和获取时都将自动去掉,例如:[Section]、[  Section]、[Section  ]都表示是Section章节,key=value、key  =value  、  key  =  value  都表示key节点的值为value。

 

 

2.17.9   GetPrivateProfileStruct(未完成)

函数名称

GetPrivateProfileStruct

头文件

#include <Windows.h>

函数功能

从指定的INI配置文件的指定章节下的指定节点读取结构体值到指定的内存,结构体值必须是调用WritePrivateProfileStruct()函数写入的,本系列函数支持多线程同时读写同一个INI配置文件。

函数声明

BOOL GetPrivateProfileStruct (

LPCSTR lpszSection,

LPCSTR lpszKey,

LPVOID lpStruct,

UINT uSizeStruct,

LPCSTR szFile

);

函数参数

lpszSection,[输入]:

存放指定的章节名称字符串的内存指针,字符串中不区分大小写字母。

lpszKey,[输入]:

存放指定的节点名称字符串的内存指针,字符串中不区分大小写字母。

节点名称中不能出现等于符号,因为每行的第一个等于符合为节点名称和值的分隔符,且值的内容可以出现等于符号。

lpStruct,[输出]:

存放结构体值的内存指针。

uSizeStruct,[输入]:

存放结构体值的内存的长度。

szFile,[输入]:

存放INI配置文件的路径字符串的内存指针,可以是相对或绝对路径,路径字符串必须包含文件名。

返回值

非0:成功。

0:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

是,只在调用本系列函数时。

其他说明

 

 

 

2.18  音频

用CWaveFile类操作WAVE格式的文件。

waveInGetDevCaps

waveInGetErrorText

waveInGetID

waveInGetPosition

waveInMessage

waveOutBreakLoop

waveOutClose

waveOutGetDevCaps

waveOutGetErrorText

waveOutGetID

waveOutGetPitch

waveOutGetPlaybackRate

waveOutGetPosition

waveOutGetVolume

waveOutMessage

waveOutPause

waveOutPrepareHeader

waveOutReset

waveOutRestart

waveOutSetPitch

waveOutSetPlaybackRate

waveOutSetVolume

waveOutUnprepareHeader

2.18.1   输入

2.18.1.1 waveInGetNumDevs

函数名称

waveInGetNumDevs

头文件

#include <Mmsystem.h>

库文件

#pragma comment(lib, "Winmm.lib")

函数功能

获取可用的音频输入设备的数量,不包括已禁用、已断开的音频输入设备。

函数声明

UINT waveInGetNumDevs (

void

);

函数参数

返回值

0:没有音频输入设备,或发生错误。

其他:音频输入设备的数量。

错误码

线程安全

原子操作

其他说明

 

 

 

2.18.1.2 waveInOpen(未完成)

函数名称

waveInOpen

头文件

#include <Mmsystem.h>

库文件

#pragma comment(lib, "Winmm.lib")

函数功能

打开指定的音频输入设备,并获取音频输入设备句柄。

打开后,将产生WIM_OPEN消息。

函数声明

MMRESULT waveInOpen (

LPHWAVEIN phwi,

UINT uDeviceID,

LPCWAVEFORMATEX pwfx,

DWORD_PTR dwCallback,

DWORD_PTR dwCallbackInstance,

DWORD fdwOpen

);

函数参数

phwi,[输出]:

存放音频输入设备句柄的变量的内存指针。

如果fdwOpen参数为WAVE_FORMAT_QUERY宏,本参数无意义。

uDeviceID,[输入]:

存放设备ID,可以是一个设备标识符或一个已打开的音频输入设备句柄,设备标识符应该为从0到音频输入设备的数量,也可以为(选一至一个):

WAVE_MAPPER宏(0xFFFF):系统自动根据指定的音频格式结构体选择的音频输入设备。

pwfx,[输入]:

存放音频输入时所用的音频格式结构体的内存指针,参考WAVEFORMATEX

dwCallback,[输入]:

存放指向回调函数的指针或窗口句柄,用于处理音频输入过程中产生的消息。

回调函数参考waveInProc

dwCallbackInstance,[输入]:

存放传递给回调函数的数据,以回调函数的参数方式传递。

如果回调方式为窗口方式,本参数无意义。

fdwOpen,[输入]:

存放打开音频输入设备时的标记,可以为(选一至一个):

CALLBACK_EVENT

dwCallback参数为事件句柄。

CALLBACK_FUNCTION

如果设置本标记,表示回调函数回调方式,dwCallback参数为回调函数的内存指针,回调函数声明参考waveInProc。该回调函数会一直在另外一个独立的新线程中被调用执行。

CALLBACK_THREAD

如果设置本标记,表示采用线程消息回调方式,dwCallback参数为线程ID,参数类型为DWORD。

当音频输入设备句柄已经被调用waveInClose()函数关闭了,窗口将收到MM_WIM_OPEN消息。

当音频输入设备已经完成一个音频数据块的采集,窗口将收到MM_WIM_DATA消息。

当音频输入设备句柄已经被调用waveInOpen()函数打开了,窗口将收到MM_WOM_CLOSE消息。

CALLBACK_WINDOW

如果设置本标记,表示采用窗口消息回调方式,dwCallback参数为窗口句柄,参数类型为HWND。

当音频输入设备句柄已经被调用waveInClose()函数关闭了,窗口将收到MM_WIM_OPEN消息。

当音频输入设备已经完成一个音频数据块的采集,窗口将收到MM_WIM_DATA消息。

当音频输入设备句柄已经被调用waveInOpen()函数打开了,窗口将收到MM_WOM_CLOSE消息。

CALLBACK_NULL

不使用任何回调机制。

本标记是默认标记。

 

WAVE_MAPPED_DEFAULT_COMMUNICATION_DEVICE

If this flag is specified and the uDeviceID parameter is WAVE_MAPPER, the function opens the default communication device.

This flag applies only when uDeviceID equals WAVE_MAPPER.

Note  Requires Windows 7

WAVE_FORMAT_DIRECT

如果设置本标记,表示通过指定的音频输入设备采集到的音频数据块结构体,不会被Abstract Control Model(ACM)驱动转换。

如果不设置本标记,表示通过指定的音频输入设备采集到的音频数据块结构体,可能会被Abstract Control Model(ACM)驱动转换。

WAVE_FORMAT_QUERY

如果设置本标记,表示查询音频输入设备是否支持指定的音频格式结构体,不会打开音频输入设备,phwi参数将无意义,支持就会返回MMSYSERR_NOERROR宏,不支持就会返回WAVERR_BADFORMAT宏。

如果不设置本标记,表示查询音频输入设备是否支持指定的音频格式结构体,并打开音频输入设备,phwi参数将有意义,支持并打开成功就会返回MMSYSERR_NOERROR宏,不支持就会返回WAVERR_BADFORMAT宏,或其他错误。

WAVE_MAPPED宏(0x0004)

The uDeviceID parameter specifies a waveform-audio device to be mapped to by the wave mapper.

返回值

MMSYSERR_NOERROR宏(0x0000):成功。

MMSYSERR_ALLOCATED宏(0x0004):Specified resource is already allocated.

MMSYSERR_BADDEVICEID宏(0x0002):Specified device identifier is out of range.

MMSYSERR_NODRIVER宏(0x0006):没有音频输入设备。

MMSYSERR_NOMEM宏(0x0007):不能分配或锁定内存。

WAVERR_BADFORMAT宏(0x0020):尝试打开的音频格式不被音频输入设备支持。

错误码

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

同一进程中,如果多次打开同一音频输入设备,获得的音频输入设备句柄都是一样的。

 

 

2.18.1.3 waveInProc

函数名称

waveInProc

头文件

#include <Mmsystem.h>

库文件

函数功能

本函数为音频输入设备回调函数的声明,当音频输入设备被打开、关闭、完成一个音频数据块的采集时,系统将自动回调本函数。

函数声明

void waveInProc (

HWAVEIN hwi,

UINT uMsg,

DWORD_PTR dwInstance,

DWORD_PTR dwParam1,

DWORD_PTR dwParam2

);

函数参数

hwi,[输入]:

存放音频输入设备句柄。

uMsg,[输入]:

存放音频输入设备的消息类型,可以为:

WIM_CLOSE宏(0x03BF):当音频输入设备句柄已经被调用waveInClose()函数关闭了,将收到本消息。

WIM_DATA宏(0x03C0):当音频输入设备已经完成一个音频数据块的采集,将收到本消息。

WIM_OPEN宏(0x03BE):当音频输入设备句柄已经被调用waveInOpen()函数打开了,将收到本消息。

dwInstance,[输入]:

存放音频输入设备句柄被调用waveInOpen()函数打开时的dwCallbackInstance参数。

程序可以自由通过设置不同的本参数,来区分是哪一个音频输入设备。

dwParam1,[输入]:

存放第一个消息参数。

如果uMsg参数为WIM_DATA宏时,本参数为已经完成采集的音频数据块结构体的内存指针,类型为WAVEHDR *。

如果uMsg参数为WIM_CLOSE宏、WIM_OPEN宏时,本参数无意义。

dwParam2,[输入]:

存放第二个消息参数,本参数无意义。

返回值

错误码

线程安全

原子操作

其他说明

 

 

 

2.18.1.4 waveInPrepareHeader

函数名称

waveInPrepareHeader

头文件

#include <Mmsystem.h>

库文件

#pragma comment(lib, "Winmm.lib")

函数功能

初始化音频数据块结构体。

函数声明

MMRESULT waveInPrepareHeader (

HWAVEIN hwi,

LPWAVEHDR pwh,

UINT cbwh

);

函数参数

hwi,[输入]:

存放音频输入设备句柄。

pwh,[输入]:

存放一个音频数据块结构体的内存指针,参考WAVEHDR

cbwh,[输入]:

存放音频数据块结构体的内存长度,单位指针。

返回值

MMSYSERR_NOERROR宏(0x0000):成功。

MMSYSERR_INVALHANDLE宏(0x0005):设备句柄无效。

MMSYSERR_NOMEM宏(0x0007):不能分配或锁定内存。

MMSYSERR_HANDLEBUSY宏(0x000C):其他线程正在使用该设备。

错误码

线程安全

原子操作

其他说明

当不再需要使用音频数据块结构体时,必须调用waveInUnprepareHeader()函数释放,否则会内存泄漏。

 

 

2.18.1.5 waveInUnprepareHeader(未完成)

函数名称

waveInUnprepareHeader

头文件

#include <Mmsystem.h>

库文件

#pragma comment(lib, "Winmm.lib")

函数功能

释放已经初始化的音频数据块结构体。

函数声明

MMRESULT waveInUnprepareHeader (

HWAVEIN hwi,

LPWAVEHDR pwh,

UINT cbwh

);

函数参数

hwi,[输入]:

存放音频输入设备句柄。

pwh,[输入]:

存放一个音频数据块结构体的内存指针,参考WAVEHDR

cbwh,[输入]:

存放音频数据块结构体的内存长度,单位指针。

返回值

MMSYSERR_NOERROR宏(0x0000):成功。

MMSYSERR_INVALHANDLE宏(0x0005):设备句柄无效。

MMSYSERR_NOMEM宏(0x0007):不能分配或锁定内存。

MMSYSERR_HANDLEBUSY宏(0x000C):其他线程正在使用该设备。

WAVERR_STILLPLAYING宏(0x0021):音频数据块结构体还添加在音频输入设备上。

错误码

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

要释放的音频数据块结构体必须已经从音频输入设备上移除,否则无法释放。

 

 

2.18.1.6 waveInAddBuffer(未完成)

函数名称

waveInAddBuffer

头文件

#include <Mmsystem.h>

库文件

#pragma comment(lib, "Winmm.lib")

函数功能

将已经初始化的音频数据块结构体添加到音频输入设备上。

同一个音频输入设备上可以添加多个音频数据块结构体,这样可以保证音频输入的连续性。

当一个音频数据块结构体已经完成采集后,该结构体会自动从音频输入设备上移除。

如果要实现连续音频输入,就在音频输入设备上添加多个音频数据块结构体,当某个采集好后被自动移除后,再立即添加进去,这样音频输入就不会中断,具体几个需要自己试,一般两个就够。

函数声明

MMRESULT waveInAddBuffer (

HWAVEIN hwi,

LPWAVEHDR pwh,

UINT cbwh

);

函数参数

hwi,[输入]:

存放音频输入设备句柄。

pwh,[输入]:

存放一个已经调用waveInPrepareHeader()函数初始化的音频数据块结构体的内存指针。

cbwh,[输入]:

存放音频数据块结构体的内存长度,单位指针。

返回值

MMSYSERR_NOERROR宏(0x0000):成功。

MMSYSERR_INVALHANDLE宏(0x0005):设备句柄无效。

MMSYSERR_NOMEM宏(0x0007):不能分配或锁定内存。

MMSYSERR_HANDLEBUSY宏(0x000C):其他线程正在使用该设备。

WAVERR_UNPREPARED宏(0x0022):音频数据块结构体未初始化。

错误码

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

如果不再需要音频输入,需先调用waveInClose()函数停止音频输入,再调用waveInReset()函数移除音频输入设备上所有的音频数据块结构体。

 

 

2.18.1.7 waveInStart(未完成)

函数名称

waveInStart

头文件

#include <Mmsystem.h>

库文件

#pragma comment(lib, "Winmm.lib")

函数功能

让一个已经打开的音频输入设备句柄开始音频输入。

当完成一个音频数据块的采集后,将产生WIM_DATA消息。

函数声明

MMRESULT waveInStart (

HWAVEIN hwi

);

函数参数

hwi,[输入]:

存放音频输入设备句柄。

返回值

MMSYSERR_NOERROR宏(0x0000):成功。

MMSYSERR_INVALHANDLE宏(0x0005):设备句柄无效。

MMSYSERR_NODRIVER宏(0x0006):没有音频输入设备。

MMSYSERR_NOMEM宏(0x0007):不能分配或锁定内存。

错误码

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

 

 

 

2.18.1.8 waveInStop(未完成)

函数名称

waveInStop

头文件

#include <Mmsystem.h>

库文件

#pragma comment(lib, "Winmm.lib")

函数功能

让一个已经开始音频输入的音频输入设备句柄停止音频输入。

停止音频输入后,将不再产生WIM_DATA消息。

函数声明

MMRESULT waveInStop (

HWAVEIN hwi

);

函数参数

hwi,[输入]:

存放音频输入设备句柄。

返回值

MMSYSERR_NOERROR宏(0x0000):成功。

MMSYSERR_INVALHANDLE宏(0x0005):设备句柄无效。

MMSYSERR_NODRIVER宏(0x0006):没有音频输入设备。

MMSYSERR_NOMEM宏(0x0007):不能分配或锁定内存。

错误码

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

如果音频输入设备正在音频输入,但还没有完成一个音频数据块的采集,则会立即中断采集,并产生WIM_DATA消息,音频数据块结构体中的dwBytesRecorded成员变量将存放实际数据的内存长度。

本函数不会移除还没有使用的音频数据块。

 

 

2.18.1.9 waveInReset(未完成)

函数名称

waveInReset

头文件

#include <Mmsystem.h>

库文件

#pragma comment(lib, "Winmm.lib")

函数功能

让一个已经开始音频输入的音频输入设备句柄停止音频输入,并将已经添加到音频输入设备上的所有音频数据块结构体全部移除。

函数声明

MMRESULT waveInReset (

HWAVEIN hwi

);

函数参数

hwi,[输入]:

存放音频输入设备句柄。

返回值

MMSYSERR_NOERROR宏(0x0000):成功。

MMSYSERR_INVALHANDLE宏(0x0005):设备句柄无效。

MMSYSERR_NODRIVER宏(0x0006):没有音频输入设备。

MMSYSERR_NOMEM宏(0x0007):不能分配或锁定内存。

错误码

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

如果音频输入设备正在音频输入,但还没有完成一个音频数据块的采集,则会立即中断采集,并产生WIM_DATA消息,音频数据块结构体中的dwBytesRecorded成员变量将存放实际数据的内存长度。

 

 

2.18.1.10    waveInClose(未完成)

函数名称

waveInClose

头文件

#include <Mmsystem.h>

库文件

#pragma comment(lib, "Winmm.lib")

函数功能

让一个已经打开的播放设备句柄关闭。

如果播放设备上还有音频数据块结构体,必须先移除,否则会导致关闭失败。

函数声明

MMRESULT waveInClose (

HWAVEIN hwi

);

函数参数

hwi,[输入]:

存放音频输入设备句柄。

返回值

MMSYSERR_NOERROR宏(0x0000):成功。

MMSYSERR_INVALHANDLE宏(0x0005):设备句柄无效。

MMSYSERR_NODRIVER宏(0x0006):没有音频输入设备。

MMSYSERR_NOMEM宏(0x0007):不能分配或锁定内存。

WAVERR_STILLPLAYING宏(0x0021):音频输入设备上还有音频数据块结构体。

错误码

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

 

 

 

2.18.2   输出

2.18.2.1 waveOutGetNumDevs

函数名称

waveOutGetNumDevs

头文件

#include <Mmsystem.h>

库文件

#pragma comment(lib, "Winmm.lib")

函数功能

获取可用的播放设备的数量,不获取已禁用、已断开的播放设备。

函数声明

UINT waveOutGetNumDevs (

void

);

函数参数

无。

返回值

0:没有播放设备,或发生错误。

其他:播放设备的数量。

错误码

线程安全

原子操作

其他说明

 

 

 

2.18.2.2 waveOutOpen(未完成)

函数名称

waveOutOpen

头文件

#include <Mmsystem.h>

库文件

#pragma comment(lib, "Winmm.lib")

函数功能

打开指定的播放设备,并获取播放设备句柄。

打开后,将产生WOM_OPEN消息。

函数声明

MMRESULT waveOutOpen (

LPHWAVEOUT phwo,

UINT_PTR uDeviceID,

LPWAVEFORMATEX pwfx,

DWORD_PTR dwCallback,

DWORD_PTR dwCallbackInstance,

DWORD fdwOpen

);

函数参数

phwo,[输出]:

存放播放设备句柄的变量的内存指针。

如果fdwOpen参数为WAVE_FORMAT_QUERY宏,本参数无意义。

uDeviceID,[输入]:

存放设备ID,可以是一个设备标识符或一个已打开的播放设备句柄,设备标识符应该从0到播放设备的数量,也可以为(选一至一个):

WAVE_MAPPER宏(0xFFFF):系统自动根据指定的音频格式结构体选择的播放设备。

pwfx,[输入]:

存放播放时所用的音频格式结构体的内存指针,参考WAVEFORMATEX

dwCallback,[输入]:

存放指向回调函数的指针或窗口句柄,用于处理播放过程中产生的消息。

dwCallbackInstance,[输入]:

存放传递给回调函数的数据,以回调函数的参数方式传递。

如果回调方式为窗口方式,本参数无意义。

fdwOpen,[输入]:

存放打开播放设备时的标记,可以为(选一至一个):

CALLBACK_EVENT:dwCallback参数为事件句柄。

CALLBACK_FUNCTION:dwCallback参数为回调函数的内存指针,回调函数声明参考waveOutProc。该回调函数会一直在另外一个独立的新线程中执行。

CALLBACK_THREAD:dwCallback参数为线程ID。

CALLBACK_WINDOW:dwCallback参数为窗口句柄,dwCallback参数类型为HWND。

CALLBACK_NULL:不使用任何回调机制。本标记是默认标记。

WAVE_ALLOWSYNC:If this flag is specified, a synchronous waveform-audio device can be opened. If this flag is not specified while opening a synchronous driver, the device will fail to open.

WAVE_MAPPED_DEFAULT_COMMUNICATION_DEVICE:If this flag is specified and the uDeviceID parameter is WAVE_MAPPER, the function opens the default communication device.

This flag applies only when uDeviceID equals WAVE_MAPPER.

Note  Requires Windows 7

WAVE_FORMAT_DIRECT:If this flag is specified, the ACM driver does not perform conversions on the audio data.

WAVE_FORMAT_QUERY:The function queries the device to determine whether it supports the given format, but it does not open the device.

WAVE_MAPPED:The uDeviceID parameter specifies a waveform-audio device to be mapped to by the wave mapper.

返回值

MMSYSERR_NOERROR宏(0x0000):成功。

MMSYSERR_ALLOCATED宏(0x0004):Specified resource is already allocated.

MMSYSERR_BADDEVICEID宏(0x0002):Specified device identifier is out of range.

MMSYSERR_NODRIVER宏(0x0006):没有音频输入设备。

MMSYSERR_NOMEM宏(0x0007):不能分配或锁定内存。

WAVERR_BADFORMAT宏(0x0020):Attempted to open with an unsupported waveform-audio format.

WAVERR_SYNC宏(0x0023):The device is synchronous but waveOutOpen was called without using the WAVE_ALLOWSYNC flag.

错误码

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.18.2.3 waveOutProc(未完成)

函数名称

waveOutProc

头文件

#include <Mmsystem.h>

库文件

#pragma comment(lib, "Winmm.lib")

函数功能

本函数为播放设备回调函数的声明,当播放设备被打开、关闭、完成一个音频数据块的播放时,系统将自动回调本函数。

函数声明

void waveOutProc (

HWAVEOUT hwo,

UINT uMsg,

DWORD_PTR dwInstance,

DWORD_PTR dwParam1,

DWORD_PTR dwParam2

);

函数参数

hwo,[输入]:

存放播放设备句柄。

uMsg,[输入]:

存放播放设备的消息类型,可以为:

WOM_CLOSE宏(0x03BF):当播放设备句柄已经被调用waveInClose()函数关闭了,将收到本消息。

WOM_DATA宏(0x03C0):当播放设备已经完成一个音频数据块的播放,将收到本消息。

WOM_OPEN宏(0x03BE):当播放设备句柄已经被调用waveInOpen()函数打开了,将收到本消息。

dwInstance,[输入]:

存放播放设备句柄被调用waveOutOpen()函数打开时的dwCallbackInstance参数。

程序可以自由通过设置不同的本参数,来区分是哪一个播放设备。

dwParam1,[输入]:

存放第一个消息参数。

如果uMsg参数为WOM_DATA宏时,本参数为已经完成播放的音频数据块结构体的内存指针,类型为WAVEHDR *。

如果uMsg参数为WOM_CLOSE宏、WOM_OPEN宏时,本参数无意义。

dwParam2,[输入]:

存放第二个消息参数,本参数无意义。

返回值

错误码

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.18.2.4 waveOutWrite(未完成)

函数名称

waveOutWrite

头文件

#include <Mmsystem.h>

库文件

#pragma comment(lib, "Winmm.lib")

函数功能

将已经完成采集的音频数据块结构体添加到播放设备上,并开始播放,播放完毕后将自动移除音频数据块结构体。

如果要实现连续播放,必须音频数据块结构体播放完毕并移除后,才能再次添加音频数据块结构体播放设备上。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.18.2.5 waveOutClose(未完成)

函数名称

waveOutClose

头文件

#include <Mmsystem.h>

库文件

#pragma comment(lib, "Winmm.lib")

函数功能

函数主要功能说明。

函数声明

类型 函数名 (

类型 参数1,

类型 参数2,

……

);

函数参数

参数1,[输入|输出|输入&输出]:

参数说明。

参数2,[输入|输出|输入&输出]:

参数说明。

……

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.18.2.6 PlaySound

函数名称

PlaySound

头文件

#include <windows.h>

#pragma comment(lib, "winmm.lib")

函数功能

播放音频,音频可以是WAVE音频文件、内存中的WAVE音频数据、程序自身的WAVE资源,本函数不能让进程同时播放两段音频,不同的进程可以同时播放。

函数声明

BOOL PlaySound (

LPCSTR pszSound,

HMODULE hmod,

DWORD fdwSound

);

函数参数

pszSound,[输入]:

存放音频数据的内存指针,具体作用根据fdwSound参数的标记而定。

hmod,[输入]:

存放当前程序实例的句柄的值,只有当fdwSound参数的设置了SND_RESOURCE标记才有意义,其他情况,此参数必须为NULL。

fdwSound,[输入]:播放标记,可以是(用'|'选一至多个):

SND_ALIAS:设置此标记表示pszSound参数为指定的注册表或WIN.INI中的系统事件的别名,有些操作系统可能没有某些事件。如果指定的系统事件不存在,就会导致播放音频失败。pszSound参数可以是(选一至一个):

"SystemAsterisk":“SystemAsterisk系统星号声”事件。

"SystemDefault":“SystemDefault系统默认声”事件。

"SystemExclamation":“SystemExclamation系统感叹声” 事件。

"SystemExit":“SystemExit系统退出声” 事件。

"SystemHand":“SystemHand系统指针声” 事件。

"SystemQuestion":“SystemQuestion系统询问声” 事件。

"SystemStart":“SystemStart系统启动声” 事件。

"SystemWelcome":“SystemWelcome系统欢迎声” 事件。

SND_ALIAS_ID:设置此标记表示pszSound参数为指定的注册表或WIN.INI中的系统事件的别名ID,有些操作系统可能没有某些事件。如果指定的系统事件不存在,就会导致播放音频失败。pszSound参数可以是(选一至一个):

SND_ALIAS_SYSTEMASTERISK:“SystemAsterisk系统星号音”事件。

SND_ALIAS_SYSTEMDEFAULT:“SystemDefault系统默认音” 事件。

SND_ALIAS_SYSTEMEXCLAMATION:“SystemExclamation系统感叹声” 事件。

SND_ALIAS_SYSTEMEXIT:“SystemExit系统退出声” 事件。

SND_ALIAS_SYSTEMHAND:“SystemHand系统指针声” 事件。

SND_ALIAS_SYSTEMQUESTION:“SystemQuestion系统询问声” 事件。

SND_ALIAS_SYSTEMSTART:“SystemStart系统启动声” 事件。

SND_ALIAS_SYSTEMWELCOME:“SystemWelcome系统欢迎声” 事件。

SND_RESOURCE:pszSound参数为WAVE资源的标识符,hmod参数就为WAVE资源的标识符所属的程序实例的句柄,当前程序实例就可调用AfxGetResourceHandle()函数获得。

SND_FILENAME:pszSound参数为指定的WAVE文件名相对或绝对路径字符串的内存指针。

SND_MEMORY:pszSound参数为存放音频数据的内存指针,播放已经载入到内存中的音频。如果同时还设置了SND_ASYNC标记,必须保证存放音频数据的内存在播放结束前是正确的。

以上标记必选一至一个。

 

SND_ASYNC:异步方式播放音频,PlaySound()函数在开始播放后立即返回,不等待播放结束。

SND_SYNC:同步方式播放音频,在播放结束后PlaySound()函数才返回。

SND_LOOP:如果设置此标记,表示不停的重复播放音频,包括播放音频失败时的缺省音频,必须与SND_ASYNC标志同时设置;如果不设置此标记,音频在播放一次后就结束了。

SND_APPLICATION:用应用程序指定的关联来播放音频,如果没有关联的播放程序,就会导致播放音频失败。

SND_NODEFAULT:如果设置此标记,当播放音频失败时,本函数就返回失败;如果不设置此标记,当播放音频失败时,则本函数就播放缺省音频,并且返回成功。

SND_NOSTOP:如果设置此标记,且当前进程的任意线程正在调用本函数同步或异步播放音频,就表示不结束当前正在播放的音频,并立即返回失败;如果不设置此标记,且当前进程的任意线程正在调用本函数异步播放音频,就表示立即结束当前正在播放的音频,开始播放本函数指定的音频,但是如果当前进程的其他线程正在调用本函数同步播放音频,就表示等待其他线程同步播放结束,再开始播放本函数指定的音频。

SND_NOWAIT:如果驱动程序正忙则函数就不播放音频,并立即返回失败。

SND_PURGE:停止所有与调用任务有关的音频。如果pszSound参数为NULL,就停止所有的音频,否则,停止pszSound指定的音频。

返回值

非0:成功。

0:失败,无法查看错误码。

错误码

线程安全

原子操作

其他说明

此函数对多线程的调用的行为不是很明确,所以要多线程播放音频不推荐使用此函数。

 

 

2.19  视频

 

 

2.20  API HOOK捕获系统API

Detours是微软开发的一个函数库,可用于捕获系统API。

 

 

2.21  异常处理

2.21.1   简介

在C++发展的后期,有的C++编译系统根据实际工作的需要,增加了一些功能,作为工具来使用,其中主要有模板(包括函数模板和类模板)、异常处理、命名空间和运行时类型,以帮助程序设计人员更方便地进行程序的设计和调试工作。1997年ANSI C++委员会将它们纳入了ANSII C++标准,建议所有的C++编译系统都能实现这些功能。这些工具是非有用的,C++的使用者应当尽量使用这些工具,因此本书对此作简要的介绍,以便为日后的进一步学习和使用打下初步基础。在本章中主要介绍异常处理和命名空间,应当注意,期的C++是不具备这些功能的,只有近期的C++系统根据ANSIC++的要求,实现了这些功能。请读者注意使用的C++版本。

2.21.2   异常处理的目的

程序员总是希望自己所编写的程序都是正确无误的,而且运行结果也是完全正确的。但是这几乎是不可能的,智者千虑,必有一失,不怕一万,就怕万一。因此,程序编制者不仅要考虑程序没有错误的理想情况,更要考虑程序存在错误时的情况,应该能够尽快地发现错误,消除错误。

语法错误:

在编译时,编译系统能发现程序中的语法错误(如关键字拼写错误,变量名未定义,语句末尾缺分号,括号不配对等),编译系统会告知用户在第几行出错,是什么样的错误。由于是在编译阶段发现的错误,因此这类错误又称编译错误。有的初学者写的并不长的程序,在编译时会出现十几个甚至几十个语法错误,有人往往感到手足无措。但是,总的来说,这种错误是比较容易发现和纠正的,因为它们一般都是有规律的,在有了一定的编译经验以后,可以很快地发现出错的位置和原因并加以改正。

运行错误:

有的程序虽然能通过编译,也能投入运行。但是在运行过程中会出现异常,得不到正确的运行结果,甚至导致程序不正常终止,或出现死机现象。

例如

.在一系列计算过程中,出现除数为0的情况。

.内存空间不够,无法实现指定的操作。

.无法打开输入文件,因而无法读取数据。

.输入数据时数据类型有错。

 

由于程序中没有对此的防范措施,因此系统只好终止程序的运行。这类错误比较隐蔽,易被发现,往往耗费许多时间和精力,这成为程序调试中的一个难点。

在设计程序时,应当事先分析程序运行时可能出现的各种意外的情况,并且分别制订出相应的处理方法,这就是程序的异常处理的目的。

需要说明:在一般情况下,异常指的是出错(差错),但是异常处理并不完全等同于对出错的处理。只要出现与人们期望的情况不同,都可以认为是异常,并对它进行异常处理。例如,在输入学生学号时输入了负数,此时程序并不出错,也不终止运行,但是人们认为这是不应有的学号,应予以处理。因此,所谓异常处理指的是对运行时出现的差错以及其他例外情况的处理。

2.21.3   异常处理的方法

C++处理异常的机制引入

在一个小的程序中,可以用比较简单的方法处理异常,例如用if语句判别除数是否为0,如果是。则输出一个出错信息。但是在一个大的系统中,包含许多模块,每个模块义包含许多函数,函数之间又五相调用,比较复杂。如果在每一个函数中都设置处理异常的程序段,会使程序过于复杂和庞大。因此,C++采取的办法是:如果在执行一个函数过程中出现异常,可以不在本函数中立即处理,而是发出一个信息,传给它的上一级(即调用它的函数),它的上级捕捉到这个信启后进行处理。如果上一级的函数也不能处理,就再传给其上一级,由其上一级处理。如此逐级上送,如果到最高一级还无法处理,最后只好异常终止程序的执行。

这样做使异常的发现与处理不由同一函数来完成。好处是使底层的函数专门用于解决实际任务,而不必再承担处理异常的任务,以减轻底层函数的负担,而把处理异常的任务上移到某一层去处理。例如在主函数中调用十几个函数,只需在主函数中设置处理异常即可,而不必在每个函数中都设置处理异常,这样可以提高效率。

C++处理异常的机制组成

C++处理异常的机制是由3个部分组成的,即检查(try)、抛出(throw)和捕捉(catch)。把需要检查的语句放在try块中,throw用来当出现异常时发出(形象地称为抛出,throw的意思是抛出)一个异常信息,而catch则用来捕捉异常信息,如果捕捉到厂异常信息,就处理它:

例1 给出三角形的三边a,b,c,求三角形的面积。只有a+b>c,b+c>a,c+a>b时才能构成三角形。设置异常处理,对不符合三角形条件的输出警告信息,不予计算。

#include <iostream>

#include <cmath>

using namespace std;

int main()

{

    double triangle(double,double,double);

    double a,b,c;

    cin>>a>>b>>c;

    while(a>0 && b>0 && c>0)

    {

        cout<<triangle(a,b,c)<<endl;

        cin>>a>>b>>c;

    }

    return 0;

}

 

double triangle (double a, double b, double c)

{

    double area;

    double s = (a+b+c)/2;

   

    area = sqrt ( s * (s - a) * (s - b) * (s - c));

   

    return area;

}

运行情况如下

6 5 4 (输入a,b,c的值)

9.92157 (输出三角形的面积)

1 1.5 2/ (输入a,b,c的值)

0.726184 (输出三角形的面积}

1 2 1 / (输人a,b,c的值)

0 (输出三角形的面积,此结果显然不对,因为不是三角形)

1 0 6/ (输入a,b,c的值)(结束)

 

程序没有对三角形条件(任意两边之和应大于第三边)进行检查,因此,当输入a=l,b=2,c=1时,则计算出三角形的面积为0,显然是不合适的。

现在修改程序,在函数triangle中对三角形条件进行检查,如果不符合三角形条件,就抛出一个异常信息,在主函数中的try-catch块中调用triangle函数,检测有无异常信息,并相应处理。修改后的程序如下:

#include <iostream>

#include <cmath>

using namespace std;

int main()

{

    double triangle(double,double,double);

    double a,b,c;

    cin>>a>>b>>c;

    try//在try块中包含要检查的函数

    {

        while(a>0 && b>0 && c>0)

        {

            cout<<triangle(a,b,c)<<endl;

            cin>>a>>b>>c;

        }

  }

    catch(double)//用catch捕捉异常信息并作相应处理

    {

        cout<<"a="<<a<<",b="<<b<<",c="<<c<<",that is not a traingle!"<<endl;

    }

    cout<<"end"<<endl;

    return 0;

}

 

double triangle (double a, double b, double c)//计算三角形的面积的函数

{

    double sqrt;

    double s=(a+b+c)/2;

    if (a+b<=c||b+c<=a||c+a<=b) throw a;//当不符合三角形条什抛出异常信息

    return sqrt(s*(s-a)*(s-b)*(s-c));

}

程序运行结果如下:

6 5 4 (输入a,b,c的值)

9.92157 (计算出三角形的面积)

1 1.5 2 (输入a,b,c的值)

0.726184 (计算出三角形的面积)

1 2 1 (输入a,b,c的值)

a=1,b=2,c=1,that is not a triangle! (异常处理)

end

 

现在结合程序分析怎样进行异常处理。

(1)首先把可能出现异常的、需要检查的语句或程序段放在try后面的花括号中。由于riangle函数是可能出现异常的部分,所以把while循环连同triangle函数放在try块中。这些语句是正常流程的一部分,虽然被放在by块中,并不影响它们按照原来的顺序执行。

(2)程序开始运行后,按正常的顺序执行到try块,开始执行by块中花括号内的语句。如果在执行try块内的语句过程中没有发生异常,则catch子句不起作用,流程转到catch子句后面的语句继续执行。

(3)如果在执行try块内的语句(包括其所调用的函数)过程中发生异常,则throw运算符抛出一个异常信息。请看程序中的triangle函数部分,当不满足三角形条件时,throw抛出double类型的异常信息a。throw抛出异常信息后,流程立即离开本函数,转到其上一级的函数(main函数)。因此不会执行triangle函数中if语句之后的return语句。

throw抛出什么样的数据由程序设计者自定,可以是任何类型的数据(包括自定义类型的据,如类对象)。

(4)这个异常信息提供给try-catch结构,系统会寻找与之匹配的catch子句。现在a是double型,而catch子句的括号内指定的类型也是double型,二者匹配,即catch捕获了该异常信息,这时就执行catch子句中的语句,本程序输出a=1.b=2,c=1,that is not a triangle!

(5)在进行异常处理后,程序并不会自动终止,继续执行catch子句后面的语句。本程序输出“end”。注意并不是从出现异常点继续执行while循环。如果在try块的花括号内有10个语句,在执行第3个语句时出现异常,则在处理完该异常后,其余7个语句不再执行,而转到catch子句后面的语句去继续执行。

由于catch子句是用来处理异常信息的,往往被称为catch异常处理块或catch异常处理器。

异常处理的语法:

throw语句一般是由throw运算符和一个数据组成的,其形式为:

throw 表达式;

try-catch的结构为:

try

{

    被检查的语句;

}

catch(异常信息类型[变量名])

{

    进行异常处理的语句;

}

 

说明:

(1)被检测的函数必须放在try块中,否则不起作用。

(2)try块和catch块作为—个整体出现,catch块是try-catch结构中的一部分,必须紧跟在try块之后,不能单独使用,在二者之间也不能插入其他语句。

(3)try和catch块中必须有用花括号括起来的复合语句,即使花括号内只有一个语句,也不能省略花括号。

(4)一个try-catch结构中只能有一个try块,但却可以有多个catch块,以便与不同的异常信息匹配。

(5)catch后面的圆括号中,一般只写异常信息的类型名,如:catch(double)。

catch只检查所捕获异常信息的类型:异常信息可以是C++系统预定义的标准类型,也可以是用户自定义的类型(如结构体或类)。如果由throw抛出的信息属于该类型或其子类型,则catch与throw二者匹配,catch捕获该异常信息。catch还可以有另外一种写法,即除了指定类型名外,还指定变量名,如:catch(double d)。

此时如果throw抛出的异常信息是double型的变量a,则catch在捕获异常信息a的同时,还使d获得a的值,或者说d得到a的一个拷贝。什么时候需要这样做呢?有时希望在捕获异常信息时,还能利用throw抛出的值。

(6)如果在catch子句中没有指定异常信息的类型,而用了删节号“…”,则表示它可以捕捉任何类型的异常信息,如:catch(…) {cout<<"OK"<<endl;},它能捕捉所有类型的异常信息,并输出“OK”。

(7)try-catch结构可以与throw出现在同一个函数中,也可以不在同一函数中。当throw抛出异常信息后,首先在本函数中寻找与之匹配的catch,如果在本函数中无try-catch结构或找不到与之匹配的catch,就转到其上一层去处理,如果其上一层也无try-catch结构或找不到与之匹配的catch,则再转到更上一层的try-catch结构去处理,也就是说转到离开出现异常最近的try-catch结构去处理。

(8)在某些情况下,在throw语句中可以不包括表达式。

(9)如果throw抛出的异常信息找不到与之匹配的catch块,那么系统就会调用一个系统函数terminate,使程序终止运行。

例2 在函数嵌套的情况下检测异常处理。

这是一个简单的例子,用来说明在try块中有函数嵌套调用的情况下抛出异常和捕捉异常的情况。

#include <iostream>

using namespace std;

 

int main ()
{

    void f1 ();

    try

    {

        f1 ( ); //调用fl ()

    }

    catch (double)

    {

        cout <<"OK0!"<<endl;

    }

    cout <<"end0"<<endl;

    return 0;

}

 

void f1 ()

{

    void f2 ();

    try

    {

        f2 (); //调用f2 ()

    }

    catch (char)

    {

        cout <<"OK1!";

    }

    cout <<"end1"<<endl;

}

 

void f2 ()

{

    void f3 ();

    try

    {

        f3 (); //调用f3 ()

    }

    catch (int)

    {

        cout <<"Ok2!"<<endl;

    }

    cout <<"end2"<<endl;

}

void f3 ()

{

    double a = 0;

    try

    {

        throw a; //抛出double类型异常信息

    }

    catch (float)

    {

        cout<<"OK3!"<<endl;

    }

    cout<<"end3"<<endl;

}

 

分析运行情况:

(1)如果将f3函数中的catch子句改为catch(double),而程序中其他部分不变,则f3函数中的throw抛出的异常信息立即被门函数中的catch子句捕获(因为抛出的是double型异常,catch要捕捉的也是double型异常,二者匹配)。于是执行catch子句中的复合语句,输出"OK3",再执行catch子句后面的语句,输出"end3"。f3函数执行结束后,流程返回f2函数中调用f3函数处继续往下执行。
程序运行结果如下:
   OK31 (在f3函数中捕获异常)
   end3 (执行f3函数中最后一个语句时的输出)
   end2 (执行f2函数中最后一个语句时的输出)
   endl (执行u函数中最后一个浯句时的输出)
   endO (执行主函数中最后—个语句时的输出)
   (2)如果在此基础上再将f3函数中的catch块改为


catch(double)



{ cout<<"OK3!"<<endl;throw;}
   f3函数中的catch子句捕获throw抛出的异常信息a,输出"OK3!"表示收到此异常信息,但它立即用"throw;”将a再抛出。由于a是double型,与f2和门函数中的catch都不匹配,因此最后被main函数中的catch子句捕获。程序运行结果如下:

OK3!(在f3函数中捕获异常)

OK0! (在主函数中捕获异常)

end0 (执行主函数中最后一个语句时的输出)

三、 在函数声明中进行异常情况指定
   为了便于阅渎程序,使用户在看程序时能够知道所用的函数是否会抛出异常信息以及异常信息可能的类型,C++允许在声明函数时列出可能抛出的异常类型,如可以将例1中第二个程序的第3行改写为:

double triangle(double,double,double)throw(double);
表示triangle函数只能抛出double类型的异常信息。如果写成

double triangle(double,double,double)throw(int,double,float,char);
则表示triangle函数可以抛出int,double,float或char类型的异常信息。异常指定是函数声明的一部分,必须同时出现在函数声明和函数定义的首行中,否则在进行函数的另一次声明时,编泽系统会报告“类型不匹配”。
   如果在声明函数时未列出可能抛出的异常类型,则该函数可以抛出任何类型的异常信息。如例1中第2个程序中所表示的那样。
如果想声明一个不能抛出异常的函数,可以写成以下形式:
double triangle(double,double,double) throw(); //throw无参数
   这时即使在函数执行过程中出现了throw语句,实际上也并不执行throw语句,并不抛出任何异常信息,程序将非正常终止。
四、 在异常处理中处理析构函数
   如果在try块(或try块中调用的函数)中定义了类对象,在建立该对象时要调用构造函数。在执行try块(包括在try块中调用其他函数)的过程中如果发生了异常,此时流程立即离开try块(如果是在try块调用的函数中发生异常,则流程首先离开该函数,回到调用它的try块处,然后流程再从try块中跳出转到catch处理块)。这样流程就有可能离开该对象的作用域而转到其他函数,因而应当事先做好结束对象前的请理工作,C++的异常处理机制会在throw抛出异常信息被catch捕获时,对有关的局部对象进行析构(调用类对象的析构函数),析构对象的顺序与构造的顺序相反,然后执行与异常信息匹配的catch块中的语句。
例 在异常处理中处理析构函数。

这是一个为说明在异常处理中调用析构函数的示例,为了请晰地表示流程,程序中加入了一些cout语句,输出有关的信息,以便读者对照结果分析程序。

#include <iostream>
#include <string>
using namespace std;
class Student
   { public:
       Student(int n,string nam) //定义构造函数


{ cout<<"construtor-"<<n<<endl;



num=n;name=nam;}


~Student(){cout<<"destructor-"<<num<<endl;} //定义析构函数

void get_data(); //成员函数声明


private:


int num;
      string name; };
void Student::get_data() 
//定义成员函数

{ if(num==0) throw num; 
//如num=O,抛出int型变量num


else cout<<num<<" "<<name<<endl; //若num不等O,输出num,name


cout<<"in get_data()"<<endl; //输出信息,表示目前在fet_data函数中 

}
void fun()
//过程函数(注意可见性)
  { Student stud1(1101,"tan");//建立对象studl

stud1.get_data(); 

//调用studl的getdata函数


Student stud2(0,"Li");
//建立对象stud2 
      stud2.get_data();  }
//调用smd2的get data函数

int main()
{ cout<<"main begin"<<endl; //表示主函数开始了

cout<<"call fun()"<<endl; //表示调用fun函数

try
     {fun();} //调用fun函数


catch(int n)


{ cout<<"num="<<n<<",error!"<<endl;} //表示num=0出错



cout<<"main end"<<endl; //表示主函数结束



return 0; }

分析程序执行过程,程序运行结果如下:

main begiin
call fun()
constructor-110l
//对立Student类对象stud1,num=1101
110l tan
     //对象stud1调用Student类的成员函数get_data,num不等O
in get_data()

//执行get_data
constructor-0

//建立Student类对象stud2,num=0,抛出num.
destructor-O

//调用Student类对象stud1的析构函数
destructor-1101
//调用Student类对象stud2的析构函数
num=O,error!

//表示num=0出错。
main end


//表示主函数结束

2.21.4   VC编译器异常选项

#include <stdio.h>

void main ()

{

    char *a;

    try

    {

        a = 0;

        (*a) = 0;

    }

    catch(...)

    {

        printf("oops,exception!!\n");

    }

}

 

这段代码的运行结果是什么?

你一定会说:"屏幕上打出oops,exception!!\n"。

没错,理论上的确是这样。

我们来验证一下,用vc6产生一个空的win32 console工程,

加入上面的cpp文件,

debug方式编译后,得到如期的结果,

但是!

release方式编译后,仍然出现了"访问冲突"!

 

这如何解释?

本怪兽经调查发现,

VC里缺身编译选项里关于异常的选项是/GX,

文档里说,这等价与/EHs--同步异常捕捉。

何解?

答:只有编译器认为有可能出异常的情况下,

即有throw出现的情况下,

编译器才会生成异常捕捉代码。

 

据说是VC6的一项新优化功能,

真是自作聪明!谁会希望这样的"异常捕捉"?

 

解决方法,去掉/GX,加上/EHa--异步异常捕捉。

这样可以保证异常捕捉代码不被"高明"的编译器优化掉。

 

那为何开头的例子里,debug版本运行正常呢?

答:debug版本不做优化。故正常也。

 

这是VC6 IDE里非常莫名其妙的地方,

用try catch的人请一定小心。

---------------------------------------------------------------------------------------------------

在【属性】-》【C/C++】-》【代码生成】-》【启用C++异常】有如下4个选项,点击组合框,显示:

是(/EHsc)

是,但有 SEH 异常(/EHa)

<从父级或项目默认设置继承>

1、如果不选择【是,但有 SEH 异常(/EHa)】选项,try { } catch(...) { } 不起作用。新建项目缺省值是【是(/EHsc)】。就是说在缺省情况下微软不支持标准C++。

2、微软自己又弄出:__try { } __except(EXCEPTION_EXECUTE_HANDLER) { }。【启用C++异常】选项对此不起作用,选什么都起作用。建议不要使用。还是使用标准的吧。

3、微软还弄出:TRY{} CATCH_ALL(e) {} END_CATCH_ALL不知为什么还弄。可能微软的开发人员那天还得弄。

总结:掌握第1种方法就足够了,其实也不应该出现其他方法。如果你的是在从API封装类,建议还是用第2种方法,可能你的类要应用到很多项目,那个项目是否选择了【是,但有 SEH 异常(/EHa)】就很难说了,可能那个程序员根本就没有注意到【是,但有 SEH 异常(/EHa)】选项,使用第1种方法会使你的异常失效。但我又觉得__try { }实在不是个东西,看着别扭。

2.21.5   捕获所有未捕获的异常

从名字上就可以看出SetUnhandledExceptionFilter()函数的作用就是设置未捕获异常的捕获函数,程序崩溃就是因为有些异常我们没有捕获,而当这些异常我们没捕获时,系统就会调用SetUnhandledExceptionFilter设置的函数,在此函数中可以进行一些操作,比如弹出对话框、打印语句等。如果没有设置未捕获异常的捕获函数,那么系统就会调用默认的未捕获异常的捕获函数,比如弹出调试对话框、显示内存读写错误对话框、等等。

 

未捕获异常的捕获函数的返回值:

EXCEPTION_EXECUTE_HANDLER equ 1 表示我已经处理了异常, 进程可以结束了

EXCEPTION_CONTINUE_SEARCH equ 0 表示我不处理,其他人来吧,于是windows调用默认的未捕获异常的捕获函数,然后显示一个错误框,并结束

EXCEPTION_CONTINUE_EXECUTION equ -1 表示错误已经被修复,请从异常发生处继续执行

 

具体使用方法如下:

//未捕获异常的捕获函数

LONG WINAPI MyUnhandledExceptionFilter (struct _EXCEPTION_POINTERS * pExp)

{

    cout <<"UnhandledException!!!"<<endl;

 

    return EXCEPTION_EXECUTE_HANDLER;//返回异常已经处理,并可以结束进程的标记

}

 

int main ()

{

    cout <<"begin!"<<endl;

 

    SetUnhandledExceptionFilter (MyUnhandledExceptionFilter);

 

    int i = 0;

    i = i / i;

 

    cout <<"end!"<<endl;

 

    getch ();

 

    return 0;

}

 

 

2.21.6   SetErrorMode(未完成)

函数名称

SetErrorMode

头文件

#include <Windows.h>

库文件

#pragma comment(lib, "Kernel32.lib")

函数功能

设置错误处理方式,选择是否让操作系统处理指定类型的严重错误,还是让调用进程来处理它们。

函数声明

UINT WINAPI SetErrorMode (

UINT uMode

);

函数参数

uMode,[输入]:

存放要让操作系统处理哪些类型的严重错误,可以为(用'|'选零至多个):

0

使用系统默认的,既让操作系统处理所有错误。

SEM_FAILCRITICALERRORS(0x0001):

如果设置本标记,表示不让系统处理关键错误,让调用进程来处理。

如果不设置本标记,表示要让系统处理关键错误,不让调用进程来处理。系统会自动弹出一个对话框来让用户选择如何处理。

SEM_NOALIGNMENTFAULTEXCEPT(0x0004):

如果设置本标记,表示The system automatically fixes memory alignment faults and makes them invisible to the application. It does this for the calling process and any descendant processes. This feature is only supported by certain processor architectures. For more information, see the Remarks section.After this value is set for a process, subsequent attempts to clear the value are ignored.

不建议设置本标记。

SEM_NOGPFAULTERRORBOX(0x0002):

如果设置本标记,表示不让系统显示Windows错误报告对话框。

如果不设置本标记,表示要让系统显示Windows错误报告对话框。系统会自动弹出一个错误报告对话框来让用户选择如何处理,对话框截图:

 

SEM_NOOPENFILEERRORBOX(0x8000)

如果设置本标记,表示不让系统处理无法找到文件时的错误,让调用进程来处理。

如果不设置本标记,表示要让系统处理无法找到文件时的错误。系统会自动弹出一个对话框来让用户选择如何处理。例如试图从一个没有软盘的软驱中读数据。

返回值

返回值1:返回值说明。

返回值2:返回值说明。

……

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

是 或 否 或 未知,表示此函数多线程调用是否会产生影响

原子操作

是 或 否 或 未知,表示此函数是否是单一操作,不是多个步骤的组合

其他说明

……

……

 

 

2.22  错误码

2.22.1   GetLastError

函数名称

GetLastError

头文件

#include <windows.h>

函数功能

获取本线程最近一次调用系统函数的错误码,多线程互不影响。因为使用的线程局部变量来存放错误码。

函数声明

DWORD GetLastError (

    void

  );

函数参数

返回值

本线程最近一次的错误码。

错误码

线程安全

原子操作

其他说明

可以使用FormatMessage()函数获取错误码对应的信息字符串。

 

 

2.22.2   FormatMessage(未完成)

函数名称

FormatMessage

头文件

#include <Windows.h>

函数功能

根据GetLastError()函数返回的错误码,获取此错误码对应的错误信息字符串存放在指定内存。

函数声明

DWORD FormatMessage (

DWORD dwFlags,

LPCVOID lpSource,

DWORD dwMessageId,

DWORD dwLanguageId,

LPSTR lpBuffer,

DWORD nSize,

va_list * Arguments

);

函数参数

dwFlags,[输入]:

可以是(用'|'选一至多个):

FORMAT_MESSAGE_FROM_SYSTEM:在系统id映射表中查找错误信息字符串。

FORMAT_MESSAGE_FROM_HMODULE:在其他资源模块中查找错误信息字符串。此标记不能和FORMAT_MESSAGE_FROM_STRING标记同时使用。

FORMAT_MESSAGE_FROM_STRING:lpSource参数是一个指向以NULL结尾的字符串,字符串包含一个消息定义,这个消息定义可以包含插入序列。此标志最好不要和FORMAT_MESSAGE_FROM_HMODULE或者FORMAT_MESSAGE_FROM_SYSTEM使用。此标记不能和FORMAT_MESSAGE_FROM_HMODULE标记同时使用。

FORMAT_MESSAGE_ALLOCATE_BUFFER:要此函数会自动分配内存来存放错误信息字符串,而不是自己指定。

FORMAT_MESSAGE_IGNORE_INSERTS:在消息定义中的插入序列将会被忽略,也就是忽略Arguments参数。

FORMAT_MESSAGE_ARGUMENT_ARRAY:Arguments参数不是一个va_list结构,它表示一个数组指针。这个标识符不能在64位整数值时使用,你如果要使用64位整数值,那么你必须使用va_list结构体。

lpSource,[输入]:

如果dwFlags参数指定了FORMAT_MESSAGE_FROM_HMODULE标记,本参数表示模块句柄。

如果dwFlags参数指定了FORMAT_MESSAGE_FROM_STRING标记,本参数表示id字符串。

其他情况本参数无意义,必须为NULL。

dwMessageId,[输入]:

存放GetLastError()函数返回的错误码。

如果dwFlags参数指定FORMAT_MESSAGE_FROM_STRING标记,则本参数无意义,必须为NULL。

dwLanguageId,[输入]:

错误信息字符串所用的语言,为0表示系统自动选择。

lpBuffer,[输入]:

存放错误信息字符串的内存指针,但是如果dwFlags指定了FORMAT_MESSAGE_ALLOCATE_BUFFER,系统会调用LocalAlloc()函数自动分配内存,本参数就为存放该内存指针的指针变量的内存指针,用户需要记住调用LocalFree()函数释放该内存。

nSize,[输入]:

存放错误信息字符串的内存长度,但是如果dwFlags指定了FORMAT_MESSAGE_ALLOCATE_BUFFER,本参数就为系统自动分配的内存的最小长度。

Arguments,[输入]:

未知,必须为NULL。

返回值

非0:存放在内存的错误信息字符串的长度。

0:失败,调用GetLastError()函数查看错误码。

错误码

EXXXX:错误码说明。

EXXXX:错误码说明。

……

线程安全

原子操作

其他说明

lpSource参数如果是模块句柄,可以调用LoadLibraryEx ("DLL文件名", NULL, LOAD_LIBRARY_AS_DATAFILE)函数获取。

lmerr.h、netmsg.dll模块包含NERR_BASE(2100)至MAX_NERR(2999)的错误码对应的信息字符串。

wininet.h、wininet.dll模块包含INTERNET_ERROR_BASE(12000)至INTERNET_ERROR_LAST(12175)的错误码对应的信息字符串。

pdhmsg.h、pdh.dll模块包含PDH_CSTATUS_VALID_DATA(0)至PDH_CSTATUS_NEW_DATA(1)、PDH_CSTATUS_NO_MACHINE(2147485648)至PDH_QUERY_PERF_DATA_TIMEOUT(3221228542)的错误码对应的信息字符串。

系统id映射表包含WSA错误码10000至11999、IPSec错误码13000至13999、Side By Side错误码14000至14999、WinEvt错误码15000至15079、Wecsvc错误码15080至15099、MUI错误码15100至15199、Monitor Configuration API错误码15200至15249、Syspart错误码15250至15299、Vortex错误码15300至15320、及其他的错误码对应的信息字符串。

 

 

3   类库

3.1 类模板

 

 

3.2 list

3.2.1 list类简介

list类是一种可在常数时间内在任何位置执行插入元素和删除元素操作的顺序容器。list类是双向链表,其迭代器是双向的。list类变量可以在任意位置高效执行插入、提取、和移动元素的操作,但它不能通过在list类变量中的位置直接操作元素。

 

头文件:#include <list>

 

assign() 给list赋值

front() 返回第一个元素

back() 返回最后一个元素

begin() 返回指向第一个元素的迭代器

end() 返回最后一个元素的下一个元素的迭代器,其实就是NULL,用于表示链表结束。

clear() 删除所有元素

empty() 判断本类变量有没有元素,如果有,则返回true,如果没有,则返回false。

erase() 删除一个元素

get_allocator() 返回list的配置器

insert() 插入一个元素

max_size() 返回list能容纳的最大元素数量

merge() 合并两个list

pop_back() 删除最后一个元素

pop_front() 删除第一个元素

push_back() 在list的末尾添加一个元素

push_front() 在list的头部添加一个元素

rbegin() 返回指向第一个元素的逆向迭代器

remove() 从list删除元素

remove_if() 按指定条件删除元素

rend() 指向list末尾的逆向迭代器

resize() 改变list的大小

reverse() 把list的元素倒转

size() 返回list中的元素个数

sort() 给list排序

splice() 合并两个list

swap() 交换两个list

unique() 删除list中重复的元素

3.3 map

关联容器与顺序容器

关联容器通过键(key)存储和读取元素,而顺序容器则通过元素在容器中的位置顺序存储和访问元素。

关联容器(Associative containers)支持通过键来高效地查找和读取元素。两个基本的关联容器类型是 map 和 set。 其中map 的元素以键-值(key-value)对的形式组织:键用作元素在 map 中的索引,而值则表示所存储和读取的数据。set 仅包含一个键,并有效地支持关于某个键是否存在的查询。

关联容器类型

 

一般来说,如果希望有效地存储不同值的集合,那么使用 set 容器比较合适,而 map 容器则更适用于需要存储(乃至修改)每个键所关联的值的情况。在做某种文本处理时,可使用 set 保存要忽略的单词。而字典则是 map 的一种很好的应用:单词本身是键,而它的解释说明则是值。 set 和 map 类型的对象所包含的元素都具有不同的键,不允许为同一个键添加第二个元素。如果一个键必须对应多个实例,则需使用 multimap 或 multi set,这两种类型允许多个元素拥有相同的键。

C++ Primer Plus 第6版 中文版 清晰有书签PDF+源代码 http://www.linuxidc.com/Linux/2014-05/101227.htm

读C++ Primer 之构造函数陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm

读C++ Primer 之智能指针 http://www.linuxidc.com/Linux/2011-08/40177.htm

读C++ Primer 之句柄类 http://www.linuxidc.com/Linux/2011-08/40175.htm

将C语言梳理一下,分布在以下10个章节中:

  1. Linux-C成长之路(一):Linux下C编程概要 http://www.linuxidc.com/Linux/2014-05/101242.htm
  2. Linux-C成长之路(二):基本数据类型 http://www.linuxidc.com/Linux/2014-05/101242p2.htm
  3. Linux-C成长之路(三):基本IO函数操作 http://www.linuxidc.com/Linux/2014-05/101242p3.htm
  4. Linux-C成长之路(四):运算符 http://www.linuxidc.com/Linux/2014-05/101242p4.htm
  5. Linux-C成长之路(五):控制流 http://www.linuxidc.com/Linux/2014-05/101242p5.htm
  6. Linux-C成长之路(六):函数要义 http://www.linuxidc.com/Linux/2014-05/101242p6.htm
  7. Linux-C成长之路(七):数组与指针 http://www.linuxidc.com/Linux/2014-05/101242p7.htm
  8. Linux-C成长之路(八):存储类,动态内存 http://www.linuxidc.com/Linux/2014-05/101242p8.htm
  9. Linux-C成长之路(九):复合数据类型 http://www.linuxidc.com/Linux/2014-05/101242p9.htm
  10. Linux-C成长之路(十):其他高级议题

注意:关联容器根据键排列元素!所以,在迭代遍历访问容器时,是按照键的顺序访问元素,而与元素在容器中的存放位置无关!

3.3.1    基础pair类型

在utility头文件定义。

 

3.3.2    map类型

 

3.3.2.1   map类型的定义

map 是键-值对的集合。map 类型通常可理解为关联数组(associative array):可使用键作为下标来获取一个值,正如内置数组类型一样。而关联的本质在于元素的值与某个特定的键相关联,而并非通过元素在数组中的位置来获取。

 

map对象的构造函数即定义方法:

 

 

在实际应用中,键类型必须定义 < 操作符,比如list<> 容器的类型则不能作为键。
在使用关联容器时,它的键不但有一个类型,而且还有一个相关的比较函数。 所用的比较函数必须在键类型上定义严格弱排序(strict weak ordering)。所谓的严格弱排序可理解为键类型数据上的“小于”关系。当用于一个键与自身的比较时,肯定会导致 false 结果。如果它们相互之间都不存在“小于”关系,则容器将之视为相同的键。用做 map 对象的键时,可使用任意一个键值来访问相应的元素。这与下面的添加元素时行为有一定的对应

3.3.2.2   map定义的类型

 

 

其中:其 value_type 是存储元素的键以及值的 pair 类型,而且键为 const

// count number of times each word occurs in the input
map<string, int> word_count; // empty map from string to int 
// get an iterator to an element in word_count
map<string, int>::iterator map_it = word_count.begin(); // *map_it is a reference to a pair<const string, int> objectcout << map_it->first; // prints the key for this element
cout << " " << map_it->second; // prints the value of the element
 
map_it->first = "new key";    <span style="color: rgb(255, 0, 0);"><strong>// error: key is const</strong></span>
 
++map_it->second; // ok: we can change value through an iterator

对迭代器进行解引用将获得一个pair对象,其first成员具有const map<K, V>::key_type 类型即存放键,而 second成员则为map<K,V>::mapped_type 类型,即存放值。

3.3.2.3   map元素添加

3.3.2.3.1 一、下标添加

当编写以下代码时:

map <string, int> word_count; // empty map
// insert default initialzed element with key Anna; then assign 1 to its value
word_count["Anna"] = 1;

将发生:

1.在 word_count 中查找键为 Anna 的元素,没有找到。
2.将一个新的键-值对插入到 word_count 中。它的键是 const string 类型的对象,保存 Anna。而它的值则采用值初始化,这就意味着在本例中值为 0。
3.将这个新的键-值对插入到 word_count 中。
4.读取新插入的元素,并将它的值赋为 1。
使用下标访问 map 与使用下标访问数组或 vector 的行为截然不同:用下标访问不存在的元素将导致在 map 容器中添加一个新元素,它的键即为该下标值。

PS:下标操作符返回值的使用
通常来说,下标操作符返回左值。它返回的左值是特定键所关联的值。可如下读或写元素:

// count number of times each word occurs in the input
map<string, int> word_count; // empty map from string to int    
string word;
while (cin >> word)
  ++word_count[word];

3.3.2.3.2 二、insert添加

map上的insert操作


1.添加元素

// if Anna not already in word_count,inserts new element with value 1
word_count.insert(map<string, int>::value_type("Anna", 1));

上面语句的实参可以简化如下两种方法:

(1) word_count.insert(make_pair("Anna", 1));

(2)使用 typedef

    typedef map<string,int>::value_type valType;
    word_count.insert(valType("Anna", 1));

2、insert的返回值

There can be only one element with a given key in a map. If we attempt to insert an element with a key that is already in the map, then insert does nothing. The versions of insert that take an iterator or iterator pair do not indicate whether or how many elements were inserted.

但是,带有一个键-值 pair 形参的 insert 版本将返回一个值:包含一个迭代器和一个 bool 值的 pair 对象,其中迭代器指向 map 中具有相应键的元素,而 bool 值则表示是否插入了该元素。如果该键已在容器中,则其关联的值保持不变,返回的 bool 值为 false。在这两种情况下,迭代器都将指向具有给定键的元素。

3.3.2.4   查找以及读取map中的元素

3.3.2.4.1 一、下标读取

  map<string,int> word_count;
  int occurs = word_count["foobar"];

但是:使用下标存在一个很危险的副作用:如果该键不在 map 容器中,那么下标操作会插入一个具有该键的新元素。

3.3.2.5   二、不修改map对象的查询操作

(1) m.count(k);返回 m 中 k 的出现次数

(2) m.find(k); 如果 m 容器中存在按 k 索引的元素,则返回指向该元素的迭代器。如果不存在,则返回超出末端迭代器

-----使用count检查对象总某键是否存在

对于 map 对象,count 成员的返回值只能是 0 或 1。map 容器只允许一个键对应一个实例,所以 count 可有效地表明一个键是否存在。如果返回值非 0,则可以使用下标操作符来获取该键所关联的值,而不必担心这样做会在 map 中插入新元素:
int occurs = 0;
if (word_count.count("foobar"))        
  occurs = word_count["foobar"];

当然,在执行 count 后再使用下标操作符,实际上是对元素作了两次查找。如果希望当元素存在时就使用它,则应该用 find 操作。

-----读取元素而不插入该元素

find 操作返回指向元素的迭代器,如果元素不存在,则返回 end 迭代器:

如果希望当具有指定键的元素存在时,就获取该元素的引用,否则就不在容器中创建新元素,那么应该使用 find。

3.3.3 删除map元素

 

3.3.4 遍历map对象

map同样提供begin和end运算。以生成遍历整个元素的迭代器

ok,that`s all .

3.3.5    实际程序演练

一、单词统计

代码一:

// 建立一个map对象,保存所读入的单词及其出现的次数(以单词为键,对应的值为单词出现的次数)
// 利用下标添加元素

#include <iostream>
#include <map>
#include <string>
using namespace std;
// 2013.11.18 Written by C_SuooL_Hu
int main()
{
 // freopen("in.txt","r",stdin);
 // freopen("out.txt","w",stdout);
 map<string, int> wordCount;
 typedef map<string, int> ::iterator valType;
 string word;
 // 读入单词并统计次数
 cout << "Enter some words (Ctrl + Z to end):" << endl;
 while (cin >> word)
 { 
 // 如果读入的word存在在容器中,则使键值为word的值++,否则添加以此元素为索引的键,然后键值初始化为0,后++,即为1.
 ++wordCount[word]; 
 }
 // 输出结果,用迭代器
 cout << "word\t\t" << "times" << endl;
 for (valType iter = wordCount.begin(); iter != wordCount.end(); ++iter)
 {
  cout << (*iter).first << "\t\t" << (*iter).second << endl;
 }
 return 0;
}

代码二:

#include <iostream>
#include <map>
#include <string>
using namespace std;
</span><pre style="line-height: 24.5px;" class="cpp" name="code">// 2013.11.18 Written by C_SuooL_Hu</pre>// mapint main() { freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); // count number of times each word occurs in the input map<string, int> word_count;
 // empty map from string to int typedef map<string, int> ::iterator valType; string word; while (cin >> word) { // inserts element with key equal to word and value 1; // if word already in word_count, insert does nothing pair<map<string, int>::iterator, bool>
 ret =word_count.insert(make_pair(word, 1)); if (!ret.second) // word already in word_count ++ret.first->second; // increment counter }// outputcout << "word\t\t" << "times" << endl;for (valType iter = word_count.begin(); iter != word_count.end(); ++iter){cout
 << (*iter).first << "\t\t" << (*iter).second << endl;}return 0;}

运行结果:

 

有图可知,用迭代器输出的时候,按照字典序输出。

3.3.6 二、单词转换器(转换译码)

代码有点丑,输入输出IO库还很需要加强。。。对文件的操作基本是文盲。。

#include <map>
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
// 2013.11.18 Written by C_SuooL_Hu
using namespace std;

ifstream& open_file(ifstream&, const string&);

int main()

{
 freopen("out.txt", "w", stdout);
 // map to hold the word transformation pairs: 
 // key is the word to look for in the input; value is word to use in the output
 map<string, string> trans_map;
    string key, value;
 
 // ´´½¨Á÷
 ifstream myfile ("trans_map.txt");
 ifstream myfilein ("in.txt");
 ofstream outfile("out.txt");
 // ÅжÏÎļþÊÇ·ñ´ò¿ª
 if(!myfile)
 {
  cout << "Unable to open myfile";
        exit(1); // terminate with error
  
 }
 if(!outfile)
 {
  cout << "Unable to open outfile";
        exit(1); // terminate with error
  
 }
 
    // read the transformation map and build the map 
    while (myfile >> key >> value) 
 {
  trans_map.insert(make_pair(key, value));
 }
 
 // this block just produces the vector so that we can print it
 // for the book
 cout << "Here is our transform string input:\n\n";
 // read some text to transform
 string word;
 
    // ok, now we're ready to do the transformations
    // open the input file and check that the open succeeded
 string WORD;
 bool firstword = true;  // controls whether a space is printed 
 while (myfilein >> WORD) 
 {
  // ok: the actual mapwork, this part is the heart of the program
  map<string, string>::const_iterator map_it =
   trans_map.find(WORD);
  
  // if this word is in the transformation map
  if (map_it != trans_map.end()) 
  {
   // replace it by the transformation value in the map
   WORD = map_it->second;  
  }
  if (firstword)
   firstword = false;
  else
   cout << " ";  // print space between words
  cout << WORD;
 }
 cout << endl;        // done with this line of input
    return 0;
}
测试结果:

 

 

 

4   结构体库

4.1 结构体模板(未完成)

结构体名称

xxx

头文件

#include <xxx.h>

#include <xxx.h>

结构体称呼

结构体的中文称呼。

结构体说明

结构体主要用途说明。

相关函数

Func1()、Func2()、Func3()…

结构体声明

struct xxx

{

类型  成员变量1;

类型  成员变量2;

……

};

成员变量

成员变量1

成员变量说明。

成员变量2

成员变量说明。

……

其他说明

……

……

 

 

4.2 套接字

4.2.1 sockaddr

头文件    :#include <linux/socket.h>

结构体名称:sockaddr

结构体说明:结构体主要使用说明。

结构体声明:struct sockaddr

{

  sa_family_t     sa_family;      /* address family, AF_xxx       */

  char            sa_data[14];    /* 14 bytes of protocol address */

};

成员变量  :sa_family:IP地址的地址族,用AF_xxx定义的

sa_data:协议的地址数据,占14个字节的

注意事项  :

……

 

 

4.2.2 sockaddr_in

头文件    :#include <netinet/in.h>

结构体名称:sockaddr_in

结构体说明:一般用于对IPv4的地址信息的说明。

结构体声明:struct sockaddr_in

{

  __SOCKADDR_COMMON (sin_);

  in_port_t sin_port;                 /* Port number.  */

  struct in_addr sin_addr;            /* Internet address.  */

 

  /* Pad to size of `struct sockaddr'.  */

  unsigned char sin_zero[sizeof (struct sockaddr) -

                         __SOCKADDR_COMMON_SIZE -

                         sizeof (in_port_t) -

                         sizeof (struct in_addr)];

};

成员变量  :sin_port:存放端口号。

sin_addr:存放IP地址。

sin_zero:填充数据,为了占满14个字节,无实际意义。

注意事项  :

……

……

 

 

4.2.3 sockaddr_in6

头文件    :#include <netinet/in.h>

结构体名称:sockaddr_in6

结构体说明:一般用于对IPv6的地址信息的说明。

结构体声明:struct sockaddr_in6

{

  __SOCKADDR_COMMON (sin6_);

  in_port_t sin6_port;        /* Transport layer port # */

  uint32_t sin6_flowinfo;     /* IPv6 flow information */

  struct in6_addr sin6_addr;  /* IPv6 address */

  uint32_t sin6_scope_id;     /* IPv6 scope-id */

};

成员变量  :sin6_port:成员变量说明。

sin6_flowinfo:成员变量说明。

sin6_addr:

sin6_scope_id:

注意事项  :

……

……

 

 

4.3 软硬件设备

4.3.1 通用

4.3.1.1   SYSTEM_PROCESS_INFORMATION(未完成)

结构体名称

SYSTEM_PROCESS_INFORMATION

头文件

#include <Winternl.h>

结构体说明

存放系统中各个进程的相关信息。

相关函数

NtQuerySystemInformation()、Func2()、Func3()…

结构体声明

struct SYSTEM_PROCESS_INFORMATION

{

ULONG         NextEntryOffset;

BYTE          Reserved1[52];

PVOID         Reserved2[3];

HANDLE        UniqueProcessId;

PVOID         Reserved3;

ULONG         HandleCount;

BYTE          Reserved4[4];

PVOID         Reserved5[11];

SIZE_T        PeakPagefileUsage;

SIZE_T        PrivatePageCount;

LARGE_INTEGER Reserved6[6];

}

成员变量

NextEntryOffset

存放下一个进程信息结构体的起始位置指针相对本结构体的起始位置指针的偏移长度,单位字节。

如果本参数为0,表示本结构体就为最后一个,没有下一个了。

Reserved1

保留参数,其实并不是没有用到,只是微软隐藏了而已。

Reserved2

保留参数,其实并不是没有用到,只是微软隐藏了而已。

UniqueProcessId

存放进程的全局唯一ID。

Reserved3

保留参数,其实并不是没有用到,只是微软隐藏了而已。

HandleCount

存放进程的句柄数。

Reserved4

保留参数,其实并不是没有用到,只是微软隐藏了而已。

Reserved5

保留参数,其实并不是没有用到,只是微软隐藏了而已。

PeakPagefileUsage

存放进程的虚拟内存使用大小峰值,单位字节,有待考证。

PrivatePageCount

存放进程的提交大小,单位字节,也就是进程动态申请的内存的理论长度。

Reserved6

保留参数,其实并不是没有用到,只是微软隐藏了而已。

其他说明

 

 

 

4.3.1.2   _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION

结构体名称

_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION

头文件

#include <Winternl.h>

结构体说明

存放每个CPU处理器核心的相关信息。

相关函数

NtQuerySystemInformation()、Func2()、Func3()…

结构体声明

typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION

{

LARGE_INTEGER IdleTime;

LARGE_INTEGER KernelTime;

LARGE_INTEGER UserTime;

LARGE_INTEGER Reserved1[2];

ULONG         Reserved2;

} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;

成员变量

IdleTime

存放CPU处理器核心的空闲时间。

KernelTime

存放CPU处理器核心的内核时间。

UserTime

存放CPU处理器核心的用户时间。

Reserved1

保留参数,其实并不是没有用到,只是微软隐藏了而已。

Reserved2

保留参数,其实并不是没有用到,只是微软隐藏了而已。

其他说明

 

 

 

4.3.2 CPU处理器

4.3.3 内存

4.3.3.1   MEMORYSTATUS(未完成)

结构体名称

MEMORYSTATUS

头文件

#include <WinBase.h>

结构体说明

存放物理内存和虚拟内存的相关信息。

相关函数

GlobalMemoryStatus()

结构体声明

struct MEMORYSTATUS

{

DWORD  dwLength;

DWORD  dwMemoryLoad;

SIZE_T dwTotalPhys;

SIZE_T dwAvailPhys;

SIZE_T dwTotalPageFile;

SIZE_T dwAvailPageFile;

SIZE_T dwTotalVirtual;

SIZE_T dwAvailVirtual;

};

成员变量

dwLength

存放本结构体占用字节大小。本参数由GlobalMemoryStatus()函数自动设置,无需事先设置。

dwMemoryLoad

存放物理内存的使用率,单位百分比,数值大于等于0,小于等于100。

0表示没有使用任何内存,100表示使用了全部内存。

dwTotalPhys

存放物理内存总大小,单位字节。

如果物理内存总大小超过4GB,本参数将一直为4GB。

dwAvailPhys

存放物理内存剩余可用大小,单位字节。

如果物理内存剩余可用大小超过4GB,本参数将一直为4GB。

dwTotalPageFile

存放虚拟内存的页面文件总大小,单位字节。

本参数并不表示页面文件在磁盘上的实际文件大小。

如果物理内存剩余可用大小超过4GB,本参数将一直为4GB。

dwAvailPageFile

存放当前调用进程对页面文件的最大可用大小,单位字节。

本参数应该小于页面文件剩余可用大小。

如果当前调用进程对页面文件的最大可用大小超过4GB,本参数将一直为4GB。

dwTotalVirtual

存放当前调用进程的虚拟地址空间的用户空间的总大小,以字节为单位。

本参数与CPU硬件性能参数及操作系统有关,例如,该值约为2 GB的在x86处理器上大多数32位进程和大约3 GB的32位进程是大地址识别运行的系统上4 GT RAM微调功能。

如果当前调用进程的虚拟地址空间的用户空间的总大小超过4GB,本参数将一直为4GB。

dwAvailVirtual

存放当前调用进程的虚拟地址空间的用户空间的剩余可用大小,以字节为单位。

如果当前调用进程的虚拟地址空间的用户空间的剩余可用大小超过4GB,本参数将一直为4GB。

其他说明

本结构体只能获取内存大小不超过4GB的相关信息,如果要获取内存大小超过4GB的相关信息,可以调用GlobalMemoryStatusEx()函数。

 

 

4.4 网络设备

4.4.1 MIB_IFROW

结构体名称

MIB_IFROW

头文件

#include <Iphlpapi.h>

结构体说明

存放网络设备的状态信息,包括名称、索引序号、类型、最大传输单元、传输速度、物理地址、管理状态、操作状态、输入输出流量记录、描述。

相关函数

GetIfTAble()

结构体声明

struct MIB_IFROW

{

WCHAR wszName[MAX_INTERFACE_NAME_LEN];

IF_INDEX dwIndex;

IFTYPE dwType;

DWORD dwMtu;

DWORD dwSpeed;

DWORD dwPhysAddrLen;

UCHAR bPhysAddr[MAXLEN_PHYSADDR];

DWORD dwAdminStatus;

INTERNAL_IF_OPER_STATUS dwOperStatus;

DWORD dwLastChange;

DWORD dwInOctets;

DWORD dwInUcastPkts;

DWORD dwInNUcastPkts;

DWORD dwInDiscards;

DWORD dwInErrors;

DWORD dwInUnknownProtos;

DWORD dwOutOctets;

DWORD dwOutUcastPkts;

DWORD dwOutNUcastPkts;

DWORD dwOutDiscards;

DWORD dwOutErrors;

DWORD dwOutQLen;

DWORD dwDescrLen;

UCHAR bDescr[MAXLEN_IFDESCR];

};

成员变量

wszName

存放网络设备的唯一GUID名称字符串。

dwIndex

存放网络设备的唯一索引序号,可以使用route print命令的接口列表查看。

dwType

存放网络设备的类型,可以为:

IF_TYPE_OTHER(1)

其他的网络设备。

IF_TYPE_ETHERNET_CSMACD(6)

以太网网络设备。

IF_TYPE_ISO88025_TOKENRING(9)

令牌环网网络设备。

IF_TYPE_FDDI(15)

FDDI光纤分布式数据接口(Fiber Distributed-Data Interface)网络设备。

IF_TYPE_PPP(23)

PPP点对点协议(Point to Point Protocol)网络设备。

IF_TYPE_SOFTWARE_LOOPBACK(24)

软件回环网络接口。

IF_TYPE_SLIP(28):

串行适配器(Serial Line Interface Protocol)。

IF_TYPE_ATM(37)

异步传输模式(Asynchronous Transfer Mode)网络设备。

IF_TYPE_IEEE80211(71)

基于IEEE 802.11标准的无线网络设备。

IF_TYPE_TUNNEL(131)

隧道式封装(Tunnel-encapsulated)网络设备。

IF_TYPE_IEEE1394(144)

基于IEEE 1394(火线)高性能串行总线的网络设备。

IF_TYPE_IEEE80216_WMAN(237)

基于WiMax全球微波互联接入 (Worldwide Interoperability for Microwave Access)的移动网络设备。

注意:只有Windows 7和Windows Server 2008 R2及以后的系统支持此类型设备。

IF_TYPE_WWANPP(243)

基于GSM全球移动通信系统(Global System for Mobile communication)标准的移动网络设备。

注意:只有Windows 7和Windows Server 2008 R2及以后的系统支持此类型设备。

IF_TYPE_WWANPP2(244)

基于CDMA码分多址技术的移动网络设备。

注意:只有Windows 7和Windows Server 2008 R2及以后的系统支持此类型设备。

dwMtu

存放网络设备的最大传输单元的长度,单位字节。

dwSpeed

存放网络设备的最大传输速率,单位比特位每秒。

有些设备是以1000为进制单位的,有些是以1024为进制单位的,表示不一样,但实际意思都是一样的,例如:1000Mbps的速率,本参数可能为1000*1000*1000=1000000000 bps,也可能为1024*1024*1024=1073741824 bps。

dwPhysAddrLen

存放bPhysAddr参数的使用长度,单位字节。

bPhysAddr

存放网络设备的MAC物理地址。

dwAdminStatus

存放网络设备的管理状态,1表示启用,2表示禁用。

管理状态是指通过控制面板的网络和共享中心等方式对该网络设备进行管理。

dwOperStatus

存放网络设备的操作状态。可以为:

IF_OPER_STATUS_NON_OPERATIONAL(0):

LAN局域网适配器已被禁用,例如:地址冲突。

IF_OPER_STATUS_UNREACHABLE(1):

WAN广域网适配器未连接。

IF_OPER_STATUS_DISCONNECTED(2):

对于LAN局域网适配器,表示网络电缆断开。对于WAN广域网适配器,表示无信号。

IF_OPER_STATUS_CONNECTING(3):

WAN广域网适配器正在进行连接。

IF_OPER_STATUS_CONNECTED(4):

WAN广域网适配器已经连接到远端对等网络。

IF_OPER_STATUS_OPERATIONAL(5):

LAN局域网适配器的默认状态,例如:已经连接。

dwLastChange

存放网络设备的已进入当前操作状态了多久,单位百分之一秒。

操作状态就是dwOperStatus成员变量所指示的操作状态。

当系统重新启动,或本参数达到2^32后,本参数清0。

dwInOctets

存放网络设备的累计输入流量,单位字节。

dwInUcastPkts

存放网络设备的输入包的累计个数。

dwInNUcastPkts

存放网络设备的输入包的累计非单播个数。

非单播是指广播和多播。

dwInDiscards

存放网络设备的输入包的累计丢弃个数。

丢弃原因可能是错误的,或者重复的,或者协议未知,等等。

dwInErrors

存放网络设备的输入包的累计因错误丢弃个数。

dwInUnknownProtos

存放网络设备的输入包的累计因协议未知丢弃个数。

dwOutOctets

存放网络设备的累计输出流量,单位字节。

dwOutUcastPkts

存放网络设备的输出包的累计个数。

dwOutNUcastPkts

存放网络设备的输入包的累计非单播个数。

非单播是指广播和多播。

dwOutDiscards

存放网络设备的输出包的累计丢弃个数。

丢弃原因可能是错误的,或者重复的,或者协议未知,等等。

dwOutErrors

存放网络设备的输出包的累计因错误丢弃个数。

dwOutQLen

存放网络设备的输出缓存长度。

本参数已不再使用。

dwDescrLen

存放网络设备的bDescr参数描述字符串的长度,包括'\0'结束符。

bDescr

存放网络设备的描述字符串,通常为硬件型号、软件虚拟名称。

其他说明

 

 

 

4.4.2 IP_ADAPTER_INFO

结构体名称

IP_ADAPTER_INFO

头文件

#include <IPTypes.h>

结构体说明

存放网络适配器的状态信息。

相关函数

GetAdaptersInfo()

结构体声明

struct xxx

{

类型  成员变量1;

类型  成员变量2;

……

};

成员变量

成员变量1

成员变量说明。

成员变量2

成员变量说明。

……

其他说明

……

……

 

 

4.4.3 IP_INTERFACE_INFO(未完成)

结构体名称

IP_INTERFACE_INFO

头文件

#include <IPExport.h>

结构体说明

存放本机所有启用了IPv4协议的物理和虚拟的网络适配器的名称和索引序号。

相关函数

GetInterfaceInfo()

结构体声明

struct IP_INTERFACE_INFO

{

LONG NumAdapters;

IP_ADAPTER_INDEX_MAP Adapter[1];

};

成员变量

NumAdapters

存放本结构体存放了多少个网络适配器。

IP_ADAPTER_INDEX_MAP

存放网络适配器的名称和索引序号的动态数组,如果NumAdapters参数为0,本参数无意义。

其他说明

本结构体只存放本机所有启用了IPv4协议的物理和虚拟的网络适配器,

 

 

4.5 性能计数器

4.5.1 PPDH_FMT_COUNTERVALUE(未完成)

结构体名称

PPDH_FMT_COUNTERVALUE

头文件

#include <Pdh.h>

结构体说明

用于存储性能计数器的数值。

相关函数

PdhGetFormattedCounterValue()、PdhCalculateCounterFromRawValue()

结构体声明

struct PDH_FMT_COUNTERVALUE

{

    DWORD    CStatus;

union

{

        LONG        longValue;

        double      doubleValue;

        LONGLONG    largeValue;

        LPCSTR      AnsiStringValue;

        LPCWSTR     WideStringValue;

    };

};

成员变量

CStatus

存放计数器数值的状态码,状态码表示该数值是否是有效,0表示有效,非0表示无效,状态码可以为:

PDH_CSTATUS_NO_MACHINE宏:

PDH was unable to connect to the computer specified in the counter path. If this status is returned when the counter is being added, the counter is not completely initialized. Each time the query is updated, PDH retries the connection. When the connection is established, normal data collection resumes.

PDH_CSTATUS_NO_OBJECT宏:

The specified computer was found, but the specified performance object was found on the computer. If this status is returned when the counter is being added, the specified counter is not included in the query. If this status is returned by an active counter, the data for that counter is invalid. Each time the data is requested, PDH tries to obtain this counter data.

PDH_CSTATUS_NO_INSTANCE宏:

The specified instance was not found in the object. If this status is returned while the counter is being added to the query, the counter is successfully added to the query, but no data is available until the specific instance appears and a successful status is returned.

PDH_CSTATUS_NO_COUNTER宏:

The specified counter was not found in the specified object. If this status is returned when the counter is being added, then the counter is not added to the query. If this status is returned after data collection, the data for that counter is invalid. Each time the data is requested, PDH tries to obtain this counter data.

PDH_CSTATUS_INVALID_DATA宏:

The counter was successfully found, but the data returned is not valid. This error can occur if the counter value is less than the previous value. (Because counter values always increment, the counter value rolls over to zero when it reaches its maximum value.) Another possible cause is a system timer that is not correct.

PDH_CSTATUS_VALID_DATA宏:

The data for the counter was returned successfully, but is unchanged from the last time the counter was read.

PDH_CSTATUS_NEW_DATA宏:

The data for the counter was returned successfully and is different from the last time the counter was read. PDH_CSTATUS_NEW_DATA can be returned on a rate counter even if the resulting rate is the same as the last sample. This is because the raw data value that is used in the determination of this status value has changed, not the computed rate.

PDH_MORE_DATA宏:

The supplied buffer was not large enough to store all of the counter data. Allocate a larger buffer and execute the function again.

PDH_CSTATUS_ITEM_NOT_VALIDATED宏:

The counter has been added to the query, but has not been validated nor accessed. No additional status information on this counter is available.

PDH_CSTATUS_NO_COUNTERNAME宏:

查询句柄中没有指定计数器的名字。

PDH_CSTATUS_NO_COUNTER宏:

指定的计数器的名字没有找到。

PDH_CSTATUS_NO_OBJECT宏:

指定的计数器的对象没有找到。

PDH_CALC_NEGATIVE_DENOMINATOR宏:

计数器具有分母值为负数的值。

PDH_CALC_NEGATIVE_TIMEBASE宏:

计数器具有时间基数为负数的值。

PDH_CALC_NEGATIVE_VALUE宏:

计数器具有负数的值。

PDH_CSTATUS_NO_COUNTERNAME宏:

没有指定计数器路径字符串。

PDH_CSTATUS_BAD_COUNTERNAME宏:

计数器路径字符串的格式是不正确的。

longValue

存放计数器数值为LONG型的值。

doubleValue

存放计数器数值为DOUBLE型的值。

largeValue

存放计数器数值为LONGLONG型的值。

AnsiStringValue

存放计数器数值为ANSI字符串型的值。暂时未用。

WideStringValue

存放计数器数值为WIDE字符串型的值。暂时未用。

其他说明

调用完收集函数并获取计数器的数值成功后,还要判断状态码是否为有效,如果是状态码无效的,则表示获取到的数值是不正确的,如果状态码是有效的,则表示获取到的数值是正确的。

根据调用获取计数器的数值函数时指定的是什么类型,来使用本结构体的哪个成员变量,例如如果指定的是LONG型,那么就使用longValue成员变量。

 

 

4.6 进程

4.6.1 PROCESS_INFORMATION

结构体名称

PROCESS_INFORMATION

头文件

#include <Windows.h>

结构体说明

进程信息结构体用于存放进程和主线程的标识和句柄。

相关函数

CreateProcess()、CreateProcessAsUser()、CreateProcessWithLogonW()、 CreateProcessWithTokenW()

结构体声明

struct PROCESS_INFORMATION

{

HANDLE hProcess;

HANDLE hThread;

DWORD dwProcessId;

DWORD dwThreadId;

};

成员变量

hProcess

存放进程的句柄。

hThread

存放主线程的句柄。

dwProcessId

存放进程的标识。

如果原进程退出后,本标识可能会分配给新进程。

dwThreadId

存放主线程的标识。

如果原线程退出后,本标识可能会分配给新线程。

其他说明

 

 

 

4.7 文件

4.7.1 SHFILEOPSTRUCT(未完成)

结构体名称

SHFILEOPSTRUCT

头文件

#include <Shellapi.h>

结构体说明

Shell命令文件操作结构体用于针对SHFileOperation()函数的使用。

结构体声明

struct SHFILEOPSTRUCT

{

HWND         hwnd;

UINT         wFunc;

PCZZTSTR     pFrom;

PCZZTSTR     pTo;

FILEOP_FLAGS fFlags;

BOOL         fAnyOperationsAborted;

LPVOID       hNameMappings;

PCTSTR       lpszProgressTitle;

};

成员变量

hwnd

存放执行文件操作时,显示的操作过程窗口的父窗口句柄,为0表示没有父窗口,也就是桌面窗口。

wFunc

存放具体执行哪种文件操作的标记,可以为(选一至一个):

FO_COPY

把pFrom成员变量指定的文件或目录复制到pTo成员变量指定的本地文件或目录。

FO_DELETE

删除pFrom成员变量指定的单个文件或单个目录。

FO_MOVE

把pFrom成员变量指定的文件或目录移动到pTo成员变量指定的本地文件或目录。

FO_RENAME

重命名pFrom成员变量指定的单个文件或单个目录。

如果要重命名多个文件或多个目录,可用FO_MOVE标记代替。

pFrom

成员变量说明。

成员变量1

成员变量说明。

成员变量1

成员变量说明。

成员变量1

成员变量说明。

成员变量1

成员变量说明。

成员变量1

成员变量说明。

其他说明

……

……

 

 

4.8 窗口

4.8.1 RECT(未完成)

结构体名称

RECT

头文件

#include <Windows.h>

结构体说明

用于存放窗口的左边、顶边、右边、底边在屏幕上的位置。

相关函数

GetWindowRect()、Func2()、Func3()…

结构体声明

struct RECT

{

LONG left;

LONG top;

LONG right;

LONG bottom;

};

成员变量

left

存放窗口的左边在屏幕上的哪个像素。

top

存放窗口的顶边在屏幕上的哪个像素。

right

存放窗口的右边在屏幕上的哪个像素。

bottom

存放窗口的底边在屏幕上的哪个像素。

其他说明

 

 

 

4.8.2 LVITEM(未完成)

结构体名称

LVITEM

头文件

#include <Commctrl.h>

结构体说明

存放列表控件中某个项目的某个字段的信息。

相关函数

CListCtrl::InsertItem()、CListCtrl::GetItem()、CListCtrl::SetItem()

结构体声明

struct LVITEM

{

    UINT mask;

    int iItem;

    int iSubItem;

    UINT state;

    UINT stateMask;

    LPSTR pszText;

    int cchTextMax;

    int iImage;

    LPARAM lParam;

    int iIndent;

#if (NTDDI_VERSION >= NTDDI_WINXP)

    int iGroupId;

    UINT cColumns; // tile view columns

    PUINT puColumns;

#endif

#if (NTDDI_VERSION >= NTDDI_VISTA) // Will be unused downlevel, but sizeof(LVITEMA) must be equal to sizeof(LVITEMW)

    int* piColFmt;

    int iGroup; // readonly. only valid for owner data.

#endif

};

成员变量

mask

存放本函数有哪些参数有效的标记,可以为(用'|'选零至多个):

LVIF_TEXT(0x00000001):

如果设置本标记,表示pszText参数有效,也就是标签字符串有效。

如果不设置本标记,表示项目没有标签。

LVIF_IMAGE(0x00000002):

 

LVIF_PARAM(0x00000004):

 

LVIF_STATE(0x00000008):

 

LVIF_INDENT(0x00000010):

 

LVIF_NORECOMPUTE(0x00000800):

 

以下标记需要XP及以后的系统才支持:

LVIF_GROUPID(0x00000100):

 

LVIF_COLUMNS(0x00000200):

 

以下标记需要VISTA及以后的系统才支持:

LVIF_COLFMT(0x00010000): // The piColFmt member is valid in addition to puColumns

 

iItem

存放项目的项目索引号,本参数只能大于等于0。

iSubItem

存放项目的字段索引号,本参数只能大于等于0。

state

成员变量说明。

stateMask

成员变量说明。

pszText

存放项目的标签字符串的内存指针。

在调用设置相关函数(例如:CListCtrl::InsertItem)时:

如果本成员变量为NULL,就表示项目没有标签,列表控件上标签位置显示为一片空白。

如果本成员变量为LPSTR_TEXTCALLBACK宏,表示项目的标签为虚拟标签。虚拟标签是指列表控件不为标签字符串分配内存,当需要显示标签时,通过调用列表控件的LVN_GETDISPINFO消息响应函数来显示。使用虚拟标签可以节约内存,并可以快速插入并显示大量项目,列表控件不会出现卡顿现象。详情请参考LVN_GETDISPINFO消息。

cchTextMax

存放项目的标签字符串的内存的最大长度。

本参数只适用于调用获取相关函数(例如:CListCtrl::GetItem)时,pszText参数指向的用于存放标签字符串的内存的最大长度,不适用于调用设置相关函数(例如:CListCtrl::InsertItem)。

iImage

成员变量说明。

lParam

成员变量说明。

iIndent

成员变量说明。

iGroupId

成员变量说明。

cColumns

成员变量说明。

puColumns

成员变量说明。

piColFmt

成员变量说明。

iGroup

成员变量说明。

其他说明

 

 

 

4.9 时钟

4.9.1 timeval

结构体名称

timeval

头文件

#include <time.h>

结构体说明

用于记录时间的结构体。

结构体声明

struct timeval

{

  time_t tv_sec;

  suseconds_t tv_usec;

};

成员变量

tv_sec

表示多少秒。

tv_usec

表示多少微秒,1秒等于1000000微秒。

其他说明

 

 

 

4.9.2 timezone

结构体名称

timezone

头文件

#include <time.h>

结构体说明

用于记录时区的结构体。

结构体声明

struct timezone

{

  int tz_minuteswest;

  int tz_dsttime;

};

成员变量

tz_minuteswest:[输入&输出],和格林威治时间往西方的时差,差了多少分钟。

tz_dsttime:[输入&输出],夏时制或夏令时或日光节约时(Daylight Saving Time)的类型。

类型如下:

DST_NONE     //不使用

DST_USA      //美国

DST_AUST     //澳洲

DST_WET      //西欧

DST_MET      //中欧

DST_EET      //东欧

DST_CAN      //加拿大

DST_GB       //大不列颠

DST_RUM      //罗马尼亚

DST_TUR      //土耳其

DST_AUSTALT  //澳洲(1986年以后)

其他说明

 

 

 

4.9.3 tm

结构体名称

tm

头文件

#include <time.h>

结构体说明

存放日历的结构体。

结构体声明

struct tm

{

  int tm_sec;

  int tm_min;

  int tm_hour;

  int tm_mday;

  int tm_mon;

  int tm_year;

  int tm_wday;

  int tm_yday;

  int tm_isdst;

};

成员变量

tm_sec:表示秒钟,在[0,60]之间,多出来的一秒是用来处理闰秒问题。

tm_min:表示分钟,在[0,59]之间。

tm_hour:表示时钟,在[0,23]之间。

tm_mday:表示日份,在[1,31]之间。

tm_mon:表示月份,在[0,11]之间。

tm_year:表示1900年到今年一共差多少年。

tm_wday:表示星期几,在[0,6]之间,星期天为0,星期一为1,以此类推。

tm_yday:表示当天是本年第几日,在[0,365]之间,非闰年有365日,闰年有366日。

tm_isdst:表示是否为日光节约时间。

其他说明

 

 

 

4.9.4 SYSTEMTIME

结构体名称

SYSTEMTIME

头文件

#include <Windows.h>

结构体说明

存放日期时间信息。

结构体声明

typedef struct _SYSTEMTIME

{

    WORD wYear;

    WORD wMonth;

    WORD wDayOfWeek;

    WORD wDay;

    WORD wHour;

    WORD wMinute;

    WORD wSecond;

    WORD wMilliseconds;

}SYSTEMTIME;

成员变量

wYear:表示年份,在[1601-30827]之间。例如:此值为2013,就表示2013年。

wMonth:表示月份,在[1-12]之间。例如:此值为1,就表示1月;此值为12,就表示12月。

wDayOfWeek:表示星期几,在[1-7]之间。例如:此值为1,就表示星期日;此值为7,就表示星期六。

wDay:表示日份,在[1-31]之间。

wHour:表示时钟,在[0-23]之间。

wMinute:表示分钟,在[0-59]之间。

wSecond:表示秒钟,在[0-59]之间。

wMilliseconds:表示毫秒,在[0-999]之间。

其他说明

 

 

 

4.9.5 TIME_ZONE_INFORMATION(未完成)

结构体名称

TIME_ZONE_INFORMATION

头文件

#include <timezoneapi.h>

结构体说明

存放时区信息的结构体。

相关函数

GetTimeZoneInformation()、SetTimeZoneInformation()

结构体声明

struct TIME_ZONE_INFORMATION

{

LONG       Bias;

WCHAR      StandardName[32];

SYSTEMTIME StandardDate;

LONG       StandardBias;

WCHAR      DaylightName[32];

SYSTEMTIME DaylightDate;

LONG       DaylightBias;

};

成员变量

Bias

存放本地时转换为协调时需要加减多少分钟。

例如:如果本地时区为东八区,则本参数为-480。

StandardName

存放本地时区的标准名称的字符串。

例如:“中国标准时间”。

本参数配置在以下注册表中:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones

以中国北京时间为例即 China Standard Time子项,

Display:在控制面板中调整时区时显示的名称

Std:标准时间名称

Dlt:如果有夏令时时区则为其名称。

Tzi:一个数据结构,包含本地时区和0时区相差的分钟数等信息。二进制形式存储的用一结构体定义之

typedef struct _REG_TZI_FORMAT

{

LONG Bias;

  LONG StandardBias;

  LONG DaylightBias;

  SYSTEMTIME StandardDate;

  SYSTEMTIME DaylightDate;

}REG_TZI_FORMAT;

StandardDate

成员变量说明。

StandardBias

成员变量说明。

DaylightName

成员变量说明。

DaylightDate

成员变量说明。

DaylightBias

成员变量说明。

其他说明

 

 

 

4.10  消息机制

4.10.1   MSG

结构体名称

MSG

头文件

#include <Windows.h>

结构体说明

用于存放每一个线程的消息队列里的消息的各项信息。

结构体声明

struct MSG

{

HWND hwnd;

UINT message;

WPARAM wParam;

LPARAM lParam;

DWORD time;

POINT pt;

};

成员变量

hwnd

存放此条窗口消息是哪一个窗口句柄的。

如果不是窗口消息,此参数为NULL。

message

存放消息值,就是表示此条消息是什么消息。例如:窗口消息可能是WM_USER、WM_CHAR等,线程消息可能是自定义的了。

wParam

存放此条消息的第一个参数,具体作用根据不同的消息而定。

lParam

存放此条消息的第二个参数,具体作用根据不同的消息而定。

time

存放此条消息的发送时间。

pt

存放此条消息在发送的时候,鼠标所在坐标。

注意:这不是接收此条消息时的坐标,因为从消息的发送到接收是需要时间的。

其他说明

 

 

 

4.11  音频

4.11.1   WAVEFORMATEX(未完成)

结构体名称

WAVEFORMATEX

头文件

#include <mmeapi.h>

结构体称呼

音频格式结构体。

结构体说明

用于存放音频数据格式的相关参数。

相关函数

waveInOpen()、Func2()、Func3()…

结构体声明

struct WAVEFORMATEX

{

WORD        wFormatTag;         /* format type */

WORD        nChannels;          /* number of channels (i.e. mono, stereo...) */

DWORD       nSamplesPerSec;     /* sample rate */

DWORD       nAvgBytesPerSec;    /* for buffer estimation */

WORD        nBlockAlign;        /* block size of data */

WORD        wBitsPerSample;     /* number of bits per sample of mono data */

WORD        cbSize;             /* the count in bytes of the size of */

                                    /* extra information (after cbSize) */

};

成员变量

wFormatTag

存放音频的格式,一般选WAVE_FORMAT_PCM宏表示原始格式,可以为(选一至一个):

WAVE_FORMAT_UNKNOWN                    0x0000 /* Microsoft Corporation */

WAVE_FORMAT_PCM                        0x0001 /* raw format */

WAVE_FORMAT_ADPCM                      0x0002 /* Microsoft Corporation */

WAVE_FORMAT_IEEE_FLOAT                 0x0003 /* Microsoft Corporation */

WAVE_FORMAT_VSELP                      0x0004 /* Compaq Computer Corp. */

WAVE_FORMAT_IBM_CVSD                   0x0005 /* IBM Corporation */

WAVE_FORMAT_ALAW                       0x0006 /* Microsoft Corporation */

WAVE_FORMAT_MULAW                      0x0007 /* Microsoft Corporation */

WAVE_FORMAT_DTS                        0x0008 /* Microsoft Corporation */

WAVE_FORMAT_DRM                        0x0009 /* Microsoft Corporation */

WAVE_FORMAT_WMAVOICE9                  0x000A /* Microsoft Corporation */

WAVE_FORMAT_WMAVOICE10                 0x000B /* Microsoft Corporation */

WAVE_FORMAT_OKI_ADPCM                  0x0010 /* OKI */

WAVE_FORMAT_DVI_ADPCM                  0x0011 /* Intel Corporation */

WAVE_FORMAT_IMA_ADPCM                  (WAVE_FORMAT_DVI_ADPCM) /*  Intel Corporation */

WAVE_FORMAT_MEDIASPACE_ADPCM           0x0012 /* Videologic */

WAVE_FORMAT_SIERRA_ADPCM               0x0013 /* Sierra Semiconductor Corp */

WAVE_FORMAT_G723_ADPCM                 0x0014 /* Antex Electronics Corporation */

WAVE_FORMAT_DIGISTD                    0x0015 /* DSP Solutions, Inc. */

WAVE_FORMAT_DIGIFIX                    0x0016 /* DSP Solutions, Inc. */

WAVE_FORMAT_DIALOGIC_OKI_ADPCM         0x0017 /* Dialogic Corporation */

WAVE_FORMAT_MEDIAVISION_ADPCM          0x0018 /* Media Vision, Inc. */

WAVE_FORMAT_CU_CODEC                   0x0019 /* Hewlett-Packard Company */

WAVE_FORMAT_HP_DYN_VOICE               0x001A /* Hewlett-Packard Company */

WAVE_FORMAT_YAMAHA_ADPCM               0x0020 /* Yamaha Corporation of America */

WAVE_FORMAT_SONARC                     0x0021 /* Speech Compression */

WAVE_FORMAT_DSPGROUP_TRUESPEECH        0x0022 /* DSP Group, Inc */

WAVE_FORMAT_ECHOSC1                    0x0023 /* Echo Speech Corporation */

WAVE_FORMAT_AUDIOFILE_AF36             0x0024 /* Virtual Music, Inc. */

WAVE_FORMAT_APTX                       0x0025 /* Audio Processing Technology */

WAVE_FORMAT_AUDIOFILE_AF10             0x0026 /* Virtual Music, Inc. */

WAVE_FORMAT_PROSODY_1612               0x0027 /* Aculab plc */

WAVE_FORMAT_LRC                        0x0028 /* Merging Technologies S.A. */

WAVE_FORMAT_DOLBY_AC2                  0x0030 /* Dolby Laboratories */

WAVE_FORMAT_GSM610                     0x0031 /* Microsoft Corporation */

WAVE_FORMAT_MSNAUDIO                   0x0032 /* Microsoft Corporation */

WAVE_FORMAT_ANTEX_ADPCME               0x0033 /* Antex Electronics Corporation */

WAVE_FORMAT_CONTROL_RES_VQLPC          0x0034 /* Control Resources Limited */

WAVE_FORMAT_DIGIREAL                   0x0035 /* DSP Solutions, Inc. */

WAVE_FORMAT_DIGIADPCM                  0x0036 /* DSP Solutions, Inc. */

WAVE_FORMAT_CONTROL_RES_CR10           0x0037 /* Control Resources Limited */

WAVE_FORMAT_NMS_VBXADPCM               0x0038 /* Natural MicroSystems */

WAVE_FORMAT_CS_IMAADPCM                0x0039 /* Crystal Semiconductor IMA ADPCM */

WAVE_FORMAT_ECHOSC3                    0x003A /* Echo Speech Corporation */

WAVE_FORMAT_ROCKWELL_ADPCM             0x003B /* Rockwell International */

WAVE_FORMAT_ROCKWELL_DIGITALK          0x003C /* Rockwell International */

WAVE_FORMAT_XEBEC                      0x003D /* Xebec Multimedia Solutions Limited */

WAVE_FORMAT_G721_ADPCM                 0x0040 /* Antex Electronics Corporation */

WAVE_FORMAT_G728_CELP                  0x0041 /* Antex Electronics Corporation */

WAVE_FORMAT_MSG723                     0x0042 /* Microsoft Corporation */

WAVE_FORMAT_INTEL_G723_1               0x0043 /* Intel Corp. */

WAVE_FORMAT_INTEL_G729                 0x0044 /* Intel Corp. */

WAVE_FORMAT_SHARP_G726                 0x0045 /* Sharp */

WAVE_FORMAT_MPEG                       0x0050 /* Microsoft Corporation */

WAVE_FORMAT_RT24                       0x0052 /* InSoft, Inc. */

WAVE_FORMAT_PAC                        0x0053 /* InSoft, Inc. */

WAVE_FORMAT_MPEGLAYER3                 0x0055 /* ISO/MPEG Layer3 Format Tag */

WAVE_FORMAT_LUCENT_G723                0x0059 /* Lucent Technologies */

WAVE_FORMAT_CIRRUS                     0x0060 /* Cirrus Logic */

WAVE_FORMAT_ESPCM                      0x0061 /* ESS Technology */

WAVE_FORMAT_VOXWARE                    0x0062 /* Voxware Inc */

WAVE_FORMAT_CANOPUS_ATRAC              0x0063 /* Canopus, co., Ltd. */

WAVE_FORMAT_G726_ADPCM                 0x0064 /* APICOM */

WAVE_FORMAT_G722_ADPCM                 0x0065 /* APICOM */

WAVE_FORMAT_DSAT                       0x0066 /* Microsoft Corporation */

WAVE_FORMAT_DSAT_DISPLAY               0x0067 /* Microsoft Corporation */

WAVE_FORMAT_VOXWARE_BYTE_ALIGNED       0x0069 /* Voxware Inc */

WAVE_FORMAT_VOXWARE_AC8                0x0070 /* Voxware Inc */

WAVE_FORMAT_VOXWARE_AC10               0x0071 /* Voxware Inc */

WAVE_FORMAT_VOXWARE_AC16               0x0072 /* Voxware Inc */

WAVE_FORMAT_VOXWARE_AC20               0x0073 /* Voxware Inc */

WAVE_FORMAT_VOXWARE_RT24               0x0074 /* Voxware Inc */

WAVE_FORMAT_VOXWARE_RT29               0x0075 /* Voxware Inc */

WAVE_FORMAT_VOXWARE_RT29HW             0x0076 /* Voxware Inc */

WAVE_FORMAT_VOXWARE_VR12               0x0077 /* Voxware Inc */

WAVE_FORMAT_VOXWARE_VR18               0x0078 /* Voxware Inc */

WAVE_FORMAT_VOXWARE_TQ40               0x0079 /* Voxware Inc */

WAVE_FORMAT_VOXWARE_SC3                0x007A /* Voxware Inc */

WAVE_FORMAT_VOXWARE_SC3_1              0x007B /* Voxware Inc */

WAVE_FORMAT_SOFTSOUND                  0x0080 /* Softsound, Ltd. */

WAVE_FORMAT_VOXWARE_TQ60               0x0081 /* Voxware Inc */

WAVE_FORMAT_MSRT24                     0x0082 /* Microsoft Corporation */

WAVE_FORMAT_G729A                      0x0083 /* AT&T Labs, Inc. */

WAVE_FORMAT_MVI_MVI2                   0x0084 /* Motion Pixels */

WAVE_FORMAT_DF_G726                    0x0085 /* DataFusion Systems (Pty) (Ltd) */

WAVE_FORMAT_DF_GSM610                  0x0086 /* DataFusion Systems (Pty) (Ltd) */

WAVE_FORMAT_ISIAUDIO                   0x0088 /* Iterated Systems, Inc. */

WAVE_FORMAT_ONLIVE                     0x0089 /* OnLive! Technologies, Inc. */

WAVE_FORMAT_MULTITUDE_FT_SX20          0x008A /* Multitude Inc. */

WAVE_FORMAT_INFOCOM_ITS_G721_ADPCM     0x008B /* Infocom */

WAVE_FORMAT_CONVEDIA_G729              0x008C /* Convedia Corp. */

WAVE_FORMAT_CONGRUENCY                 0x008D /* Congruency Inc. */

WAVE_FORMAT_SBC24                      0x0091 /* Siemens Business Communications Sys */

WAVE_FORMAT_DOLBY_AC3_SPDIF            0x0092 /* Sonic Foundry */

WAVE_FORMAT_MEDIASONIC_G723            0x0093 /* MediaSonic */

WAVE_FORMAT_PROSODY_8KBPS              0x0094 /* Aculab plc */

WAVE_FORMAT_ZYXEL_ADPCM                0x0097 /* ZyXEL Communications, Inc. */

WAVE_FORMAT_PHILIPS_LPCBB              0x0098 /* Philips Speech Processing */

WAVE_FORMAT_PACKED                     0x0099 /* Studer Professional Audio AG */

WAVE_FORMAT_MALDEN_PHONYTALK           0x00A0 /* Malden Electronics Ltd. */

WAVE_FORMAT_RACAL_RECORDER_GSM         0x00A1 /* Racal recorders */

WAVE_FORMAT_RACAL_RECORDER_G720_A      0x00A2 /* Racal recorders */

WAVE_FORMAT_RACAL_RECORDER_G723_1      0x00A3 /* Racal recorders */

WAVE_FORMAT_RACAL_RECORDER_TETRA_ACELP 0x00A4 /* Racal recorders */

WAVE_FORMAT_NEC_AAC                    0x00B0 /* NEC Corp. */

WAVE_FORMAT_RAW_AAC1                   0x00FF /* For Raw AAC, with format block AudioSpecificConfig() (as defined by MPEG-4), that follows WAVEFORMATEX */

WAVE_FORMAT_RHETOREX_ADPCM             0x0100 /* Rhetorex Inc. */

WAVE_FORMAT_IRAT                       0x0101 /* BeCubed Software Inc. */

WAVE_FORMAT_VIVO_G723                  0x0111 /* Vivo Software */

WAVE_FORMAT_VIVO_SIREN                 0x0112 /* Vivo Software */

WAVE_FORMAT_PHILIPS_CELP               0x0120 /* Philips Speech Processing */

WAVE_FORMAT_PHILIPS_GRUNDIG            0x0121 /* Philips Speech Processing */

WAVE_FORMAT_DIGITAL_G723               0x0123 /* Digital Equipment Corporation */

WAVE_FORMAT_SANYO_LD_ADPCM             0x0125 /* Sanyo Electric Co., Ltd. */

WAVE_FORMAT_SIPROLAB_ACEPLNET          0x0130 /* Sipro Lab Telecom Inc. */

WAVE_FORMAT_SIPROLAB_ACELP4800         0x0131 /* Sipro Lab Telecom Inc. */

WAVE_FORMAT_SIPROLAB_ACELP8V3          0x0132 /* Sipro Lab Telecom Inc. */

WAVE_FORMAT_SIPROLAB_G729              0x0133 /* Sipro Lab Telecom Inc. */

WAVE_FORMAT_SIPROLAB_G729A             0x0134 /* Sipro Lab Telecom Inc. */

WAVE_FORMAT_SIPROLAB_KELVIN            0x0135 /* Sipro Lab Telecom Inc. */

WAVE_FORMAT_VOICEAGE_AMR               0x0136 /* VoiceAge Corp. */

WAVE_FORMAT_G726ADPCM                  0x0140 /* Dictaphone Corporation */

WAVE_FORMAT_DICTAPHONE_CELP68          0x0141 /* Dictaphone Corporation */

WAVE_FORMAT_DICTAPHONE_CELP54          0x0142 /* Dictaphone Corporation */

WAVE_FORMAT_QUALCOMM_PUREVOICE         0x0150 /* Qualcomm, Inc. */

WAVE_FORMAT_QUALCOMM_HALFRATE          0x0151 /* Qualcomm, Inc. */

WAVE_FORMAT_TUBGSM                     0x0155 /* Ring Zero Systems, Inc. */

WAVE_FORMAT_MSAUDIO1                   0x0160 /* Microsoft Corporation */

WAVE_FORMAT_WMAUDIO2                   0x0161 /* Microsoft Corporation */

WAVE_FORMAT_WMAUDIO3                   0x0162 /* Microsoft Corporation */

WAVE_FORMAT_WMAUDIO_LOSSLESS           0x0163 /* Microsoft Corporation */

WAVE_FORMAT_WMASPDIF                   0x0164 /* Microsoft Corporation */

WAVE_FORMAT_UNISYS_NAP_ADPCM           0x0170 /* Unisys Corp. */

WAVE_FORMAT_UNISYS_NAP_ULAW            0x0171 /* Unisys Corp. */

WAVE_FORMAT_UNISYS_NAP_ALAW            0x0172 /* Unisys Corp. */

WAVE_FORMAT_UNISYS_NAP_16K             0x0173 /* Unisys Corp. */

WAVE_FORMAT_SYCOM_ACM_SYC008           0x0174 /* SyCom Technologies */

WAVE_FORMAT_SYCOM_ACM_SYC701_G726L     0x0175 /* SyCom Technologies */

WAVE_FORMAT_SYCOM_ACM_SYC701_CELP54    0x0176 /* SyCom Technologies */

WAVE_FORMAT_SYCOM_ACM_SYC701_CELP68    0x0177 /* SyCom Technologies */

WAVE_FORMAT_KNOWLEDGE_ADVENTURE_ADPCM  0x0178 /* Knowledge Adventure, Inc. */

WAVE_FORMAT_FRAUNHOFER_IIS_MPEG2_AAC   0x0180 /* Fraunhofer IIS */

WAVE_FORMAT_DTS_DS                     0x0190 /* Digital Theatre Systems, Inc. */

WAVE_FORMAT_CREATIVE_ADPCM             0x0200 /* Creative Labs, Inc */

WAVE_FORMAT_CREATIVE_FASTSPEECH8       0x0202 /* Creative Labs, Inc */

WAVE_FORMAT_CREATIVE_FASTSPEECH10      0x0203 /* Creative Labs, Inc */

WAVE_FORMAT_UHER_ADPCM                 0x0210 /* UHER informatic GmbH */

WAVE_FORMAT_ULEAD_DV_AUDIO             0x0215 /* Ulead Systems, Inc. */

WAVE_FORMAT_ULEAD_DV_AUDIO_1           0x0216 /* Ulead Systems, Inc. */

WAVE_FORMAT_QUARTERDECK                0x0220 /* Quarterdeck Corporation */

WAVE_FORMAT_ILINK_VC                   0x0230 /* I-link Worldwide */

WAVE_FORMAT_RAW_SPORT                  0x0240 /* Aureal Semiconductor */

WAVE_FORMAT_ESST_AC3                   0x0241 /* ESS Technology, Inc. */

WAVE_FORMAT_GENERIC_PASSTHRU           0x0249

WAVE_FORMAT_IPI_HSX                    0x0250 /* Interactive Products, Inc. */

WAVE_FORMAT_IPI_RPELP                  0x0251 /* Interactive Products, Inc. */

WAVE_FORMAT_CS2                        0x0260 /* Consistent Software */

WAVE_FORMAT_SONY_SCX                   0x0270 /* Sony Corp. */

WAVE_FORMAT_SONY_SCY                   0x0271 /* Sony Corp. */

WAVE_FORMAT_SONY_ATRAC3                0x0272 /* Sony Corp. */

WAVE_FORMAT_SONY_SPC                   0x0273 /* Sony Corp. */

WAVE_FORMAT_TELUM_AUDIO                0x0280 /* Telum Inc. */

WAVE_FORMAT_TELUM_IA_AUDIO             0x0281 /* Telum Inc. */

WAVE_FORMAT_NORCOM_VOICE_SYSTEMS_ADPCM 0x0285 /* Norcom Electronics Corp. */

WAVE_FORMAT_FM_TOWNS_SND               0x0300 /* Fujitsu Corp. */

WAVE_FORMAT_MICRONAS                   0x0350 /* Micronas Semiconductors, Inc. */

WAVE_FORMAT_MICRONAS_CELP833           0x0351 /* Micronas Semiconductors, Inc. */

WAVE_FORMAT_BTV_DIGITAL                0x0400 /* Brooktree Corporation */

WAVE_FORMAT_INTEL_MUSIC_CODER          0x0401 /* Intel Corp. */

WAVE_FORMAT_INDEO_AUDIO                0x0402 /* Ligos */

WAVE_FORMAT_QDESIGN_MUSIC              0x0450 /* QDesign Corporation */

WAVE_FORMAT_ON2_VP7_AUDIO              0x0500 /* On2 Technologies */

WAVE_FORMAT_ON2_VP6_AUDIO              0x0501 /* On2 Technologies */

WAVE_FORMAT_VME_VMPCM                  0x0680 /* AT&T Labs, Inc. */

WAVE_FORMAT_TPC                        0x0681 /* AT&T Labs, Inc. */

WAVE_FORMAT_LIGHTWAVE_LOSSLESS         0x08AE /* Clearjump */

WAVE_FORMAT_OLIGSM                     0x1000 /* Ing C. Olivetti & C., S.p.A. */

WAVE_FORMAT_OLIADPCM                   0x1001 /* Ing C. Olivetti & C., S.p.A. */

WAVE_FORMAT_OLICELP                    0x1002 /* Ing C. Olivetti & C., S.p.A. */

WAVE_FORMAT_OLISBC                     0x1003 /* Ing C. Olivetti & C., S.p.A. */

WAVE_FORMAT_OLIOPR                     0x1004 /* Ing C. Olivetti & C., S.p.A. */

WAVE_FORMAT_LH_CODEC                   0x1100 /* Lernout & Hauspie */

WAVE_FORMAT_LH_CODEC_CELP              0x1101 /* Lernout & Hauspie */

WAVE_FORMAT_LH_CODEC_SBC8              0x1102 /* Lernout & Hauspie */

WAVE_FORMAT_LH_CODEC_SBC12             0x1103 /* Lernout & Hauspie */

WAVE_FORMAT_LH_CODEC_SBC16             0x1104 /* Lernout & Hauspie */

WAVE_FORMAT_NORRIS                     0x1400 /* Norris Communications, Inc. */

WAVE_FORMAT_ISIAUDIO_2                 0x1401 /* ISIAudio */

WAVE_FORMAT_SOUNDSPACE_MUSICOMPRESS    0x1500 /* AT&T Labs, Inc. */

WAVE_FORMAT_MPEG_ADTS_AAC              0x1600 /* Microsoft Corporation */

WAVE_FORMAT_MPEG_RAW_AAC               0x1601 /* Microsoft Corporation */

WAVE_FORMAT_MPEG_LOAS                  0x1602 /* Microsoft Corporation (MPEG-4 Audio Transport Streams (LOAS/LATM) */

WAVE_FORMAT_NOKIA_MPEG_ADTS_AAC        0x1608 /* Microsoft Corporation */

WAVE_FORMAT_NOKIA_MPEG_RAW_AAC         0x1609 /* Microsoft Corporation */

WAVE_FORMAT_VODAFONE_MPEG_ADTS_AAC     0x160A /* Microsoft Corporation */

WAVE_FORMAT_VODAFONE_MPEG_RAW_AAC      0x160B /* Microsoft Corporation */

WAVE_FORMAT_MPEG_HEAAC                 0x1610 /* Microsoft Corporation (MPEG-2 AAC or MPEG-4 HE-AAC v1/v2 streams with any payload (ADTS, ADIF, LOAS/LATM, RAW). Format block includes MP4 AudioSpecificConfig() -- see HEAACWAVEFORMAT below */

WAVE_FORMAT_VOXWARE_RT24_SPEECH        0x181C /* Voxware Inc. */

WAVE_FORMAT_SONICFOUNDRY_LOSSLESS      0x1971 /* Sonic Foundry */

WAVE_FORMAT_INNINGS_TELECOM_ADPCM      0x1979 /* Innings Telecom Inc. */

WAVE_FORMAT_LUCENT_SX8300P             0x1C07 /* Lucent Technologies */

WAVE_FORMAT_LUCENT_SX5363S             0x1C0C /* Lucent Technologies */

WAVE_FORMAT_CUSEEME                    0x1F03 /* CUSeeMe */

WAVE_FORMAT_NTCSOFT_ALF2CM_ACM         0x1FC4 /* NTCSoft */

WAVE_FORMAT_DVM                        0x2000 /* FAST Multimedia AG */

WAVE_FORMAT_DTS2                       0x2001

WAVE_FORMAT_MAKEAVIS                   0x3313

WAVE_FORMAT_DIVIO_MPEG4_AAC            0x4143 /* Divio, Inc. */

WAVE_FORMAT_NOKIA_ADAPTIVE_MULTIRATE   0x4201 /* Nokia */

WAVE_FORMAT_DIVIO_G726                 0x4243 /* Divio, Inc. */

WAVE_FORMAT_LEAD_SPEECH                0x434C /* LEAD Technologies */

WAVE_FORMAT_LEAD_VORBIS                0x564C /* LEAD Technologies */

WAVE_FORMAT_WAVPACK_AUDIO              0x5756 /* xiph.org */

WAVE_FORMAT_OGG_VORBIS_MODE_1          0x674F /* Ogg Vorbis */

WAVE_FORMAT_OGG_VORBIS_MODE_2          0x6750 /* Ogg Vorbis */

WAVE_FORMAT_OGG_VORBIS_MODE_3          0x6751 /* Ogg Vorbis */

WAVE_FORMAT_OGG_VORBIS_MODE_1_PLUS     0x676F /* Ogg Vorbis */

WAVE_FORMAT_OGG_VORBIS_MODE_2_PLUS     0x6770 /* Ogg Vorbis */

WAVE_FORMAT_OGG_VORBIS_MODE_3_PLUS     0x6771 /* Ogg Vorbis */

WAVE_FORMAT_3COM_NBX                   0x7000 /* 3COM Corp. */

WAVE_FORMAT_FAAD_AAC                   0x706D

WAVE_FORMAT_AMR_NB                     0x7361 /* AMR Narrowband */

WAVE_FORMAT_AMR_WB                     0x7362 /* AMR Wideband */

WAVE_FORMAT_AMR_WP                     0x7363 /* AMR Wideband Plus */

WAVE_FORMAT_GSM_AMR_CBR                0x7A21 /* GSMA/3GPP */

WAVE_FORMAT_GSM_AMR_VBR_SID            0x7A22 /* GSMA/3GPP */

WAVE_FORMAT_COMVERSE_INFOSYS_G723_1    0xA100 /* Comverse Infosys */

WAVE_FORMAT_COMVERSE_INFOSYS_AVQSBC    0xA101 /* Comverse Infosys */

WAVE_FORMAT_COMVERSE_INFOSYS_SBC       0xA102 /* Comverse Infosys */

WAVE_FORMAT_SYMBOL_G729_A              0xA103 /* Symbol Technologies */

WAVE_FORMAT_VOICEAGE_AMR_WB            0xA104 /* VoiceAge Corp. */

WAVE_FORMAT_INGENIENT_G726             0xA105 /* Ingenient Technologies, Inc. */

WAVE_FORMAT_MPEG4_AAC                  0xA106 /* ISO/MPEG-4 */

WAVE_FORMAT_ENCORE_G726                0xA107 /* Encore Software */

WAVE_FORMAT_ZOLL_ASAO                  0xA108 /* ZOLL Medical Corp. */

WAVE_FORMAT_SPEEX_VOICE                0xA109 /* xiph.org */

WAVE_FORMAT_VIANIX_MASC                0xA10A /* Vianix LLC */

WAVE_FORMAT_WM9_SPECTRUM_ANALYZER      0xA10B /* Microsoft */

WAVE_FORMAT_WMF_SPECTRUM_ANAYZER       0xA10C /* Microsoft */

WAVE_FORMAT_GSM_610                    0xA10D

WAVE_FORMAT_GSM_620                    0xA10E

WAVE_FORMAT_GSM_660                    0xA10F

WAVE_FORMAT_GSM_690                    0xA110

WAVE_FORMAT_GSM_ADAPTIVE_MULTIRATE_WB  0xA111

WAVE_FORMAT_POLYCOM_G722               0xA112 /* Polycom */

WAVE_FORMAT_POLYCOM_G728               0xA113 /* Polycom */

WAVE_FORMAT_POLYCOM_G729_A             0xA114 /* Polycom */

WAVE_FORMAT_POLYCOM_SIREN              0xA115 /* Polycom */

WAVE_FORMAT_GLOBAL_IP_ILBC             0xA116 /* Global IP */

WAVE_FORMAT_RADIOTIME_TIME_SHIFT_RADIO 0xA117 /* RadioTime */

WAVE_FORMAT_NICE_ACA                   0xA118 /* Nice Systems */

WAVE_FORMAT_NICE_ADPCM                 0xA119 /* Nice Systems */

WAVE_FORMAT_VOCORD_G721                0xA11A /* Vocord Telecom */

WAVE_FORMAT_VOCORD_G726                0xA11B /* Vocord Telecom */

WAVE_FORMAT_VOCORD_G722_1              0xA11C /* Vocord Telecom */

WAVE_FORMAT_VOCORD_G728                0xA11D /* Vocord Telecom */

WAVE_FORMAT_VOCORD_G729                0xA11E /* Vocord Telecom */

WAVE_FORMAT_VOCORD_G729_A              0xA11F /* Vocord Telecom */

WAVE_FORMAT_VOCORD_G723_1              0xA120 /* Vocord Telecom */

WAVE_FORMAT_VOCORD_LBC                 0xA121 /* Vocord Telecom */

WAVE_FORMAT_NICE_G728                  0xA122 /* Nice Systems */

WAVE_FORMAT_FRACE_TELECOM_G729         0xA123 /* France Telecom */

WAVE_FORMAT_CODIAN                     0xA124 /* CODIAN */

WAVE_FORMAT_FLAC                       0xF1AC /* flac.sourceforge.net */

WAVE_FORMAT_EXTENSIBLE                 0xFFFE /* Microsoft */

nChannels

存放音频的声道数量,1表示单声道,2表示双声道立体声。

nSamplesPerSec

存放音频的采样频率,单位赫兹。

如果wFormatTag参数为WAVE_FORMAT_PCM宏,本参数可以为8000、11025、22050、44100。

对于非PCM格式请根据厂商的说明设置本参数。

nAvgBytesPerSec

存放音频的平均数据传输速率,单位字节每秒。这个值对于创建缓冲大小是很有用的。

如果wFormatTag参数为WAVE_FORMAT_PCM宏,本参数应与nSamplesPerSec参数相同。

对于非PCM格式请根据厂商的说明设置本参数。

nBlockAlign

存放音频的采样单元的大小,也就是每一次采样到的音频数据单元的大小,单位字节,计算方法:声道数量×采样位数÷8。

如果wFormatTag参数为WAVE_FORMAT_PCM宏,本参数为(nChannels * wBitsPerSample) / 8。

对于非PCM格式请根据厂商的说明设置本参数。

wBitsPerSample

存放音频的采样位数,单位比特位。

如果wFormatTag参数为WAVE_FORMAT_PCM宏,本参数可以为8、16。

对于非PCM格式请根据厂商的说明设置本参数。

cbSize

存放音频的额外信息的大小,单位字节,额外信息添加在WAVEFORMATEX结构的结尾。

这个信息可以作为非PCM格式的wFormatTag额外属性。

如果wFormatTag参数指定的音频格式不需要额外的信息,此值必需为0。

如果wFormatTag参数为WAVE_FORMAT_PCM宏,本参数无意义。

其他说明

一个使用额外信息的例子,微软自适应音频脉冲编码(ms-adpcm)格式,对于ms-adpcm的wformattag参数为WAVE_FORMAT_ADPCM宏。cbSize参数通常会被设置为2(16位)。存储ms-adpcm格式的额外信息系数对编码和波形音频数据解码所需。

 

 

4.11.2   WAVEHDR(未完成)

结构体名称

WAVEHDR

头文件

#include <mmeapi.h>

结构体说明

音频数据块结构体,用于存放音频输入设备和播放设备的一个音频数据块。

相关函数

waveInPrepareHeader()、Func2()、Func3()…

结构体声明

struct WAVEHDR

{

    LPSTR       lpData;                 /* pointer to locked data buffer */

    DWORD       dwBufferLength;         /* length of data buffer */

    DWORD       dwBytesRecorded;        /* used for input only */

    DWORD_PTR   dwUser;                 /* for client's use */

    DWORD       dwFlags;                /* assorted flags (see defines) */

    DWORD       dwLoops;                /* loop control counter */

    struct WAVEHDR * lpNext;     /* reserved for driver */

    DWORD_PTR   reserved;               /* reserved for driver */

};

成员变量

lpData

存放音频数据块的实际数据数组的内存指针。

dwBufferLength

存放音频数据块的实际数据数组的内存长度,单位字节。

dwBytesRecorded

存放在音频数据块的实际数据数组中,实际数据的内存长度,单位字节。

dwUser

存放音频的额外信息。

如果音频的格式为PCM格式,本参数无意义。

dwFlags

存放音频数据块的控制标记,可以为(用'|'选零至多个):

WHDR_DONE宏(0x0001)Set by the device driver to indicate that it is finished with the buffer and is returning it to the application.

WHDR_PREPARED宏(0x0002)Set by Windows to indicate that the buffer has been prepared with the waveInPrepareHeader or waveOutPrepareHeader function.

WHDR_BEGINLOOP宏(0x0004)This buffer is the first buffer in a loop. This flag is used only with output buffers.

WHDR_ENDLOOP宏(0x0008)This buffer is the last buffer in a loop. This flag is used only with output buffers.

WHDR_INQUEUE宏(0x0010)Set by Windows to indicate that the buffer is queued for playback.

dwLoops

存放播放循环次数,本参数只针对播放设备有效,音频输入设备无意义。

lpNext

本参数无意义。

reserved

本参数无意义。

其他说明

 

 

 

5   errno错误码

注意:数值在不同的操作系统上可能不一样。

 

EPERM            (1) /* Operation not permitted */

ENOENT           (2) /* No such file or directory */

ESRCH            (3) /* No such process */

EINTR            (4) /* Interrupted system call */

EIO              (5) /* Input/output error */

ENXIO            (6) /* No such device or address */

E2BIG            (7) /* Argument list too long */

ENOEXEC          (8) /* Exec format error */

EBADF            (9) /* Bad file descriptor */

ECHILD           (10)/* No child processes */

EDEADLK          (11)/* Resource deadlock avoided */

ENOMEM           (12)/* Cannot allocate memory */

EACCES           (13)/* Permission denied */

EFAULT           (14)/* Bad address */

ENOTBLK          (15)/* Block device required */

EBUSY            (16)/* Device or resource busy */

EEXIST           (17)/* File exists */

EXDEV            (18)/* Invalid cross-device link */

ENODEV           (19)/* No such device */

ENOTDIR          (20)/* Not a directory */

EISDIR           (21)/* Is a directory */

EINVAL           (22)/* Invalid argument */

EMFILE           (24)/* Too many open files */

ENFILE           (23)/* Too many open files in system */

ENOTTY           (25)/* Inappropriate ioctl for device */

ETXTBSY          (26)/* Text file busy */

EFBIG            (27)/* File too large */

ENOSPC           (28)/* No space left on device */

ESPIPE           (29)/* Illegal seek */

EROFS            (30)/* Read-only file system */

EMLINK           (31)/* Too many links */

EPIPE            (32)/* Broken pipe */

EDOM             (33)/* Numerical argument out of domain */

ERANGE           (34)/* Numerical result out of range */

EAGAIN           (35)/* Resource temporarily unavailable */

EWOULDBLOCK   EAGAIN /* Operation would block */

EINPROGRESS      (36)/* Operation now in progress */

EALREADY         (37)/* Operation already in progress */

ENOTSOCK         (38)/* Socket operation on non-socket */

EDESTADDRREQ     (39)/* Destination address required */

EMSGSIZE         (40)/* Message too long */

EPROTOTYPE       (41)/* Protocol wrong type for socket */

ENOPROTOOPT      (42)/* Protocol not available */

EPROTONOSUPPORT  (43)/* Protocol not supported */

ESOCKTNOSUPPORT  (44)/* Socket type not supported */

EOPNOTSUPP       (45)/* Operation not supported */

EPFNOSUPPORT     (46)/* Protocol family not supported */

EAFNOSUPPORT     (47)/* Address family not supported by protocol */

EADDRINUSE       (48)/* Address already in use */

EADDRNOTAVAIL    (49)/* Cannot assign requested address */

ENETDOWN         (50)/* Network is down */

ENETUNREACH      (51)/* Network is unreachable */

ENETRESET        (52)/* Network dropped connection on reset */

ECONNABORTED     (53)/* Software caused connection abort */

ECONNRESET       (54)/* Connection reset by peer */

ENOBUFS          (55)/* No buffer space available */

EISCONN          (56)/* Transport endpoint is already connected */

ENOTCONN         (57)/* Transport endpoint is not connected */

ESHUTDOWN        (58)/* Cannot send after transport endpoint shutdown */

ETOOMANYREFS     (59)/* Too many references: cannot splice */

ETIMEDOUT        (60)/* Connection timed out */

ECONNREFUSED     (61)/* Connection refused */

ELOOP            (62)/* Too many levels of symbolic links */

ENAMETOOLONG     (63)/* File name too long */

EHOSTDOWN        (64)/* Host is down */

EHOSTUNREACH     (65)/* No route to host */

ENOTEMPTY        (66)/* Directory not empty */

EPROCLIM         (67)/* Too many processes */

EUSERS           (68)/* Too many users */

EDQUOT           (69)/* Disk quota exceeded */

ESTALE           (70)/* Stale NFS file handle */

EREMOTE          (71)/* Object is remote */

EBADRPC          (72)/* RPC struct is bad */

ERPCMISMATCH     (73)/* RPC version wrong */

EPROGUNAVAIL     (74)/* RPC program not available */

EPROGMISMATCH    (75)/* RPC program version wrong */

EPROCUNAVAIL     (76)/* RPC bad procedure for program */

ENOLCK           (77)/* No locks available */

ENOSYS           (78)/* Function not implemented */

EFTYPE           (79)/* Inappropriate file type or format */

EAUTH            (80)/* Authentication error */

ENEEDAUTH        (81)/* Need authenticator */

ELAST            (81)/* Must be equal largest errno */

EBACKGROUND      (100)/* Inappropriate operation for background process */

EDIED            (101)/* Translator died */

ED               (102)/* ? */

EGREGIOUS        (103)/* You really blew it this time */

EIEIO            (104)/* Computer bought the farm */

EGRATUITOUS      (105)/* Gratuitous error */

EILSEQ           (106)/* Invalid or incomplete multibyte or wide character */

EBADMSG          (107)/* Bad message */

EIDRM            (108)/* Identifier removed */

EMULTIHOP        (109)/* Multihop attempted */

ENODATA          (110)/* No data available */

ENOLINK          (111)/* Link has been severed */

ENOMSG           (112)/* No message of desired type */

ENOSR            (113)/* Out of streams resources */

ENOSTR           (114)/* Device not a stream */

EOVERFLOW        (115)/* Value too large for defined data type */

EPROTO           (116)/* Protocol error */

ETIME            (117)/* Timer expired */

ECANCELED        (118)/* Operation canceled */

ENOTSUP          (118)/* Not supported */

6   转义字符

字符

进制

十六

进制

对应按键

名称

Windows控制台下输出效果

例子

\a

7

0x7

响铃符(BEL)

在支持的设备(终端)上鸣响一声

 

\b

8

0x8

Backspace

退格

退格符(BS)

光标在当前位置左移一格

 

\f

12

0xC

分页符(FF)

打印机跳到下一页打印

 

\n

10

0xA

Enter

回车

回车换行符(LF)

光标跳到下一行行首

 

\r

13

0xD

回车符(CR)

光标回到当前行首

printf("123456\rABC");

屏幕上输出:ABC456

\t

9

0x9

Tab

制表

水平制表符(HT)

光标水平跳到下一个制表位

 

\v

11

0xB

垂直制表符(VT)

不支持

 

\?

63

0x3F

?

问号

 

打印一个‘?’

正确:printf("\?");

printf("?");

\\

92

0x5C

\

反斜杠

 

打印一个‘\’

正确:printf("\\");

错误:printf("\");

\'

39

0x27

'

单引号

 

打印一个‘'’

正确:printf("\'");

错误:printf("'");

\"

34

0x22

"

双引号

 

打印一个‘"’

正确:printf("\"");

错误:printf(""");

\0

0

0x0

NULL

空字符

 

字符串结束标记

printf("abc\0efg");

输出:abc

\xhh

       

对应一个十六进制ASCII码值的字符

'\x0A' 相当于 '\n'

'\x1B' 相当于 '\e'

正确:printf("\xA");

printf("\x00a");

错误:printf("\x100");

printf("\x");

\bbb

       

对应一个八进制ASCII码值的字符

'\101' 相当于 'A'

'\033' 相当于 '\e'

printf("\071");

输出:9

printf("\1013");

输出:A3

printf("\778");

输出:?8

           

 

\e

27

0x1B

Esc

退出

操作符

不支持

 

\e[0m

       

不支持

 

\e[1m

       

不支持

 

\e[4m

       

不支持

 

\e[5m

       

不支持

 

\e[7m

       

不支持

 

\e[8m

       

不支持

 

\e[30m

       

不支持

 

\e[31m

       

不支持

 

\e[32m

       

不支持

 

\e[33m

       

不支持

 

\e[34m

       

不支持

 

\e[35m

       

不支持

 

\e[36m

       

不支持

 

\e[37m

       

不支持

 

\e[40m

       

不支持

 

\e[41m

       

不支持

 

\e[42m

       

不支持

 

\e[43m

       

不支持

 

\e[44m

       

不支持

 

\e[45m

       

不支持

 

\e[46m

       

不支持

 

\e[47m

       

不支持

 

\e[nA

       

不支持

 

\e[nB

       

不支持

 

\e[nC

       

不支持

 

\e[nD

       

不支持

 

\e[y;xH

       

不支持

 

\e[2J

       

不支持

 

\e[K

       

不支持

 

\e[s

       

不支持

 

\e[u

       

不支持

 

\e[?25l

       

不支持

 

\e[?25h

       

不支持

 

 

7   常量类型

与变量类似,常量实际上也有多种细分的类型。在C语言中变量需要先定义类型才能在语句中使用,而常量有默认的类型。

数值末尾不添加类型说明符的整型常量默认为是int型的。超出int型范围的整型常量,默认为是long型的。也就是说,整型常量1234一定是int类型的,而整型常量123467(超过了32767)在int型最大值是32767的系统中是long型的。

数值末尾不添加类型说明符的浮点型常量默认为是double型的。也就是说,任意一个浮点型常量,不论是小数形式表示的,还是指数形式表示的,只要数的末尾没有加类型说明符F(或者f),一律被编译程序当成是double型的常量。

如果默认的类型不合适,可以在常量的末尾加上类型说明符。

对于整型常量,可在末尾加U表示无符号整型或加L表示长整型;在整型常量的开头,还可加上进制说明符,以0开头表示八进制整数,0x或0X开头表示十六进制整数。

对浮点型常量,在末尾可加F(或f),表示该常量是单精度浮点型。

(1)数值常量的存储类型(初学时不必看)

与基本类型变量一样,常量也分为三大类型:字符型、整型和浮点型。除了字符型常量比较简单外,常量根据在内存中存储方式(参见本章提高部分)的不同,可细分为很多类型。所有常量的(不同存储)类型请参见表3-2:

 

说明:说明常量类型的字符U、L、F都可以用小写字符u、l、f,多个类型符号连在一起书写时,符号之间的顺序是任意的。比如,123UL、 123LU、123ul都是一样的。

总之,数值末尾不添加类型说明符的整型常量(比如123)默认是int型的,但是该数的值如果超出了int型的范围,那么该数默认是long型的;不添加类型说明符的实型常量(比如123.34)一定是double型的。

其他强制指定的常量类型一般很少使用。强制指定常量类型常常是为了减少程序运行时的类型转换。比如在变量定义时,使用“float  x = 123.3F;”就比使用“floatx=123.3 ;”要好,前者避免了一次不必要的运行时的类型转换。

(2)数值常量的多种机外书写形式(初学时不必看)

上表中对常量的分类,是一种本质上的分类,因为上表中各种不同的常量在内存中的存储方式不同(参见本章提高部分)。但是,常量还可以根据在源程序中的书写(或输入输出中的)形式来进行分类。

上一章已经讲过,浮点型常量有两种书写形式:十进制小数形式和十进制指数形式。如,小数形式123.45和指数形式1.2345e2,在内存中其实是具有完全相同存储形式的浮点数(默认为double型的)。它们仅仅是在程序中(或输入输出时)的表现形式不同而已。再加上不同的存储形式(double型与float型),数值大小相同(取值不超过float型范围)的浮点型常量一共有4种机外表示形式:123.45、1.2345e2、123.45f、1.2345e2f。

整型常量在C语言源程序中(或程序运行的输入输出时),除了可以用十进制形式书写(或输入输出)之外,还可以使用八进制和十六进制形式来书写(或输入输出)。

八进制整型常量:常量中只包含数字0~7,用0开头表示的数都是八进制整型常量。比如,034、065、–013。

十六进制整型常量:常量中包含数字0~9和字符a~f(或者用A~F),以0x(或0X)开头的,都是十六进制整型常量。比如,0x3d、 0XEF、–0x8a等。

同一个十进制整数123(默认为int型),还可以用八进制整数0173来表示,或者用十六进制整数0x7B来表示。它们也仅仅是在程序中(或输入输出时)的表现形式不同而已,在计算机内部,它们是形式完全相同的二进制整数0000000001111011(假设int型占2个字节)。再加上不同的存储形式(int、long、unsigned、unsigned long),数值大小相同且值不超过int范围的整型常量一共有3×4=12种机外表示形式:123、123L、123U、123UL、0173、0173L、0173U、0173UL、0x7B、0x7BL、0x7BU、0x7BUL。

八进制和十六进制整数主要应用在系统编程和嵌入式编程方面(主要原因在于:机外形式的八进制和十六进制整数与机内形式的二进制整数之间很容易进行相互转换)。如果一个二进制整数中的n个位分别用来表示n个开关的状态,在用C语言编程时,那么就最好使用无符号的八进制整数(或无符号十六进制的整数)来表示此二进制整数,C语言的源程序中无法直接使用二进制整数。

8   ASCII码字符表

二进制

八进制

十进制

十六进制

对应按键

缩写/字符

解释

0000 0000

000

0

00

 

NUL (null)

空字符

0000 0001

001

1

01

 

SOH (start of headline)

标题开始

0000 0010

002

2

02

 

STX (start of text)

正文开始

0000 0011

003

3

03

 

ETX (end of text)

正文结束

0000 0100

004

4

04

 

EOT (end of transmission)

传输结束

0000 0101

005

5

05

 

ENQ (enquiry)

请求

0000 0110

006

6

06

 

ACK (acknowledge)

收到通知

0000 0111

007

7

07

 

BEL (bell)

响铃

0000 1000

010

8

08

 

BS (backspace)

退格

0000 1001

011

9

09

Tab制表

HT (horizontal tab)

水平制表符

0000 1010

012

10

0A

Enter回车

LF (NL line feed, new line)

换行键

0000 1011

013

11

0B

 

VT (vertical tab)

垂直制表符

0000 1100

014

12

0C

 

FF (NP form feed, new page)

换页键

0000 1101

015

13

0D

 

CR (carriage return)

回车键

0000 1110

016

14

0E

 

SO (shift out)

不用切换

0000 1111

017

15

0F

 

SI (shift in)

启用切换

0001 0000

020

16

10

 

DLE (data link escape)

数据链路转义

0001 0001

021

17

11

 

DC1 (device control 1)

设备控制1

0001 0010

022

18

12

 

DC2 (device control 2)

设备控制2

0001 0011

023

19

13

 

DC3 (device control 3)

设备控制3

0001 0100

024

20

14

 

DC4 (device control 4)

设备控制4

0001 0101

025

21

15

 

NAK (negative acknowledge)

拒绝接收

0001 0110

026

22

16

 

SYN (synchronous idle)

同步空闲

0001 0111

027

23

17

 

ETB (end of trans. block)

传输块结束

0001 1000

030

24

18

 

CAN (cancel)

取消

0001 1001

031

25

19

 

EM (end of medium)

介质中断

0001 1010

032

26

1A

 

SUB (substitute)

替补

0001 1011

033

27

1B

 

ESC (escape)

换码(溢出)

0001 1100

034

28

1C

 

FS (file separator)

文件分割符

0001 1101

035

29

1D

 

GS (group separator)

分组符

0001 1110

036

30

1E

 

RS (record separator)

记录分离符

0001 1111

037

31

1F

 

US (unit separator)

单元分隔符

0010 0000

040

32

20

Space空格

  (space)

空格

0010 0001

041

33

21

 

!

 

0010 0010

042

34

22

 

"

 

0010 0011

043

35

23

 

#

 

0010 0100

044

36

24

 

$

 

0010 0101

045

37

25

 

%

 

0010 0110

046

38

26

 

&

 

0010 0111

047

39

27

 

'

 

0010 1000

050

40

28

 

(

 

0010 1001

051

41

29

 

)

 

0010 1010

052

42

2A

 

*

 

0010 1011

053

43

2B

 

+

 

0010 1100

054

44

2C

 

,

 

0010 1101

055

45

2D

 

-

 

0010 1110

056

46

2E

 

.

 

0010 1111

057

47

2F

 

/

 

0011 0000

060

48

30

 

0

 

0011 0001

061

49

31

 

1

 

0011 0010

062

50

32

 

2

 

0011 0011

063

51

33

 

3

 

0011 0100

064

52

34

 

4

 

0011 0101

065

53

35

 

5

 

0011 0110

066

54

36

 

6

 

0011 0111

067

55

37

 

7

 

0011 1000

070

56

38

 

8

 

0011 1001

071

57

39

 

9

 

0011 1010

072

58

3A

 

:

 

0011 1011

073

59

3B

 

;

 

0011 1100

074

60

3C

 

 

0011 1101

075

61

3D

 

=

 

0011 1110

076

62

3E

 

 

0011 1111

077

63

3F

 

?

 

0100 0000

100

64

40

 

@

 

0100 0001

101

65

41

 

A

 

0100 0010

102

66

42

 

B

 

0100 0011

103

67

43

 

C

 

0100 0100

104

68

44

 

D

 

0100 0101

105

69

45

 

E

 

0100 0110

106

70

46

 

F

 

0100 0111

107

71

47

 

G

 

0100 1000

110

72

48

 

H

 

0100 1001

111

73

49

 

I

 

0100 1010

112

74

4A

 

J

 

0100 1011

113

75

4B

 

K

 

0100 1100

114

76

4C

 

L

 

0100 1101

115

77

4D

 

M

 

0100 1110

116

78

4E

 

N

 

0100 1111

117

79

4F

 

O

 

0101 0000

120

80

50

 

P

 

0101 0001

121

81

51

 

Q

 

0101 0010

122

82

52

 

R

 

0101 0011

123

83

53

 

S

 

0101 0100

124

84

54

 

T

 

0101 0101

125

85

55

 

U

 

0101 0110

126

86

56

 

V

 

0101 0111

127

87

57

 

W

 

0101 1000

130

88

58

 

X

 

0101 1001

131

89

59

 

Y

 

0101 1010

132

90

5A

 

Z

 

0101 1011

133

91

5B

 

[

 

0101 1100

134

92

5C

 

\

 

0101 1101

135

93

5D

 

]

 

0101 1110

136

94

5E

 

^

 

0101 1111

137

95

5F

 

_

 

0110 0000

140

96

60

 

`

 

0110 0001

141

97

61

 

a

 

0110 0010

142

98

62

 

b

 

0110 0011

143

99

63

 

c

 

0110 0100

144

100

64

 

d

 

0110 0101

145

101

65

 

e

 

0110 0110

146

102

66

 

f

 

0110 0111

147

103

67

 

g

 

0110 1000

150

104

68

 

h

 

0110 1001

151

105

69

 

i

 

0110 1010

152

106

6A

 

j

 

0110 1011

153

107

6B

 

k

 

0110 1100

154

108

6C

 

l

 

0110 1101

155

109

6D

 

m

 

0110 1110

156

110

6E

 

n

 

0110 1111

157

111

6F

 

o

 

0111 0000

160

112

70

 

p

 

0111 0001

161

113

71

 

q

 

0111 0010

162

114

72

 

r

 

0111 0011

163

115

73

 

s

 

0111 0100

164

116

74

 

t

 

0111 0101

165

117

75

 

u

 

0111 0110

166

118

76

 

v

 

0111 0111

167

119

77

 

w

 

0111 1000

170

120

78

 

x

 

0111 1001

171

121

79

 

y

 

0111 1010

172

122

7A

 

z

 

0111 1011

173

123

7B

 

{

 

0111 1100

174

124

7C

 

|

 

0111 1101

175

125

7D

 

}

 

0111 1110

176

126

7E

 

~

 

0111 1111

177

127

7F

 

DEL (delete)

删除

 

posted @ 2014-01-26 17:26  赤勇玄心行天道  阅读(6584)  评论(2编辑  收藏  举报