DOBON.NET DOBON.NETプログラミング掲示板過去ログ

WM_GETTEXTについて

  • 題名: WM_GETTEXTについて
  • 著者: ferguson
  • 日時: 2003/08/28 0:45:21
  • ID: 475
  • この記事の返信元:
    • (なし)
  • この記事への返信:
  • ツリーを表示
分類:[VB6以前]

今下記のようなソースを使用していますが、以下の部分がよくわかりません。
どなたか教えて頂けないでしょうか?

※1について
wParamについてはByte数+Null分なのでEditTextLen + 1なのはわかるのですが、
lParamのTextBuff(0)がよく分かりません。なぜTextBuff(0)なのでしょうか?

※2について
gTextBuff = StrConv(TextBuff(), vbUnicode)のTextBuff()はなぜ添字なしの
配列を指定しいるのでしょうか?これはTextBuff()のすべてをUnicodeに変換する
意味なのでしょうか?

VBをはじめてまだ間もないため、検討違いの質問をしていたら申し訳ありません。
長々書いて申し訳ありませんが、よろしくお願い致します。

'---------------------------------------------------------------
' 関数名: GetEditboxText
' 機能 : メモ帳の文字列を取得する
' 引数 : (in) hEditbox … メモ帳のエディットボックスのハンドル
' 返り値 : 正常:取得した文字列 エラー:空文字
'---------------------------------------------------------------
Public Function GetEditboxText(ByVal hEditbox As Long) As String

Dim TextBuff() As Byte 'メモ帳の文字列格納バイト配列
Dim EditTextLen As Long 'メモ帳の文字列サイズ
Dim ret As Long
Dim gTextBuff As String '取得した文字列

'メモ帳の文字列サイズ取得
EditTextLen = GetEditboxLenB(hEditbox)

'サイズが0なら終了
If EditTextLen = 0 Then Exit Function

'バッファ確保
ReDim Preserve TextBuff(EditTextLen - 1) As Byte

'メモ帳からテキスト取得
※1 ret = SendMessage(hEditbox, WM_GETTEXT, EditTextLen + 1, TextBuff(0))

If ret = 0 Then Exit Function

'ANSI→ UNICODE変換
※2 gTextBuff = StrConv(TextBuff(), vbUnicode)

GetEditboxText = strNullCut(gTextBuff)

End Function
  • 題名: Re[1]: WM_GETTEXTについて
  • 著者: ピラルク
  • 日時: 2003/08/29 23:03:56
  • ID: 516
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
■No475に返信(fergusonさんの記事)

まず型として、以下のようになります。
(3つ目はSourceでは未登場ですが)

Debug.Print TypeName(TextBuff(0)) ' Byte
Debug.Print TypeName(TextBuff()) ' Byte()
Debug.Print TypeName(TextBuff) ' Byte()

> ※1について

数値配列のデータは、常にメモリ上で連続した領域に配置される
ので、先頭のアドレスさえ渡せれば必要な情報は渡せているから。

(参)▼DLL プロシージャへの配列の引き渡し
http://www.microsoft.com/japan/developer/library/VBCon98/vbconpassingarraystodllprocedure.htm

> ※2について

Byte配列ならVBはそれを文字列として認めてくれる。
でも、ByteならCStr()を通したような数値→数字の変換
が行われる。

▼詳細
VB6以前では、Byteの1次元配列とString型は関数の引数における
型チェックにおいて、かなり互換性を認めているようです。

Dim ba(9) As Byte

ba(0) = Asc("A")
ba(2) = Asc("B")
ba(4) = Asc("C")
''ba(6) = Asc("D") 'あえて飛ばしてみる
ba(8) = Asc("E")

として、

Debug.Print ba()
Debug.Print StrComp(ba(), "ABC" & vbNullChar & "E")
Debug.Print Mid$(ba(), 2)

とした場合、

ABC E
0 'StrCompが0を返すのはString的に同値
BC E

となりました。
Mid$()など通常Stringを扱う関数の引数にByte()型を渡して
も通用するものが多いです。
(ba(6)をあえて飛ばしてみたのは、終端nullではなくByte配列
のsizeから文字列を取得していることを明らかにするため)

ただ完全に互換かというとそうではなく、

Debug.Print "ABC" & vbNullChar & "E" = ba()

というような同値判定はちゃんと(?)「型が一致しません」
と言われます。

Debug.Print "ABC" & vbNullChar & "E" = Trim$(ba())

と、例えば Trim$() をかぶせたら通るようになります。
「Byte配列にTrimかけれるものならやってみな!」とやらし
たら、VBはあっさりとやってしまうんですよね。

Mid(ba(), 2, 2) = "XY"

同じ(本当は同じではない) Mid$()も書き換え版の使い方は、
「型が一致しません」と怒られます。

Dim s As String
s = ba

という代入も可能で、

Debug.Print "s = " & s

で、"s = ABC E" が表示されます。

s = ba(0)

という代入も可能で、こうした場合は、

Debug.Print "s = " & s

で、"s = 65" が表示されます。

ここで、先の結論に到達するわけです。

Byte配列ならVBはそれを文字列として認めてくれる。
でも、ByteならCStr()を通したような数値→数字の変換
が行われる。

全体的には、余計混乱が増したのではないかと思います。(^^;

この一連のVBの動作に、筋道通った理屈を求めるのは
無理があるので、VB(VB6以前)は元々型付けの厳密な
言語ではないので、VB開発陣はそこを前向きに利用し、
より生産性が上がるように、Byte配列とStringに融通
の利く便宜を図ってくれていると解釈するのが自然だ
と思います。


> VBをはじめてまだ間もないため、検討違いの質問をして
いたら申し訳ありません。

いえ、NativeのVBユーザならそんなとこ気にもせず
「動いているから正だ」と判断しがちなところ。
おかげで、私もあらためてVB6ランゲージの懐の深さ(?)
を知ることが出来ました。

DOBON.NET | プログラミング道 | プログラミング掲示板