ホーム >プログラム >Delphi 6 ローテクTips >Unicodeの結合文字列をAnsiStringの合成文字に変換

といっても「が」を「が」に変換するというようなことだけなんですが。



本来同じ名前のファイルは同一フォルダには存在できないのですが、上の図では同じ名前のファイルが存在してしまっているように見えます。
実はこれ同じように見えるけれども違うファイル名です。
上のファイルの「が」という文字は「か」+「゙」というUnicodeの結合文字列なのです。
参考サイトでは半濁点で説明していますが、これは濁点の結合文字列の例です。

で、この結合文字列の「が」と普通の「が」をWideComparStrやWideCompareTextで比較すると0が返ります。上の二つのファイルをWideCompareTextで比較すると本来違うはずのファイル名であっても同じであるという値の0が返ってくるわけです。
検索などの場合はそれでいいのでしょうが、ファイル名の比較の場合はそれでは困ります。
ファイル名の比較はWideUpperCaseで大文字に変換して比較するということをしなければなりません。

  if (WideUpperCase(ls_File1) = WideUpperCase(ls_File2)) then begin
    //同じファイル名であったときの処理
  end else begin
   //違うファイル名であったときの処理
  end;

この場合ファイル名の違いは分かってもその大小は分かりません。ファイルのソートなどでファイル名の大小の値が必要な場合はWideCompareTextとの併用が必要になります。


この結合文字列を普通にAnsiStringでキャストすると「か?」となってしまいます。
それをきちんと「が」にするにはWC_COMPOSITECHECKを指定したWideCharToMultiByte APIを使う必要があります。

function gfnsWideToAnsi(sSrc: WideString): AnsiString;
{結合文字列をきちんとAnsiStringに変換。
例)「が」→「が」みたいな感じで。
}
var
  li_Len:  Integer;
  lp_Buff: PAnsiChar;
begin
  //WC_COMPOSITECHECKが肝
  li_Len := WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, PWideChar(sSrc), -1, nil, 0, nil, nil);
  Inc(li_Len);
  lp_Buff := AllocMem(li_Len);
  try
    WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, PWideChar(sSrc), -1, lp_Buff, li_Len, nil, nil);
    Result := AnsiString(lp_Buff);
  finally
    FreeMem(lp_Buff);
  end;
end;

今回のようなUnicodeの合成文字は上図のJIS2004対応フォントを入れていないと文字化けします。


OS(XP)を再インストールしたところだめになってしまいました。
AnsiStringでキャストしたときと同じように「が」ではなく「か?」になってしまいます。

私のPCだとXPのSP3を適用するとシステムの休止状態ができなくなるので再インストール後はSP2にとどめているので、そのせいなのかも知れません。

と、思ったらいつの間にか「か?」ではなくちゃんと「が」に変換できるようになっていました。
XPはSP2のままなのですが、、一体何がきっかけなのだろうか…