函数功能:该函数将虚拟键消息转换为字符消息。字符消息被寄送到调用线程的消息队列里,当下一次线程调用函数GetMessage或PeekMessage时被读出。
函数原型:
BOOLTranslateMessage(
CONSTMSG*lpMsg //message information
);
参数
IpMsg:指向含有消息的MSG结构的指针,该结构里含有用函数GetMessage或PeekMessage从调用线程的消息队列里取得的消息信息。
返回值:如果消息被转换(即,字符消息被寄送到调用线程的消息队列里),返回非零值。如果消息是WM_KEYDOWN,WM_KEYUPWM_SYSKEYDOWN或WM_SYSKEYUP,返回非零值,不考虑转换。如果消息没被转换(即,字符消息没被寄送到调用线程的消息队列里),返回值是零。
备注:此函数不修改由参数IpMsg指向的消息。
WM_KEYDOWN和WM_KEYUP组合产生一个WM_CHAR或WM_DEADCHAR消息。
WM_SYSKEYDOWN和WM_SYSKEYUP组合产生一个WM_SYSCHAR或WM_SYSDEADCHAR消息。TranslateMessage为那些由键盘驱动器映射为ASCll字符的键产生WM_CHAR消息。
如果应用程序为其他用途处理虚拟键消息,不应调用TranslateMessage。例如,如果件TranslateAccelerator返回一个非零值,应用程序不应调用TranslateMessage。
WindowsCE:WindowsCE不支持扫描码或扩展键标志,因此,不支持由TranslateMessage产生的WM_CHAR消息中的IKeyData参数(IParam)取值16-24。
TranslateMessage只能用于转换调用GetMessage或PeekMessage接收的消息。
函数功能:该函数分发一个消息给窗口程序。通常消息从GetMessage函数获得。消息被分发到回调函数(过程函数),作用是消息传递给操作系统,然后操作系统去调用我们的回调函数,也就是说我们在窗体的过程函数中处理消息
函数原型:LONGDispatchMessage(CONST MSG*lpmsg);
参数:
lpmsg:指向含有消息的MSG结构的指针。
返回值:返回值是窗口程序返回的值。尽管返回值的含义依赖于被调度的消息,但返回值通常被忽略。
备注:MSG结构必须包含有效的消息值。如果参数lpmsg指向一个WM_TIMER消息,并且WM_TIMER消息的参数IParam不为NULL,则调用IParam指向的函数,而不是调用窗口程序。
CW2A将宽字符集(Unicode)转化为多字符集(ASCII)
CA2W就是反过来转换了
注意要利用USES_CONVERSION提前进行声明。
C: convert 转换
W: wide 广泛的
2: to 到
A ASCII; ASCII码
extern可以置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。另外,extern也可用来进行链接指定。
在一个源文件里定义了一个数组:char a[6];
在另外一个文件里用下列语句进行了声明:extern char *a;
请问,这样可以吗?
答案与分析:
1)、不可以,程序运行时会告诉你非法访问。原因在于,指向类型T的指针并不等价于类型T的数组。extern char *a声明的是一个指针变量而不是字符数组,因此与实际的定义不同,从而造成运行时非法访问。应该将声明改为extern char a[ ]。
2)、例子分析如下,如果a[] = "abcd",则外部变量a=0x12345678 (数组的起始地址),而*a是重新定义了一个指针变量a的地址可能是0x87654321,直接使用*a是错误的.
3)、这提示我们,在使用extern时候要严格对应声明时的格式,在实际编程中,这样的错误屡见不鲜。
4)、extern用在变量声明中常常有这样一个作用,你在*.c文件中声明了一个全局的变量,这个全局的变量如果要被引用,就放在*.h中并用extern来声明。
把一个班的学生姓名和成绩存放到一个结构数组中,寻找和输出最高分者。
#include<iostream>
#include<string>
using namespace std;
#define MAX 100
struct student
{
string name;
float score;
};
void main()
{
student stu[MAX];
int max=-1,n;
cout<<"请输入班级人数:";
int num;
cin>>num;
for(int i=1;i<=num;i++)
{
cout<<endl<<"请输入第"<<i<<"个人的姓名和分数:"<<endl;
cin>>stu[i-1].name>>stu[i-1].score;
if(max<stu[i-1].score)
{max=stu[i-1].score;n=i-1;}
}
cout<<"分数最高者为:"<<endl;
cout<<stu[n].name<<" 分数为: "<<stu[n].score<<endl;
}
#define MAX_PATH 256 宏定义,定义数组的大小;
ZeroMemory,是美国微软公司的软件开发包SDK中的一个宏。其作用,是用0来填充一块内存区域。
用法
声明
void ZeroMemory( PVOID Destination,SIZE_T Length);
参数
Destination :指向一块准备用0来填充的内存区域的开始地址。
Length :准备用0来填充的内存区域的大小,按字节来计算。
返回值
无
作用
ZeroMemory只是将指定的内存块清零。
使用结构前清零,而不让结构的成员数值具有不确定性,是一个好的编程习惯。
errno_t strncpy_s(
char *strDest,
size_t numberOfElements,
const char *strSource,
size_t count
);
strDest:Destination string.:目标字符串。
numberOfElements:The size of the destination string, incharacters.:目的地的大小的字符串,在字符。
strSource:Source string.源字符串。
Count:Number of characters to be copied, or _TRUNCATE.要复制的字符数,或_TRUNCATE
Locale:The locale to use.:语言环境使用。
typedefstruct _KEY_INFO_{
INT nVKcode; // 键值虚拟码例:VK_INSERT
TCHAR szVKName[SSN_NAMELEN]; // 键字符串例:VK_PAD_INSERT
TCHAR szVKDescID[SSN_NAMELEN]; // 键汉字描述字符串ID;因为资源在文本文件里所以ID也是字符串类型
TCHAR szVKDesc[SSN_NAMELEN]; // 键汉字描述字符串例:小键盘零
_KEY_INFO_()
{nVKcode=0;ZeroMemory(szVKName, sizeof(szVKName));ZeroMemory(szVKDescID,sizeof(szVKDescID));/*ZeroMemory(szVKDesc,sizeof(szVKDesc));*/};
_KEY_INFO_(INT code, const TCHAR*keyName, const TCHAR *keyDescID/*, constTCHAR *keyDesc=NULL*/)
{nVKcode=code;_tcsncpy_s(szVKName, _countof(szVKName),keyName, _TRUNCATE); _tcsncpy_s(szVKDescID,_countof(szVKDescID), keyDescID, _TRUNCATE); /*_tcsncpy_s(szVKDesc, _countof(szVKDesc), keyDesc,_TRUNCATE);*/};
}SSN_KEY_INFO, *PSSN_KEY_INFO;
第一个没参数的叫默认构造函数第二个叫带参数的构造函数
_KEY_INFO_()
{nVKcode=0;ZeroMemory(szVKName, sizeof(szVKName));ZeroMemory(szVKDescID,sizeof(szVKDescID));/*ZeroMemory(szVKDesc,sizeof(szVKDesc));*/};
_KEY_INFO_(INT code, const TCHAR*keyName, const TCHAR *keyDescID/*, constTCHAR *keyDesc=NULL*/)
{nVKcode=code;_tcsncpy_s(szVKName, _countof(szVKName),keyName, _TRUNCATE); _tcsncpy_s(szVKDescID,_countof(szVKDescID), keyDescID, _TRUNCATE); /*_tcsncpy_s(szVKDesc, _countof(szVKDesc), keyDesc,_TRUNCATE);*/};
的过程,如同给一个变量先赋一个默认值,然后在执行以下程序;
#define _countof(_Array) (sizeof(_Array)/ sizeof(_Array[0]))
size_t 类型定义在cstddef头文件中,该文件是C标准库的头文件stddef.h的C++版。它是一个与机器相关的unsigned类型,其大小足以保证存储内存中对象的大小。
结构体内部可以定义函数,来表示结构体的特点。
函数功能:该函数检取指定虚拟键的状态。该状态指定此键是UP状态,DOWN状态,还是被触发的(开关每次按下此键时进行切换)。
函数原型:SHORTGetKeyState(int nVirtKey);
函数:
nVrtKey:定义一虚拟键。若要求的虚拟键是字母或数字(A~Z,a~z或0~9),nVirtKey必须被置为相应字符的ASCII码值,对于其他的键,nVirtKey必须是一虚拟键码。若使用非英语键盘布局,则取值在ASCIIa~z和0~9的虚拟键被用于定义绝大多数的字符键。例如,对于德语键盘格式,值为ASCII0(OX4F)的虚拟键指的是"0"键,而VK_OEM_1指"带变音的0键"
返回值:返回值给出了给定虚拟键的状态,状态如下:
若高序位为1,则键处于DOWN状态,否则为UP状态。
若低序位为1,则键被触发。例如CAPSLOCK键,被找开时将被触发。若低序位置为0,则键被关闭,且不被触发。触发键在键盘上的指示灯,当键被触发时即亮,键不被触发时即灭。
备注:当给定线程从它的消息队列中读键消息时,该函数返回的键状态发生改变。该状态并不反映与硬件相关的中断级的状态。使用GetAsyncKeyState可获取这一信息。
Private Type KBDLLHOOKSTRUCT'这个是低级键盘钩子的索引值
vkCode As Long '虚拟按键码(1--254)
scanCode As Long '硬件按键扫描码
flags As Long '键按下:128 抬起:0
time As Long '消息时间戳间
dwExtraInfo As Long '额外信息
typedefstruct tagKBDLLHOOKSTRUCT {
DWORD vkCode;
DWORD scanCode;
DWORD flags;
DWORD time;
ULONG_PTR dwExtraInfo;
}KBDLLHOOKSTRUCT, FAR *LPKBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;
Constructs a container object.(构造一个容器对象);
multimap::multimap(STL/CLR)
first
Beginning of range to insert.(范围的开始插入。)
last
End of range to insert.(结束的范围来插入。)
pred
Ordering predicate for the controlled sequence.(控制顺序排列谓词。)
right
Object or range to insert.(要插入的对象或范围)
typedef multimap<_Kty, _Ty, _Pr, _Alloc> _Myt;
template<
class Key,
class Type,
class Traits = less<Key>,
class Allocator=allocator<pair <const Key, Type>>
>
class map
Key
The key data typeto be stored in the map.关键数据类型存储在地图上。
Type
The element datatype to be stored in the map.元素的数据类型可以存储在地图上。
Traits
Thetype that provides a function object that can compare two element values assort keys to determine their relative order in the map. This argument isoptional and the binary predicate less<Key> is thedefault value.
类型,提供了一个函数对象,可以比较两个元素值作为排序键,以确定其相对顺序在地图上。此参数是可选的,二元谓词少<KEY>是默认值。
Allocator
Thetype that represents the stored allocator object that encapsulates detailsabout the map's allocation and deallocation of memory. This argument isoptional and the default value is allocator<pair<constKey, Type>>.
类型表示存储分配器对象封装了有关地图的分配和释放内存的详细信息。此参数是可选的,默认值是分配器<的一双<constKey, TYPE>>。
Map以按键/数值对的形式存储数据,和数组非常相似,在数组中存在的索引,它们本身也是对象。
Map的接口
Map---实现Map
Map.Entry--Map的内部类,描述Map中的按键/数值对。
SortedMap---扩展Map,使按键保持升序排列
在所有的预处理指令中,#Pragma指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。
一般格式
其格式一般为: #pragma Para。其中Para 为参数,下面来看一些常用的参数。
(1)message参数
Message 参数能够在编译信息输出窗口中输出相应的信息,这对于源代码信息的控制是非常重要的。其使用方法为:
#pragma message(“消息文本”)
当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。
当我们在程序中定义了许多宏来控制源代码版本的时候,我们自己有可能都会忘记有没有正确的设置这些宏,此时我们可以用这条指令在编译的时候就进行检查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86这个宏可以用下面的方法
#ifdef _X86
#pragma message(“_X86 macro activated!”)
#endif
当我们定义了_X86这个宏以后,应用程序在编译时就会在编译输出窗口里显示“_X86macro activated!”。我们就不会因为不记得自己定义的一些特定的宏而抓耳挠腮了。
(2)code_seg
另一个使用得比较多的pragma参数是code_seg。格式如:
#pragma code_seg( ["section-name"[,"section-class"]] )
它能够设置程序中函数代码存放的代码段,当我们开发驱动程序的时候就会使用到它。
(3)#pragmaonce
(比较常用)
只要在头文件的最开始加入这条指令就能够保证头文件被编译一次,这条指令实际上在VC6中就已经有了,但是考虑到兼容性并没有太多的使用它。
#pragma once是编译相关,就是说这个编译系统上能用,但在其他编译系统不一定可以,也就是说移植性差,不过现在基本上已经是每个编译器都有这个定义了。
#ifndef,#define,#endif这个是C++语言相关,这是C++语言中的宏定义,通过宏定义避免文件多次编译。所以在所有支持C++语言的编译器上都是有效的,如果写的程序要跨平台,最好使用这种方式。
(4)#pragmahdrstop
#pragma hdrstop表示预编译头文件到此为止,后面的头文件不进行预编译。BCB可以预编译头文件以加快链接的速度,但如果所有头文件都进行预编译又可能占太多磁盘空间,所以使用这个选项排除一些头文件。
有时单元之间有依赖关系,比如单元A依赖单元B,所以单元B要先于单元A编译。你可以用#pragma startup指定编译优先级,如果使用了#pragma package(smart_init) ,BCB就会根据优先级的大小先后编译。
(5)#pragmaresource
#pragma resource "*.dfm"表示把*.dfm文件中的资源加入工程。*.dfm中包括窗体外观的定义。
(6)#pragmawarning
#pragma warning( disable : 4507 34; once : 4385;error : 164 )
等价于:
#pragma warning(disable:4507 34) // 不显示4507和34号警告信息
#pragma warning(once:4385) // 4385号警告信息仅报告一次
#pragma warning(error:164) // 把164号警告信息作为一个错误。
同时这个pragma warning 也支持如下格式:
#pragma warning( push [ ,n ] )
#pragma warning( pop )
这里n代表一个警告等级(1---4)。
#pragma warning( push )保存所有警告信息的现有的警告状态。
#pragma warning( push, n)保存所有警告信息的现有的警告状态,并且把全局警告等级设定为n。
#pragma warning( pop )向栈中弹出最后一个警告信息,
在入栈和出栈之间所作的一切改动取消。例如:
#pragma warning( push )
#pragma warning( disable : 4705 )
#pragma warning( disable : 4706 )
#pragma warning( disable : 4707 )
//.......
#pragma warning( pop )
在这段代码的最后,重新保存所有的警告信息(包括4705,4706和4707)。
(7)pragmacomment
pragma comment(...)
该指令将一个注释记录放入一个对象文件或可执行文件中。
常用的lib关键字,可以帮我们连入一个库文件。
每个编译程序可以用#pragma指令激活或终止该编译程序支持的一些编译功能。例如,对循环优化功能:
#pragma loop_opt(on) // 激活
#pragma loop_opt(off) // 终止
有时,程序中会有些函数会使编译器发出你熟知而想忽略的警告,如“Parameter xxx is never used in function xxx”,可以这样:
#pragma warn —100 // Turn off the warning messagefor warning #100
int insert_record(REC *r)
{ /* function body */ }
#pragma warn +100 // Turn the warning message forwarning #100 back on
函数会产生一条有唯一特征码100的警告信息,如此可暂时终止该警告。
每个编译器对#pragma的实现不同,在一个编译器中有效在别的编译器中几乎无效。可从编译器的文档中查看。
#pragma pack(n)和#pragma pop()
struct sample
{
char a;
double b;
};
当sample结构没有加#pragma pack(n)的时候,sample按最大的成员那个对齐;
(所谓的对齐是指对齐数为n时,对每个成员进行对齐,既如果成员a的大小小于n则将a扩大到n个大小;
如果a的大小大于n则使用a的大小;)所以上面那个结构的大小为16字节.
当sample结构加#pragma pack(1)的时候,sizeof(sample)=9字节;无空字节。
(另注:当n大于sample结构的最大成员的大小时,n取最大成员的大小。
所以当n越大时,结构的速度越快,大小越大;反之则)
#pragma pop()就是取消#pragma pack(n)的意思了,也就是说接下来的结构不用#pragma pack(n)
#pragma comment( comment-type,["commentstring"] )
comment-type是一个预定义的标识符,指定注释的类型,应该是compiler,exestr,lib,linker之一。
commentstring是一个提供为comment-type提供附加信息的字符串。
注释类型:
1、compiler:
放置编译器的版本或者名字到一个对象文件,该选项是被linker忽略的。
2、exestr:
在以后的版本将被取消。
3、lib:
放置一个库搜索记录到对象文件中,这个类型应该是和commentstring(指定你要Linker搜索的lib的名称和路径)这个库的名字放在Object文件的默认库搜索记录的后面,linker搜索这个这个库就像你在命令行输入这个命令一样。你可以在一个源文件中设置多个库记录,它们在object文件中的顺序和在源文件中的顺序一样。如果默认库和附加库的次序是需要区别的,使用Z编译开关是防止默认库放到object模块。
4、linker:
linker:指定一个连接选项,这样就不用在命令行输入或者在开发环境中设置了。
只有下面的linker选项能被传给Linker.
/DEFAULTLIB,/EXPORT,/INCLUDE,/MANIFESTDEPENDENCY, /MERGE,/SECTION
(1) /DEFAULTLIB:library
/DEFAULTLIB 选项将一个 library 添加到 LINK 在解析引用时搜索的库列表。用 /DEFAULTLIB指定的库在命令行上指定的库之后和 .obj 文件中指定的默认库之前被搜索。忽略所有默认库 (/NODEFAULTLIB) 选项重写 /DEFAULTLIB:library。如果在两者中指定了相同的library 名称,忽略库 (/NODEFAULTLIB:library) 选项将重写/DEFAULTLIB:library。
(2)/EXPORT:entryname[,@ordinal[,NONAME]][,DATA]
使用该选项,可以从程序导出函数,以便其他程序可以调用该函数。也可以导出数据。通常在 DLL 中定义导出。entryname是调用程序要使用的函数或数据项的名称。ordinal 在导出表中指定范围在 1 至 65,535 的索引;如果没有指定 ordinal,则 LINK 将分配一个。NONAME关键字只将函数导出为序号,没有 entryname。
DATA 关键字指定导出项为数据项。客户程序中的数据项必须用 extern __declspec(dllimport)来声明。
有三种导出定义的方法,按照建议的使用顺序依次为:
源代码中的 __declspec(dllexport).def 文件中的 EXPORTS 语句LINK 命令中的 /EXPORT 规范所有这三种方法可以用在同一个程序中。LINK在生成包含导出的程序时还创建导入库,除非生成中使用了 .exp 文件。
LINK 使用标识符的修饰形式。编译器在创建 .obj 文件时修饰标识符。如果 entryname以其未修饰的形式指定给链接器(与其在源代码中一样),则 LINK 将试图匹配该名称。如果无法找到唯一的匹配名称,则 LINK 发出错误信息。当需要将标识符指定给链接器时,请使用 Dumpbin 工具获取该标识符的修饰名形式。
#pragmacomment(linker,"/SECTION:shared,RWS")
这些字句的解释:
第一个#pragma叙述建立数据段,这里命名为shared。您可以将这段命名为任何一个您喜欢的名字。在这里的#pragma叙述之后的所有初始化了的变量都放在shared数据段中。第二个#pragma叙述标示段的结束。对变量进行专门的初始化是很重要的,否则编译器将把它们放在普通的未初始化数据段中而不是放在shared中。
连结器必须知道有一个「shared」共享数据段。在「Project Settings」对话框选择「Link」页面卷标。选中「STRLIB」时在「Project Options」字段(在Release和Debug设定中均可),包含下面的连结叙述:
/SECTION:shared,RWS
字母RWS表示段具有读、写和共享属性。或者,您也可以直接用DLL原始码指定连结选项,就像我们在STRLIB.C那样:
#pragmacomment(linker,"/SECTION:shared,RWS")
(3)/INCLUDE:symbol
/INCLUDE 选项通知链接器将指定的符号添加到符号表。
若要指定多个符号,请在符号名称之间键入逗号 (,)、分号 (;) 或空格。在命令行上,对每个符号指定一次 /INCLUDE:symbol。
链接器通过将包含符号定义的对象添加到程序来解析 symbol。该功能对于添包含不会链接到程序的库对象非常有用。用该选项指定符号将通过 /OPT:REF 重写该符号的移除。
我们经常用到的是#pragma comment(lib,"*.lib")这类的。#pragma comment(lib,"Ws2_32.lib")表示链接Ws2_32.lib这个库。和在工程设置里写上链入Ws2_32.lib的效果一样,不过这种方法写的程序别人在使用你的代码的时候就不用再设置工程settings了
(8)#pragmadata_seg
#pragma data_seg介绍
用#pragma data_seg建立一个新的数据段并定义共享数据,其具体格式为:
#pragma data_seg ("shareddata")
HWND sharedwnd=NULL;//共享数据
#pragma data_seg()
-----------------------------------------------------------------
1,#pragmadata_seg()一般用于DLL中。也就是说,在DLL中定义一个共享的有名字的数据段。最关键的是:这个数据段中的全局变量可以被多个进程共享,否则多个进程之间无法共享DLL中的全局变量。
2,共享数据必须初始化,否则微软编译器会把没有初始化的数据放到.BSS段中,从而导致多个进程之间的共享行为失败。例如,
#pragma data_seg("MyData")
int g_Value; // Note that the global is notinitialized.
#pragma data_seg()
DLL提供两个接口函数:
int GetValue()
{
return g_Value;
}
void SetValue(int n)
{
g_Value = n;
}
然后启动两个进程A和B,A和B都调用了这个DLL,假如A调用了SetValue(5); B接着调用int m = GetValue(); 那么m的值不一定是5,而是一个未定义的值。因为DLL中的全局数据对于每一个调用它的进程而言,是私有的,不能共享的。假如你对g_Value进行了初始化,那么g_Value就一定会被放进MyData段中。换句话说,如果A调用了SetValue(5); B接着调用int m = GetValue(); 那么m的值就一定是5,这就实现了跨进程之间的数据通信。
#pragma data_seg( ".mysec ")
HWND g_hwnd=NULL;
#pragma data_seg()
#pragma comment(linker,"/section:mysec,RWS ")
编译成功后,我用dumpbin/headers 看了一下,改不成Shared属性。
我用的是vc++.net 是不是编译器那里还需要设置呢?
谢谢
两个改错方案:
1、
#pragma data_seg( ".mysec ")
HWND g_hwnd=NULL;
#pragma data_seg()
#pragma comment(linker,"/section:.mysec,RWS ")
2、
#pragma data_seg( "mysec ")
HWND g_hwnd=NULL;
#pragma data_seg()
#pragma comment(linker,"/section:mysec,RWS ")
都行。
将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值, 块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作, 其返回值为指向S的指针。
void *memset(void *s, int ch, size_t n);
函数解释:将s中前n个字节替换为ch并返回s;
memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。
TCHAR.H routine |
_UNICODE & _MBCS not defined |
_MBCS defined |
_UNICODE defined |
_tcscpy_s |
strcpy_s |
_mbscpy_s |
wcscpy_s |
Copy a string. These areversions of strcpy,wcscpy, _mbscpy with security enhancementsas described in SecurityFeatures in the CRT.
复制一个字符串。这些都是_mbscpy与wcscpy,STRCPY的安全性增强版本,在CRT的安全功能描述。
strcpy
原型声明:extern char *strcpy(char *dest,const char *src);
头文件:string.h
功能:把从src地址开始且含有NULL结束符的字符串赋值到以dest开始的地址空间
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。 返回指向dest的指针。
_tcscpy_s
errno_t strcpy_s(
char *strDestination,
size_t numberOfElements,
const char *strSource
);
strDestination
Location of destination string buffer:目的地的位置字符串缓冲区;
numberOfElements
Size of the destination stringbuffer: 目标字符串缓冲区的大小;
strSource
Null-terminated source stringbuffer:NULL结尾的源字符串缓冲区。
http://blog.csdn.net/sky04/article/details/6536011
char *p=NULL;
try
{
p=new char[128];
}
catch(...) //抓所有的异常
{
//异常处理
}
要防止因为异常产生的内存泄漏,可以使用智能指针,也可以用
__try
{
}
__finally
{
}
《Windows核心编程》一书第23~25章是很好的参考资料。
try,catch,throw:
try包含你要防护的代码 ,称为防护块. 防护块如果出现异常,会自动生成异常对象并抛出.
catch捕捉特定的异常,并在其中进行适当处理.
throw可以直接抛出/产生异常,导致控制流程转到catch块.
重要观点: C++中异常是用对象来表示的,称为异常对象.
基本格式:
try{ your code; }
catch(T1t1) //T1可以是任意类型,int,char,CException...
{/*T1指定了你要捕捉的异常的类型,t1指定了异常对象的名称,当有异常抛出,异常对象将被复制到t1 中,这样你就可以在本处理块中使用该对象,获取相关信息,进行适当处理. 处理代码;*/}
catch(T2*pt1)
//上面的catch是值传递,这里使用指针传递.
{ 处理代码; }
catch(...)
//...是捕捉任意类型的异常.
{ 处理代码; }
//其他代码;
/*某个catch执行完,就跳转到这里继续执行. 在没有使用C++异常处理的情况下,如果在此之前出现异常,则//这里的其他代码不会被执行,从而造成问题.请考虑在这里放置: delete pobj1; 如果不使用用try,catch机制,内存泄漏是必然的, 因为出现问题后,执行流程无法跳转到这里. */
/*说明: try{}之后可以跟任意个catch块. 发生异常后,会生成临时的异常对象,进行一些自动处理之后,程序 流程跳转到后面的catch(),逐个检查这些catch(),如果与catch() 中指定的类型一致,则将对象拷贝给catch参数中的对象, 接着执行该catch块中的代码,然后跳过其他所有剩下的catch, 继续执行后续的代码.
上面所说的自动处理指的是堆栈回退,说白了就是为函数中的局部对象调用析构函数,保证这些局部对象行为良好. */
catch()的顺序通常按照:从特殊到一般的顺序: catch(Tsub o){} catch(Tbaseo){} catch(...){} 如果第一个catch为catch(Tbase){},则它将捕捉其所有派生类的异常对象. 如果第一个catch为catch(...){},则其后的所有catch永远不可能被执行.
重新抛出异常: 从上面的处理机制可以看到,只有一个catch可能被执行, 如果一个catch被执行,其他后续的catch就会被跳过了. 有时候一个catch中可能无法完成异常的全部处理,需要将异常提交给更高的层,以期望得到处理.重新抛出异常实现了这种可能性. 语法: throw ; 空的throw语句,只能在catch中使用. 它重新抛出异常对象,其外层的catch可能可以捕捉这个重新抛出的异常并做适当处理.
_tcslen(str) 获得字符串长度
_tcsrchr(str, L'\\') 反向搜索获得最后一个TCHAR的位置
_stprintf(TCHAR *buffer,const TCHAR *format[,argument] ... )获得一个格式化字符串
_tcsdup 给一个指针分配源字符串大小的内存并从源字符串copy值
_tcstok 按标记将字符串拆分
tcscpy拷贝字符串
Containsstrings returned from the IShellFolder interface methods.
包含从IShellFolder接口的方法返回的字符串。
typedef struct _STRRET {
UINT uType;
union {
LPWSTR pOleStr;
UINT uOffset;
CHAR cStr[MAX_PATH];
};
} STRRET, *LPSTRRET;
Members
uType
Type: UINT
A value that specifies thedesired format of the string. This can be one of the following values.
一个值,指定所需的格式字符串。这可以是下列值之一。
STRRET_CSTR
The string is returned inthe cStr member.
该字符串被返回在CSTR成员。
STRRET_OFFSET
The uOffset member value indicates the number ofbytes from the beginning of the item identifier list where the string islocated.
从开始的项目标识符列表的字符串位于uOffset成员值表示的字节数。
STRRET_WSTR
Thestring is at the address specified by pOleStr member.
字符串是pOleStr成员中指定的地址。
pOleStr
Type: LPWSTR
A pointer to the string.This memory must be allocated with CoTaskMemAlloc. It is the calling application's responsibility to free thismemory with CoTaskMemFree when it is no longer needed.
字符串的指针。这必须与CoTaskMemAlloc来分配内存。它是调用应用程序的责任与CoTaskMemFree释放内存,当它不再需要。
uOffset
Type: UINT
The offset into the itemidentifier list.
偏移到项目标识符列表。
cStr
Type: CHAR[MAX_PATH]
The buffer to receive thedisplay name.接收缓冲区的显示名称。
只有分号“;”组成的语句称为空语句。
空语句是什么也不执行的语句。在程序中空语句可用来作空循环体。
例如 while(getchar()!='\n');
本语句的功能是,只要从键盘输入的字符不是回车则重新输入。这里的循环体为空语句
空语句仅由一个分号组成,不进行任何操作。一般用于语法上要求有一条语句但实际没有任何操作的场合。例如:
for(i=1;i<10;i++); //空语句,起延时作用。。。
他是一个完整的循环结构,在多数情况下用于时间等待。
54 LPCTSTR类型:
LP:long型指针,这是为了兼容Windows 3.1等16位操作系统遗留下来的,在win32中以及其他的32为操作系统中, long指针和near指针及far修饰符都是为了兼容的作用。没有实际意义。
C:常量;
T:和_T含义一样,应该是UNICODE型;
STR:字符串
调用这个成员函数创建一个连接的服务器上的目录。
BOOL CreateDirectory(
LPCTSTRpstrDirName
);
pstrDirName
A pointer to a string containing the name of thedirectory to create.
一个指针指向字符串包含的目录的名称来创建。
assert宏的原型定义在assert.h中,其作用是如果它的条件返回错误,则终止程序执行.
原型定义:
1 |
#include "assert.h" |
|
2 |
void assert( int expression ); |
assert的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。
hash_map::empty
Tests if a hash_mapis empty.测试如果hash_map是空的。
bool empty( ) const;
true if the hash_map is empty; false if the hash_map is nonempty.
真实的,如果hash_map是空的;hash_map是假的,如果非空。
tstring szAppPath =GetAppPath();
::CreateDirectory(strRet.c_str(),NULL);
strRet.size()
写相应的变量. 后边可以自动弹出一些函数;
这些函数是在其他类中定义的,再该文件中声明类该类的对象。则就可以应用该类的成员函数。
:: 这个符号是用于全局变量的;
class B;//声明类B
CTTSManager g_TTSManager;
CTTSManager 是类声明对象
语法:
constchar *c_str();
c_str()函数返回一个指向正规C字符串的指针, 内容与本string串相同.
这是为了与c语言兼容,在c语言中没有string类型,故必须通过string类对象的成员函数c_str()把string 对象转换成c中的字符串样式。
注意:一定要使用strcpy()函数等来操作方法c_str()返回的指针
比如:最好不要这样:
char*c;
strings="1234";
c = s.c_str(); //c最后指向的内容是垃圾,因为s对象被析构,其内容被处理
应该这样用:
char c[20];
string s="1234";
strcpy(c,s.c_str());
这样才不会出错,c_str()返回的是一个临时指针,不能对其进行操作
再举个例子
c_str()以 char* 形式传回 string 内含字符串
如果一个函数要求char*参数,可以使用c_str()方法:
strings = "Hello World!";
printf("%s",s.c_str()); //输出 "HelloWorld!"