tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板
VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板
[ツリー表示へ]  [ワード検索]  [Home]

タイトル Re^7: ファイルパスの機種依存文字を取得する方法について
投稿日: 2014/12/03(Wed) 12:50
投稿者魔界の仮面弁士
> またUnicode 対応コントロールを用意してあるだけでもありません。

Label の代用とする、TextOutW API のサンプルを書いてみました。

下記では説明のため、フォーム上から直接 API を呼んでいますが、
描画処理を UserControl 化しておくと、通常の Label の代用として使えるかと。

Option Explicit

Private Declare Function TextOutW Lib "GDI32" (ByVal hDC As OLE_HANDLE, ByVal nXStart As Long, ByVal nYStart As Long, ByVal lpString As Long, ByVal cbString As Long) As Long

'第1引数:Form/PictureBox/Printerのいずれかの hDC プロパティ
'第2引数:描画させたい文字列
'第3、第4引数:描画先の座標
Private Sub DrawText(ByVal h As OLE_HANDLE, ByVal Text As String, ByVal x As Integer, ByVal y As Integer)
    '2014/12/09 削除
    'Dim s As String
    's = Text & vbNullChar
    'TextOutW h, x, y, StrPtr(s), Len(s)

    '2014/12/09 差し替え
    TextOutW h, x, y, StrPtr(Text), Len(Text)
End Sub

Private Sub Form_Load()
    Picture1.AutoRedraw = True
    Picture1.ScaleMode = vbPixels
    Picture1.BorderStyle = 0
End Sub

Private Sub Command1_Click()
    'Picture1.Cls
    DrawText Picture1.hDC, "[" & ChrW(&H33A5) & "]立方メートル", 30, 30
    Picture1.Refresh

    'PictureBox や Form を渡す場合は、描画完了後に
    'Refresh メソッドを呼び出すことで、
    'API からの描画結果を反映させる
End Sub

Private Sub Command2_Click()
    Printer.Print " ";
    DrawText Printer.hDC, "[" & ChrW(&H33A5) & "]立方メートル", 30, 30
    Printer.EndDoc
    
    '印刷情報が何も無いときには、Printer.EndDoc を呼び出しても
    '何も出力されない。そのため、Printer に対して API で描画する場合は、
    'あらかじめ、空白文字を Print しておくと良い。
End Sub


> コモンダイアログでファイルを選択(パスを取得)した時点で文字化けますか?
試してみていただければ分かるかと思いますが、ダイアログの表示が
化けるわけではありません。化けるのは、String 型プロパティの内容です。

具体的には、FileName プロパティ、InitDir プロパティ、DialogTitle プロパティなどです。

そのため、今回問題としているようなファイルパスを扱おうとすると、
選択されたファイル名を正しく受け取れず、"?" などに化けてしまいます。
取得だけではなく、初期表示のパスを指定する場合も同様です。


> 表示の仕様のみで、管理では取得されているということはないですか?

コントロールが内部で呼び出している API が違うので、どうしようもありません。

コモンダイアログ コントロールが内部で呼び出しているのは
GetOpenFileNameA API であり、文字列は ANSI 文字列(Shift_JIS 相当)となります。
GetOpenFileNameW API であれば、Wide 文字列(Unicode)になるのですけれどね。


> GDI+ Flat APIのページは英文でC言語で書かれてますよね?
C++ 言語ではないでしょうか? C 言語ではなく。


> "AV"というVBのAPIの宣言をコピーできるフリーソフトにもないので
> 自分では理解できないと思います。
GDI+ Flat API を使ったサンプルは、過去に何度か投稿していますが、
そのものズバリなコードを毎回作っているわけでは無いので、
API 仕様を見て、自分で記述できるだけの力量が求められますね…。



> ファイルパスの機種依存文字を取得する方法について
> などの内容も対応されている・・?

はい。.NET 世代の VB は、Unicode パスを問題なく扱うことが出来ます。

そうでないバージョン(VB5、VB6、VBA6.x、VBA7.x など)においては、
今回述べてきたように、Unicode パスを扱う機能を備えていません。


そもそも Windows 3.1 の頃は、Unicode を扱えませんでした。
これは VB2 や VB4/16 などの時代ですね。

Windows 95 の登場時に、少数の Unicode API、いわゆる「〜W 系」の API が
サポートされましたが、大部分は「〜A 系」な ANSI バージョンのままでした。
これは VB4/32 や VB5 の時代ですね。


ただしこれらの時代であっても、Windows NT 系列の OS であれば、Unicode API が
採用されていました。ただし互換性のため、同じ機能を持つ ANSI バージョンの API も
同時に用意されていました。


このことから、
・「〜A 系」API なら、WinNT 系でも Win9x系 でも 動作する。
・「〜W 系」API だと、WinNT 系では動くが、Win9x 系で動作しない。
という状況が生まれます。

このような事情から、VB4〜VB6 においては、言語仕様的には Unicode 対応ですが、
OS 機能の呼び出しには、基本的に ANSI バージョンの API を使う仕組みになっています。

中には、OS の種別に応じて、〜A と 〜W を切り替えるような実装としたコントロールも
あるのですが、少なくとも VB5 Learning 付属のコントロールはそうなっていないということです。


> VBのバージョンが最新になると標準でサポートされている内容が増える・・・?
バージョンアップすれば、新しい機能が追加されていくのは確かにその通りですが、
逆に、不要とされた機能が廃止される可能性もありますよ。

たとえば、VB5 の OLEオブジェクトコントロールは、VB.NET には用意されていません。
(旧VB と VB.NET の違いについては過去に何度か話題になっていますので、過去ログを参照してみて下さい)


それはさておき:

必ずしも、常に「最新」バージョンを追い続ける必要は無いと思いますが、
だからといって、あまりにも古いバージョンに固執することはお奨めしません。

サポートの切れた古いツールを使い続けることには限界があるので、
VB201x 世代の新しいバージョンへの移行を検討しておくのが賢明かと思います。

なお、VB.NET 2002/2003 世代も避けておきましょう。今となっては旧世代の言語仕様です。
少なくとも VB2005 以降(できれば 2008 以降)がお奨めです。最新は 2013 ですね。

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。