2010年12月3日金曜日

Windows 7 における VB6 の Strconv 関数の挙動

以前にTwitter上でつぶやいたにも関わらず、きれいさっぱり忘れてしまいなおかつその問題が別の案件で出てしまってさぁどうしよう、と悩んでしまったのでメモとして。

Shift-JIS を扱うプログラムではバイト単位に文字列を操作したいという要求が多いので、例えば「先頭5バイト」などといった場合、次のような書き方が多いと思う。

StrConv( LeftB ( StrConv ( [originalStrings], vbUniCode), 5), vbFromUnicode)

Vista まではこれで問題がないのだけど、Windows7ではStrconv関数内部で呼び出されているAPIの挙動が変化したので、これで抽出した場合でも2バイト文字の先頭1バイトは残ってしまう。VistaまではStrconv関数の処理結果として2バイト文字の先頭だけが残るようなケースでは、その部分を除去してくれていたのだけどWindows7ではそうならずにそのまま返却されてくるんだよねぇ。

対応策としては「1文字ずつ」処理するようなロジックに切り替えることぐらいしか思いついていません。大した手間でもないのでそれで十分だと思います・・・

3 件のコメント:

  1. >VistaまではStrconv関数の処理結果として2バイト文字の先頭だけが残るようなケースでは、その部分を除去してくれていたのだけどWindows7ではそうならずにそのまま返却されてくる

    この部分ですが、この挙動が問題になり調べたところ
    Vistaまでは1バイトが除去ではなく残っているが表示系のプロパティに入れても表示されないだけのようです。
    Windows7にでは1バイト文字が意味不明な2バイトに変わってしまう為に表示されているようです。

    それぞれvbFromUnicode時点とvbUnicode後を再度vbFromUnicodeにしてLenBで調べて見ると上記のような結果になりました。

    返信削除
  2. もう少し調べて以下のことが分りましたので追記しておきます。

    2バイト文字の先頭だけを切った結果の1文字の文字コードは必ず同じものになるようです
    VISTAまでの場合 00h
    Windes7の場合 8145h
    というように必ずなります。

    返信削除
  3. コメント&調査していただいてありがとうございます!

    そのまま返却されてくるのではなく、特定のコードにて返却されるのですね。勉強になりました。

    Vista までは 0x00 ということなので文字列変数における文字終端となる、という動きみたいなのかな?

    返信削除