Windows API常识

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");

 LPCTSTR pcStr = str;

 

2.CString和LPTSTR的转化:

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

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

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

正确的转化方法为:

CString str("string");

LPTSTR pStr = str.GetBuffer();

 str.ReleaseBuffer();

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

 

3.CString和char*的转化

方法一:使用wcstombs()函数

CString str("string");

char pChar[100];

 wcstombs(pChar,str,100);

方法二:使用wcstombs_s()函数

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

 

参考资料:

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

 

原文地址:https://www.cnblogs.com/CathyGao/p/2291416.html