Windows核心编程17章------后续

一、ANSIUNICODE知识点 

二、 用内存映射文件来把一个ANSIUNICODE文本文件内容颠倒过来。

三、进程间共享数据,参考API一日一练

一、ANSIUNICODE知识点

1、  判断一个文本是ANSI还是UNICODE

2、  如何对字符串进行有选择的比较

3、  让程序支持UNICODE

4、  Windows定义的UNICODE数据类型

5、  如何对UNICODE操作

6、  ANSIUNICODE的相互转换

1、判断一个文本是ANSI还是UNICODE

 1)判断如果文本文件的开头两个字节是0xFF0xFE,那么就是Unicode,否则是ANSI  

2)用IsTextUnicode进行判断。IsTextUnicode使用一系列统计方法和定性方法,以便猜测缓存的内容。由于这不是一种确切的科学方法,因此   IsTextUnicode有可能返回不正确的结果。

2、通过调用CompareString来实现。
标志                                           含义
NORM_IGNORECASE   忽略字母的大小写
NORM_IGNOREKANATYPE   不区分平假名与片假名字符
NORM_IGNORENONSPACE   忽略无间隔字符
NORM_IGNORESYMBOLS   忽略符号
NORM_IGNOREWIDTH   不区分单字节字符与作为双字节字符的同一个字符
SORT_STRINGSORT   将标点符号作为普通符号来处理

3、在vc编译选项上,vc7.0以上在工程的属性页中的字符集选上 "使用   Unicode   字符集 "即可,在vc6.0下可能麻烦一点,得先把vc运行库的unicode版本复制到vc路径下,一般都是和xxx.libansi对应xxxU.lib,默认装vc时是不会装的,再在工程属性
1)改语言定义:
project   settings "C++ "页中的 "preprocessor   definitions "中改_MBCS_UNICODE
2
)改入口函数:
"link "页中的 "project   Options "加入/entry: "wWinMainCRTStartup "即可.
3
)在代码上,处理字符中的多用TCHAR.H中的宏,strcpy_tcscpy代替,TCHARchar,
TCHAR   m_mystr[]=_T( "xxxx ")代替  char   m_mystr[]= "xxxx ";
4
)注意调试UNICODE程序时,需要在安装时VC选择所有选项,否则会缺少动态库和相应的.lib文件

4Windows定义的UNICODE数据类型

数据类型    说明
WCHAR   Unicode字符
PWSTR   指向Unicode字符串的指针
PCWSTR   指向一个恒定的Unicode字符串的指针
对应的ANSI数据类型为CHARLPSTRLPCSTR
ANSI/Unicode通用数据类型为TCHARPTSTR,LPCTSTR

5、如何对UNICODE操作

字符集   特性              实例
ANSI   操作函数以str开头  strcpy
Unicode  
操作函数以wcs开头  wcscpy
MBCS  
操作函数以_mbs开头  _mbscpy
ANSI/Unicode  
操作函数以_tcs开头   _tcscpyC运行期库)
ANSI/Unicode   操作函数以lstr开头   lstrcpyWindows函数

6ANSIUNICODE的相互转换

1)将ANSI转换到Unicode

(1)通过L这个宏来实现,例如:   CLSIDFromProgID(   L "MAPI.Folder ",&clsid);
(2)
通过MultiByteToWideChar函数实现转换,例如:

char   *szProgID   =   "MAPI.Folder ";
WCHAR   szWideProgID[128];
CLSID   clsid;
long   lLen   =   MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID));
szWideProgID[lLen]   =   '\0 ';  

(3)通过A2W宏来实现,例如:  
USES_CONVERSION;  
CLSIDFromProgID(   A2W(szProgID),&clsid);  

2)将Unicode转换到ANSI

(1)使用WideCharToMultiByte,例如:
//  
假设已经有了一个Unicode     wszSomeString...  
char   szANSIString   [MAX_PATH];  
WideCharToMultiByte   (   CP_ACP,   WC_COMPOSITECHECK,   wszSomeString,   -1,   szANSIString,   sizeof(szANSIString),   NULL,   NULL   );  

