英数字のみのテキストファイルに、Win10メモ帳で漢字を追記すると、
メモ帳での保存時にUTF8が選択されるから、昔ながらのANSI/SJISを前提とした
アプリだとエラーが出るんだと。
久しぶりのWin32、以下のように修正してやりました。
MultiByteToWideChar()/WideCharToMultiByte()はBOMを削除しないので、ファイルから読み込んだバイナリーデータを変換する場合には、BOMのバイト分ずらす必要がありました。
#include <mlang.h>
...
IMultiLanguage2* mlang = NULL;
DetectEncodingInfo detectEnc{};
HRESULT hres=CoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, IID_IMultiLanguage2, (void**)&mlang);
{
int encCount=1;
DWORD size_i;
char txtdata[MAX_BUFFERBLOCK];
HANDLE h=CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
ReadFile(h, txtdata, MAX_BUFFERBLOCK, &size_i, NULL);
CloseHandle(h);
hres=mlang->DetectInputCodepage(MLDETECTCP_NONE, 0, txtdata, (INT *)&size_i, &detectEnc, &encCount);
}
}
mlang->Release();
if(detectEnc.nCodePage==65001){ // UTF8
char b_filename[MAX_PATH]{};
strcpy(b_filename, filename);
PathRenameExtension(b_filename, ".ini_UTF8");
MoveFileEx(filename, b_filename, MOVEFILE_REPLACE_EXISTING);
HANDLE h;
DWORD srcsize, medsize, dstsize, rwsize;
unsigned char *mtxt=NULL, *mtxt_a=NULL;
wchar_t *wtxt=NULL;
bool wBOM=false;
{
h=CreateFile(b_filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
srcsize=GetFileSize(hFile, NULL);
mtxt=(unsigned char *)malloc(srcsize);
ReadFile(h, (char *)mtxt, srcsize, &rwsize, NULL);
CloseHandle(h);
if((mtxt[0]==0xef)&&(mtxt[1]==0xbb)&&(mtxt[2]==0xbf)) wBOM=true;
if(wBOM==true){
mtxt_a=&mtxt[3];
srcsize=rwsize-3;
}else{
mtxt_a=&mtxt[0];
srcsize=rwsize;
}
medsize=MultiByteToWideChar(CP_UTF8, 0, (LPCCH)mtxt_a, srcsize, NULL, 0);
wtxt=(wchar_t *)malloc(medsize*sizeof(wchar_t));
MultiByteToWideChar(CP_UTF8, 0, (LPCCH)mtxt_a, srcsize, wtxt, medsize);
dstsize=WideCharToMultiByte(CP_ACP, 0, wtxt, medsize, NULL, 0, NULL, NULL);
mtxt=(unsigned char *)realloc(mtxt, dstsize*sizeof(unsigned char));
WideCharToMultiByte(CP_ACP, 0, wtxt, medsize, (LPSTR)mtxt, dstsize, NULL, NULL);
h=CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hFile, (char *)(mtxt), dstsize, &rwsize, NULL);
CloseHandle(h);
}
if(mtxt!=NULL) free(mtxt);
if(wtxt!=NULL) free(wtxt);