タイトル | : Re^8: Windowsのシステムで使用しているフォントの取得。 |
記事No | : 14297 |
投稿日 | : 2009/11/25(Wed) 02:15 |
投稿者 | : 魔界の仮面弁士 |
> 下記のようなコードで動作確認をしています。 私は、 >>> コピー & ペーストで検証可能なコードが提示されれば、 と書きましたが、提示されたコードは Declare 等がありませんので、 残念ながら、第三者が検証することはできる物にはなっていないようです。
元のコードをある程度想像することはできますが、ByVal/ByRef の宣言の違いや、 As Any/As Long/As ユーザー定義型 の違いなどで、動作が異なってしまう事も 珍しくないので、API 宣言部まで含めて提示していただいた方が指摘しやすいです。
> Private Const LF_FACESIZE = &H20 > Private Type LOGFONT 中略 > lfFaceName(LF_FACESIZE) As Byte > End Type
Option Base は 0 なのですよね? だとしたら、宣言が間違っていると思います。 元となる WinGDI.h においては、この宣言は 》 CHAR lfFaceName[LF_FACESIZE]; と定義されています。つまり、32文字分の領域を持つメンバということです。しかし、 ヨシさんが書かれた宣言では、0 To 32 の範囲すなわち 33 バイトの領域になっています。
また、上記の宣言を使おうとしているとことは、現在の Declare 宣言では、 SystemParametersInfoA を用いているのかと想像します。
文字列を扱う API に対して、ANSI 版の実装を利用しようとする場合、VB6 では Unicode と既定の文字コードとの間で、暗黙の変換作業が入ることになります。 多言語対応にする場合、この時点での破損を防ぐ意味でも、文字コード変換の伴わない SystemParametersInfoW などの Wide 版 API を用いた方が良いかと思いますよ。
> dim strResult as string > dim lngRet as long > dim A as LOGFONT > dim i as integer 実際のコードからコピーしてきたものではありませんね?
> strResult = strResult & Chr(A.lfFaceName(I)) 多言語対応するのであれば、Chr 関数は避けた方が良いかと。 StrConv を第3引数付きで呼び出すか、もしくは、そもそも ANSI 処理は避け、 すべて Unicode 版 API で制御するようにしてみてください。
> Text1.Font.Charset = 128 ここで、128 という固定値をセットしているようですが、それは この段階で、A.lfCharSet の内容も 128 になっていたという事でしょうか。
> Text1.Font = strResult Font プロパティに String を渡してはまずいでしょう。
フォント名を渡すなら、 Text1.Font.Name = strResult と書くべきですし、Font プロパティにフォントそのものを渡す意図なら、 Dim F As Font Set F = New StdFont F.Name = … F.Size = … F.CharSet = … : Set Text1.Font = F のようになるかと。
> A.lfFaceName に格納される値は、バイト型で下記になります。 > 183 > 76 > 63 > 182 > 174 > 182 > 192 合計7バイト、という事ですね。
お使いの中国語の文字コードは何ですか? (Big5 とか GB2312 とか) また、本来取得されるべき文字列は、何という文字列ですか?
>(おそらく「微軟正K體」) 漢字5文字だとしたら、7バイトしか無いのは間違っていますよね。
微軟正K體だとしたら、 繁体字中国語(Big-5) :B7,4C,B3,6E,A5,BF,B6,C2,C5,E9 簡体字中国語(GB2312):CE,A2,DC,9B,D5,FD,BA,DA,F3,77 Unicode (UTF-16):AE,5F,DF,8E,63,6B,D1,9E,D4,9A 日本語 (Shift_JIS):94,F7,93,EE,90,B3,FC,4B,E9,93 と 10 バイトにエンコードされる事でしょう。しかし、提示の7バイトは、 B7,4C,3F,B6,AE,B6,C0 という事で、上記どれとも一致していませんので、API の扱いに そもそも問題があるように思えます。宣言にしても、Chr 関数を使っている点にしても。
そもそも 〜A系 API ではなく、〜W系の実装を使えば、そうした変換自体が不要ですが、 もしも 〜A系を使うなら、Byte 配列を String に戻す際には、Chr 関数ではなく、 ADODB.Stream 等を用いるか、StrConv の第3引数指定を利用してみてください。
たとえば下記はいずれも、「微軟正K體」を表すバイナリを文字列に復元しています。 (ToBinary という部分は、Byte 配列を表していると思ってください)
Dim buf() As Byte
'日本語(Shift_JIS) buf = ToBinary("94,F7,93,EE,90,B3,FC,4B,E9,93") Debug.Print StrConv(buf, vbUnicode, 1041)
'繁体字中国語(Big-5) buf = ToBinary("B7,4C,B3,6E,A5,BF,B6,C2,C5,E9") Debug.Print StrConv(buf, vbUnicode, 1028)
'簡体字中国語(GB2312) buf = ToBinary("CE,A2,DC,9B,D5,FD,BA,DA,F3,77") Debug.Print StrConv(buf, vbUnicode, 2052)
'Unicode(UTF-16) buf = ToBinary("AE,5F,DF,8E,63,6B,D1,9E,D4,9A") Debug.Print StrConv(buf, 0, 0)
' Vista Business (x64) SP2/ XP Professional (x86) SP3 で動作確認。
なお、StrConv の第3引数に指定した LocaleID が実行環境でサポートされていない場合、 実行時エラーとなります。
|