(2)使用W2A宏来实现,例如:
USES_CONVERSION;
pTemp=W2A(wszSomeString);  
注意在转换时可能存在的问题:
因为ANSIUNICODE,如果使用A2WMultiByteToWideChar(第一个参数是CP_ACP)的话,是根据系统默认的转码表,把转入的ANSI字符串看作Multi-Bytes字符串处理的,如果是中文(中文windows默认就是中文),一个大于0x87byte可能和下一byte一起被看作一个汉字,然后根据汉字的Unicode编码转换为相同的Unicode汉字,如果找不到相应的编码,一般就用一个默认的字符来取代它(一般是问号,由此看,如果随便把一段数据给他转,转化很复杂而且极可能不可逆,而且你加密过的ANSI码是相当混乱的有很多〉0x87byte,转换就变得不可逆了。
建议自己直接就这样写:
CHAR   lpANSI[COUNT];
WCHAR   lpUnicode[COUNT];
int   i   =   0;  
while(lpANSI[i]   !=   '\0 '   )   {
        lpUnicode[i]   =   (WCHAR)lpANSI[i];
}
lpUnicode[i]   =   L '\0 ';
然后按相同的方法转回来,因为对于0~0x87ANSI字符串,对应的Unicode码就是相同的16位值,至于其他的,你的字符串反正加了密,没必要转换成显示出来是一样的字符,就按同样的方法处理了,其实如果中间的字符串不用显示或别的,直接reutrn   (LPWSTR)lpANSI;过去也可以,   反正接受的时候自己清楚就可以了。

二、用内存映射文件来把一个ANSIUNICODE文本文件内容颠倒过来。

两个注意点:颠倒前,先给指定文件复制一份,防止颠倒后文件不可逆。

Ø  因文本文件并非以字符0结尾,而C语言格式字符串最后一个字符必须是0。所以创建文件映射对象时,文件长度增加一个宽字符的大小(用来存放字符0)

Ø  在一个文本文件中,每行末尾的回车换行符”\r\n”也会被颠倒,用_strrev倒序后需将”\n\r”转为”\r\n”

BOOL FileReverse(LPCTSTR pszPathname)
{
//Open the file for reading and writing
HANDLE hFile = CreateFile(pszPathname, GENERIC_WRITE | GENERIC_READ, 0, 
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hFile)
{
AfxMessageBox(_T("File could not be opened."));
return FALSE;
}

//Create the file-mapping object.
DWORD dwFileSize = GetFileSize(hFile, NULL);
HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 
0, dwFileSize + sizeof(TCHAR), NULL);
if (NULL == hFileMap)
{
AfxMessageBox(_T("File map could not be opened."));
CloseHandle(hFile);
return FALSE;
}

//Get the address where the first byte of the file is mapped into memory.
PVOID pvFile = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);
if (NULL == pvFile)
{
AfxMessageBox(_T("Could not map view of file"));
CloseHandle(hFileMap);
CloseHandle(hFile);
return FALSE;
}

//Does the buffer contain ANSI or Unicode
int iUnicodeTestFlags = -1;
BOOL bIsTextUnicode = IsTextUnicode(pvFile, dwFileSize, &iUnicodeTestFlags);

if (!bIsTextUnicode)
{
//把一个字符0写到文件末尾并颠倒字符串
PSTR pchANSI = (PSTR)pvFile;
pchANSI[dwFileSize / sizeof(char)] = 0;

//reverse the contexts of the file
_strrev(pchANSI); //ansi用_strrev(pvFile);

//convert all "\n\r" combinations back to "\r\n" to preserve
//the normal end-of-line sequence.
pchANSI = strstr(pchANSI, "\n\r");

while (pchANSI != NULL)
{
*pchANSI++ = '\r';
*pchANSI++ = '\n';
pchANSI = strstr(pchANSI, "\n\r");
}
}
else
{
//把一个字符0写到文件末尾并颠倒字符串
PWSTR pchUnicode = (PWSTR)pvFile;
pchUnicode[dwFileSize / sizeof(WCHAR)] = 0;

if ((iUnicodeTestFlags & IS_TEXT_UNICODE_SIGNATURE) !=0)
{
//if the first character is the Unicode BOM(byte-order-mark)
//0xFEFF,keep the character at the begining of the file.
pchUnicode++;
}

_wcsrev(pchUnicode);

//convert all "\n\r" combinations back to "\r\n" to preserve
//the normal end-of-line sequence.
pchUnicode = wcsstr(pchUnicode, L"\n\r");

while (pchUnicode!=NULL)
{
*pchUnicode++ = L'\r';
*pchUnicode++ = L'\n';
pchUnicode = wcsstr(pchUnicode, L"\n\r");
}
}
//Clean up everything before exiting.
UnmapViewOfFile(pvFile);
CloseHandle(hFileMap);

//Remove trailing zero character added earlier.
SetFilePointer(hFile, dwFileSize, NULL, FILE_BEGIN);
SetEndOfFile(hFile);
CloseHandle(hFile);

return TRUE;

}



 

你可能感兴趣的:(unicode,ansi)