2012-09-26 69 views
0

我試圖編寫一個通用的文本編輯器,它可以在EditControl中打開並顯示ANSI和Unicode。如果我確定文本是ANSI,是否需要重複撥打ReadFile()?無法弄清楚如何執行此任務。我的下面的嘗試不起作用,它顯示'?' EditControl中的字符。MultiByteToWideChar或WideCharToMultiByte和txt文件

LARGE_INTEGER fSize; 
     GetFileSizeEx(hFile,&fSize); 

     int bufferLen = fSize.QuadPart/sizeof(TCHAR)+1; 
     TCHAR* buffer = new TCHAR[bufferLen];  
     buffer[0] = _T('\0'); 

     DWORD wasRead = 0; 
     ReadFile(hFile,buffer,fSize.QuadPart,&wasRead,NULL);   
     buffer[wasRead/sizeof(TCHAR)] = _T('\0'); 

     if(!IsTextUnicode(buffer,bufferLen,NULL)) 
     {      
      CHAR* ansiBuffer = new CHAR[bufferLen]; 
      ansiBuffer[0] = '\0'; 
      WideCharToMultiByte(CP_ACP,0,buffer,bufferLen,ansiBuffer,bufferLen,NULL,NULL); 
      SetWindowTextA(edit,ansiBuffer); 
      delete[]ansiBuffer; 
     } 
     else 
      SetWindowText(edit,buffer); 

     CloseHandle(hFile); 
     delete[]buffer; 
+0

記事本++的源代碼可能是相關的作爲參考:http://notepad-plus-plus.org/download/ –

回答

2

有一些緩衝區長度錯誤和古怪,但這是你的大問題。您錯誤地致電WideCharToMultiByte。這意味着接收UTF-16編碼文本作爲輸入。但是,當IsTextUnicode返回false意味着該緩衝區不是UTF-16編碼的。

以下基本上是你所需要的:

if(!IsTextUnicode(buffer,bufferLen*sizeof(TCHAR),NULL)) 
    SetWindowTextA(edit,(char*)buffer); 

請注意,我已經固定長度參數IsTextUnicode

爲了什麼是值得的,我想我會讀到char的緩衝區。這將消除對sizeof(TCHAR)的需求。事實上,我會完全停止使用TCHAR。這個程序應該是全編碼的 - TCHAR是你在編譯Windows和NT的9x版本時使用的。我不想爲9x編譯我想象的東西。

所以我可能會這樣的代碼是:

char* buffer = new char[filesize+2];//+2 for UTF-16 null terminator 
DWORD wasRead = 0; 
ReadFile(hFile, buffer, filesize, &wasRead, NULL);   
//add error checking for ReadFile, including that wasRead == filesize 
buffer[filesize] = '\0'; 
buffer[filesize+1] = '\0'; 
if (IsTextUnicode(buffer, filesize, NULL)) 
    SetWindowText(edit, (wchar_t*)buffer); 
else 
    SetWindowTextA(edit, buffer); 
delete[] buffer; 

還要注意,該代碼未考慮接收UTF-8編碼的文本的可能性。如果你想處理,你需要把你的char緩衝區,並通過使用CP_UTF8通過MultiByteToWideChar發送。

+0

非常感謝,它工作正常)) –

+1

要小心。 ['IsTextUnicode()'可以報告錯誤結果](http://blogs.msdn.com/b/michkap/archive/2005/01/30/363308.aspx)。 [記事本使用'IsTextUnicode()'](http://blogs.msdn.com/b/oldnewthing/archive/2007/04/17/2158334.aspx)來檢測文件編碼,偶爾會出錯。你不應該依賴'IsTextUnicode()',並且不應該對文件的編碼做出假設。如果存在BOM,它會告訴你文件的編碼,所以先查找。如果沒有BOM存在,詢問用戶編碼是什麼,不要試圖猜測它,因爲有時你可能會猜錯。 –