Windows API常识

摘要:
例如,字符“A”在ASCII下由一个字节表示,在Unicode下由两个字节表示。高字部分用“0”填充;函数“procedure”由ASCII下的两个字节和Unicode下的两字节表示。Unicode用于表示固定长度的世界字符。据统计,两个字节可以对所有现有字符进行编码而不会产生歧义。Microsoft当前的SDK保留了两组API,一组用于编写使用Unicode编码来处理字符的程序,另一组用于撰写使用ASCII编码来处理字符串的程序。#IfdefUNICODE#defineMessageBoxMessageBoxW#else#defineMMessageBoxMessageBoxA#endifMessageBox只是一个宏。

typedef float FLOAT;

typedef long LONG;

typedef short SHORT

typedef int INT;

typedef char CHAR;

 

typedef unsigned int UINT;

typedef unsigned int UINT32;

typedef signed int INT32;

typedef unsigned long DWORD;

typedef unsigned short WORD;

 

#if defined(_WIN64)

typedef __int64 LONG_PTR;

#else

typedef long LONG_PTR;

#endif

 

typedef LONG_PTR LPARAM;

typedef UINT_PTR WPARAM;

 

#define   VOID void

#define CONST   const

 

 

ANSI(即MBCS):为多字节字符集,它是不定长表示世界文字的编码方式。ANSI表示英文字母时就和ASCII一样,但表示其他文字时就需要用多字节。

 

Unicode:用两个字节表示一个字符的编码方式。比如字符'A'在ASCII下面用一个字节表示,而在Unicode下面用两个字节表示,其中高字节用“0”填充;函数'程'在ASCII下面用两个字节表示,而在Unicode下面也是用两个字节表示。Unicode的用处就是定长表示世界文字,据统计,用两个字节可以编码现存的所有文字而没有二义。

 

微软目前的SDK中保留了2套API,一套用于采用Unicode编码处理字符的程序的编写,一套用于采用ASCII编码处理字符的程序的编写。

 

#ifdef UNICODE

#define MessageBox  MessageBoxW

#else

#define MessageBox  MessageBoxA

#endif 

 

MessageBox只是一个宏而已。所以在程序中,这3个名字你都可以使用。

只不过需要注意的是:

使用 MessageBoxA 的话,那么你要注意传给它的参数,字符都必须是单字节,也就是ASCII,在程序中就是char;

使用 MessageBoxW 的话,那么,字符都必须使用Unicode,程序中就是 wchar_t。

因此,我们在编程的时候尽量使用不带后缀的宏定义,使用微软给我们定义的 TCHAR 字符数据类型:

(通用数据类型:定义了一套宏能根据不同的工程环境定义成不同的字符数据类型

 

 

#ifdef  UNICODE

typedef  WCHAR  TCHAR;

#else

typedef  char TCHAR

#endif

 

 

 

单字节的char 和 宽字节的wchar_t

宽字节的操作其实和单字节的字符操作一样,只是在前面加上 L 表示是宽字节的字符或者字符串。

char   c = 'b';

wcha_t  wc = L'b';

 

char  c[10];

wchar_t wc[10];

 char c[] = "beyondcode";

wchar_t wc[] = L"beyondcode";

 

char   *p = c;      

wchar_t *wp = wc;   

 

 

 typedef char  CHAR;

typedef wchar_t  WCHAR;

typedef  CHAR  *LPSTR;    

typedef  WCHAR  *LPWSTR;  

// 下面变量名中增加的这个 C 的含义就代表是const修饰符,常量指针,指向的内容不能通过这个指针被改变,只可以读取

typedef  CONST  CHAR  *LPCSTR;    

typedef  CONST  WCHAR *LPCWSTR;

#ifdef   UNICODE

typedef  LPWSTR   LPTSTR;

#else

typedef  LPSTR LPTSTR;

#endif

 

 总结:

LPSTR = char *
LPCSTR = const char *
LPWSTR = wchar_t *
LPCWSTR = const wchar_t *

LPTSTR = _TCHAR *
LPCTSTR = const _TCHAR *

LPOLESTR = OLECHAR * = BSTR = LPWSTR(Win32)
LPCOLESTR = const OLECHAR * = LPCWSTR(Win32)

// 这里:L代表LONG, P就是指针的意思, C就是constant的意思, W是wide的意思,STR就是string的意思

它们之间相互转换的方法:

W2T()   // LPWSTR->LPTSTR

T2W()   // LPWSTR->LPTSTR

W2CT()   // LPCWSTR->LPCSTR

T2CW()   // LPCSTR->LPCWSTR

A2W()    // ANSI->UNICODE

W2A()    // UNICODE->ANSI

 

一个重要的宏:

_T()

功能:只要将字符或者字符串常量放在_T()这个宏里面,那么这个宏就能根据当前的环境决定是否在字符或字符串前面加L

举例:

 

TCHAR tc = _T('A');

 

在不需要改写源代码的情况下,就可以编译出Unicode和ASCII两套程序,而只需要改变工程的环境而已。

 

 

// ASCII 版本

#include <windows.h>

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)

{

MessageBoxA( NULL, "Hello beyondcode", "Title", MB_OK );

return 0;

}

 

// Unicode 版本

#include <windows.h>

int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd )

{

MessageBoxW( NULL, L"Hello Beyondcode", L"Title", MB_OK );

return 0;

}

 

