none
VB6からWindows APIのDrawTextを使用すると「12×23」が「23×12」と出力される RRS feed

  • 質問

  • はじめて投稿させていただきます。よろしくお願い致します。

    Windows APIのDrawTextを使用したVB6のプログラムで「12×23」が「23×12」となる現象が発生
    しており、以下のサイトのプログラムで検証したところ、『DT_END_ELLIPSIS』を設定した場合に
    再現することができました。
    http://support.microsoft.com/kb/154517/ja

    OSによって発生しない場合もあり、以下の点で問題があるのではないかと考えていますが、
    不具合等の情報があればお教えいただけないでしょうか。
    1. VB6からDrawTextを使用する場合の問題
    2. User32.dllのバージョンの問題

    環境の詳細は以下となります。
    <言語>
    Visual Basic 6.0 SP6

    <プログラム>
    DrawTextの描画オプションに『DT_END_ELLIPSIS』を設定する

    <発生するOS>
    Windows XP SP3(User32.dllのバージョン:5.1.2600.5512)
    Windows 2003 SP2(User32.dllのバージョン:5.2.3790.3959)
    Windows 7(User32.dllのバージョン:6.1.7600.16385)

    <発生しないOS>
    Windows 2000 SP4(User32.dllのバージョン:5.0.2195.7032)

    <発生する文字列のパターン>
    数値×文字列
    数値*文字列
    数値÷文字列

    • 編集済み ひろり 2011年1月31日 10:50 例としてあげていた『「1×2」が「2×1」』が現象を的確に表現していないため修正
    2011年1月31日 2:14

回答

  • DT_END_ELLIPSISを10進数(32768)で書けば起きませんので、そういう問題だと思います。

    つまり、0x8000が-32768と解釈され、それがLongに変換され、結果的にDT_RTLREADING(0x20000)のビットが立ったのではないかと。

    もうVBは完全に忘れてしまったので、言語的な説明ができませんですみません。

     

    • 編集済み データくん 2011年1月31日 3:57 誤字訂正
    • 回答としてマーク ひろり 2011年1月31日 11:57
    2011年1月31日 3:56

すべての返信

  • DT_END_ELLIPSISを10進数(32768)で書けば起きませんので、そういう問題だと思います。

    つまり、0x8000が-32768と解釈され、それがLongに変換され、結果的にDT_RTLREADING(0x20000)のビットが立ったのではないかと。

    もうVBは完全に忘れてしまったので、言語的な説明ができませんですみません。

     

    • 編集済み データくん 2011年1月31日 3:57 誤字訂正
    • 回答としてマーク ひろり 2011年1月31日 11:57
    2011年1月31日 3:56
  • DT_END_ELLIPSISを10進数(32768)で書けば起きませんので、そういう問題だと思います。

    つまり、0x8000が-32768と解釈され、それがLongに変換され、結果的にDT_RTLREADING(0x20000)のビットが立ったのではないかと。

    素早いご回答ありがとうございます。
    ご指摘いただいたとおりでした。

    プログラムでは以下のように明示的に型を指定しておらず、デバッグ実行で確認したところ
    -32768と認識されていました。

    Private Const DT_END_ELLIPSIS = &H8000

    -32768はLong型では0xFFFF8000となり、DrawTextで使用できる以下のビットが立っている状態
    で実行していたということですね。

    ・DT_END_ELLIPSIS = &H00008000
    ・DT_MODIFYSTRING = &H00010000
    ・DT_RTLREADING = &H00020000
    ・DT_WORD_ELLIPSIS = &H00040000

    お教えいただいたように10進数で指定するか、明示的にLong型を指定することで解決できました。

    Private Const DT_END_ELLIPSIS = 32768 ' (符号付16bitでは32768は表現できない)
    Private Const DT_END_ELLIPSIS = &H8000&

    参考として、調査中に見つけたページを記載します。
    <DrawText関数>
    http://msdn.microsoft.com/ja-jp/library/cc428474.aspx
    <DrawTextの修正プログラム>
    http://support.microsoft.com/kb/819628/

    (DT_RTLREADINGを使うことはないと思いますが、動作が少々気になりました。本稿の解決に無関係ですが。。。)

    2011年1月31日 11:56