我正在尝试编写一个通用文本编辑器,它可以在EditControl中打开并显示ANSI和Unicode。如果我确定文本是ANSI,是否需要重复调用ReadFile()
?无法弄清楚如何执行此任务。我下面的尝试不起作用,显示'?' EditControl中的字符。
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 :(得分:2)
有一些缓冲区长度错误和奇怪,但这是你的大问题。您错误地致电WideCharToMultiByte
。这意味着接收UTF-16编码的文本作为输入。但是当IsTextUnicode
返回false时,表示缓冲区不是UTF-16编码的。
以下基本上是您所需要的:
if(!IsTextUnicode(buffer,bufferLen*sizeof(TCHAR),NULL))
SetWindowTextA(edit,(char*)buffer);
请注意,我已将长度参数修改为IsTextUnicode
。
对于它的价值,我想我会读到char
的缓冲区。这将消除对sizeof(TCHAR)
的需求。事实上,我完全停止使用TCHAR
。这个程序应该一直是Unicode - TCHAR
是你在编译Windows的NT和9x变体时使用的。你不再编译我想象的9倍了。
所以我可能会这样编码:
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
缓冲区并使用MultiByteToWideChar
通过CP_UTF8
发送。