// 通用数据类型版本

#include <windows.h>

#include <tchar.h>    // 定义了_tWinMain 和 _T() 宏

int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd )

{

MessageBox( NULL, _T("Hello Beyondcode"), _T("Title"), MB_OK );

return 0;

}

 

 

格式化字符串函数:

#ifdef UNICODE

#define wsprintf  wsprintfW

#else

#define wsprintf  wsprintfA

#endif 

wsprintf最前面的 w 是Windows的 W,代表是windows的API函数了,其实它是一个宏,真正的API函数其实是 wsprintfA 和 wsprintfW 这两个

 

举例:

int sum = 12345;

TCHAR strSum[256] = { 0 };

wsprintf( strSum, _T("%d"), sum );

 

传递的参数凡是涉及到字符串常量的我们都是用_T()宏,字符串指针的我们都使用LPTSTR和LPCTSTR

strSum代表的是 wchar_t*,这里隐式转换const wchar_t*

 

另外还有:

sprintf   // 单字节版本的C/C++库函数

swprintf  // 宽字节版本的C/C++库函数

 

 

CString:动态的TCHAR数组。它是一个完全独立的类,封装了“+”等操作符和字符串操作方法,换句话说就是CString是对TCHAR操作的方法的集合。

 

string:string是c++中的字符串变量,因为操作c类型的char非常麻烦,而且很容易出现内存泄漏,所以c++就对c中的char 进行了封装,包含了赋值、删除、增加等常用操作,这些操作都不用考虑内存,使用更加方便

能使用string就尽量使用string,使用需要引用  #include <string>

 

相互转化:

1.CString和LPCTSTR的转化:

 CString和LPCTSTR不需要转化,两者是等价的

 CString str("cstring");

 LPCTSTRpcStr = str;

 

2.CString和LPTSTR的转化:

下述转法虽然可以,但是却不安全:

CString str("string");
LPTSTRpStr = (LPTSTR)(LPCTSTR)(str);

因为本来转化后的字符串变得可以修改了,造成了安全隐患。

正确的转化方法为:

CString str("string");

LPTSTRpStr = str.GetBuffer();

 str.ReleaseBuffer();

注意:GetBuffer()和ReleaseBuffer()之间不可以调用任何的CString函数, 因为无法预测对内存的操作,所以任何CString函数得到的结果都是不确定的.

 

3.CString和char*的转化

方法一:使用wcstombs()函数

CString str("string");

charpChar[100];

 wcstombs(pChar,str,100);

方法二:使用wcstombs_s()函数

同上面一样,wcstombs_s()是wcstombs()的安全版本

 

参考资料:

http://www.haogongju.net/art/787689

 

免责声明:文章转载自《Windows API常识》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Web_php_unserialize(序列化与反序列化)Java命令学习系列(三)——Jmap下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

sqlmap 绕过WAF

1、基本的语法 sqlmap 更新  sqlmap -update 具体的使用方法: sqlmap -u url --current-user sqlmap -u url --current-db sqlmap -u url --tables -D "db_name" sqlmap -u url --columns -T "tablename" users...

c 结构体中的变长数组

在Linux系统里,/usr/include/linux/if_pppox.h里面有这样一个结构: structpppoe_tag{ __u16tag_type; __u16tag_len; chartag_data[0]; }__attribute((packed)); 最后一个成员为可变长的数组,对于TLV(Type-Length-Value)形式的结...

文本格式ANSI,Unicode等有什么区别

首先DBCS是亚洲的字符集,包含了ANSI,ANSI也就是ASCII值为0-255之间的字符,当字符为ANSI时,存放于文件中占用的是一个字节。如果是非ANSI的呢,则占用两字节。用VB的ASC函数可以很容易得到一个字符的DBCS值(或是说ANSI值吧)假如一个字符得到的DBCS值为&H1234,当然,这个值是转换成了十六进制的,因为对于磁盘存放来...

python基础之字符编码

一 了解字符编码的知识储备 1. 文本编辑器存取文件的原理(nodepad++,pycharm,word) 打开编辑器就打开了启动了一个进程,是在内存中的,所以在编辑器编写的内容也都是存放与内存中的,断电后数据丢失 因而需要保存到硬盘上,点击保存按钮,就从内存中把数据刷到了硬盘上。 在这一点上,我们编写一个py文件(没有执行),跟编写其他文件没有任何区别,...

JS编码方式

1. escape(): 采用unicode字符集对指定的字符串除0-255以外进行编码。所有的空格符、标点符号、特殊字符以及更多有联系非ASCII字符都将被转化成%xx格式的字符编码(xx等于该字符在字符集表里面的编码的16进制数字)。比如,空格符对应的编码是%20。escape不编码字符有69个:*,+,-,.,/,@,_,0-9,a-z,A-Z。 2...

ASCII码、HEX、字符、BCD 等等 基础知识思考

每每遇到这些问题就要想个半天,想不明白还不舒服,今天特别把所想整理下避免以后再次进入思想漩涡!!!计算机存储和传输都是以字节为单位1 bit = 1 二进制数据1 byte = 8 bit1 字母 = 1 byte = 8 bit1 汉字 = 2 byte = 16 bit1. bit:位一个二进制数据0或1,是1bit;2. byte:字节存储空间的基本...