タイトル | : Re^7: ファイルパスの機種依存文字を取得する方法について |
記事No | : 16043 |
投稿日 | : 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 ですね。
|