Windows核心編程17章——後續

來源:互聯網
上載者:User

一、ANSI和UNICODE知識點 

二、 用記憶體對應檔來把一個ANSI或UNICODE文字檔內容顛倒過來。

三、進程間共用資料,參考API一日一練

一、ANSI和UNICODE知識點

1、 
判斷一個文本是ANSI還是UNICODE

2、 
如何對字串進行有選擇的比較

3、 
讓程式支援UNICODE

4、 
Windows定義的UNICODE資料類型

5、 
如何對UNICODE操作

6、 
ANSI和UNICODE的相互轉換

1、判斷一個文本是ANSI還是UNICODE

 1)判斷如果文字檔的開頭兩個位元組是0xFF和0xFE,那麼就是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.lib的ansi對應xxxU.lib,預設裝vc時是不會裝的,再在工程屬性
1)改語言定義:
在project   settings的 "C++ "頁中的 "preprocessor   definitions "中改_MBCS為_UNICODE
2)改入口函數:
在 "link "頁中的 "project   Options "加入/entry: "wWinMainCRTStartup "即可.
3)在代碼上,處理字元中的多用TCHAR.H中的宏,如strcpy用_tcscpy代替,用TCHAR代char,
用TCHAR   m_mystr[]=_T( "xxxx ")代替  char   m_mystr[]= "xxxx ";
4)注意調試UNICODE程式時,需要在安裝時VC選擇所有選項,否則會缺少動態庫和相應的.lib檔案

4、Windows定義的UNICODE資料類型

資料類型    說明
WCHAR   Unicode字元
PWSTR  指向Unicode字串的指標
PCWSTR  指向一個恒定的Unicode字串的指標
對應的ANSI資料類型為CHAR,LPSTR和LPCSTR。
ANSI/Unicode通用資料類型為TCHAR,PTSTR,LPCTSTR。

5、如何對UNICODE操作

字元集  
特性              執行個體
ANSI  操作函數以str開頭  strcpy
Unicode  操作函數以wcs開頭  wcscpy
MBCS  操作函數以_mbs開頭  _mbscpy
ANSI/Unicode  操作函數以_tcs開頭   _tcscpy(C運行期庫)
ANSI/Unicode  操作函數以lstr開頭   lstrcpy(Windows函數

6、ANSI和UNICODE的相互轉換

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);  
注意在轉換時可能存在的問題:
因為ANSI轉UNICODE,如果使用A2W或MultiByteToWideChar(第一個參數是CP_ACP)的話,是根據系統預設的轉碼錶,把轉入的ANSI字串看作Multi-Bytes字串處理的,如果是中文(中文windows預設就是中文),一個大於0x87的byte可能和下一byte一起被看作一個漢字,然後根據漢字的Unicode編碼轉換為相同的Unicode漢字,如果找不到相應的編碼,一般就用一個預設的字元來取代它(一般是問號“?”),由此看,如果隨便把一段資料給他轉,轉化很複雜而且極可能無法復原,而且你加密過的ANSI碼是相當混亂的有很多〉0x87的byte,轉換就變得無法復原了。
建議自己直接就這樣寫:
CHAR   lpANSI[COUNT];
WCHAR   lpUnicode[COUNT];
int   i   =   0;  
while(lpANSI[i]   !=   '\0 '   )   {
        lpUnicode[i]   =   (WCHAR)lpANSI[i];
}
lpUnicode[i]   =   L '\0 ';
然後按相同的方法轉回來,因為對於0~0x87的ANSI字串,對應的Unicode碼就是相同的16位值,至於其他的,你的字串反正加了密,沒必要轉換成顯示出來是一樣的字元,就按同樣的方法處理了,其實如果中間的字串不用顯示或別的,直接reutrn
  (LPWSTR)lpANSI;過去也可以,  
反正接受的時候自己清楚就可以了。

二、用記憶體對應檔來把一個ANSI或UNICODE文字檔內容顛倒過來。

兩個注意點:顛倒前,先給指定檔案複製一份,防止顛倒後檔案無法復原。

Ø  因文字檔並非以字元0結尾,而C語言格式字串最後一個字元必須是0。所以建立檔案對應物件時,檔案長度增加一個寬字元的大小(用來存放字元0)。

Ø  在一個文字檔中,每行末尾的斷行符號分行符號”\r\n”也會被顛倒,用_strrev倒序後需將”\n\r”轉為”\r\n”。

BOOL FileReverse(LPCTSTR pszPathname){//Open the file for reading and writingHANDLE 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 Unicodeint 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;}

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.