毎々参考にさせていただいております。
過去ログを参照しましたところ、
http://madia.world.coocan.jp/cgi-bin/VBBBS/wwwlng.cgi?print+200302/03020044.txt
のURLと全く同じ現象なのですが、ここにある方法では解決できなかったため、
質問させていただきます。
こちらを参考にプログラムを組んでいるのですが。。。
http://www.bcap.co.jp/hanafusa/VBHLP/Apointrow.htm
コントロール配列で複数のテキストボックスに対して、SendMessageのEM_GETLINE
をしようして、ループで文字列を取得しようとしているのですが、複数回の実行
で文字列取得に成功するテキストボックスやしないテキストボックスが変わった
り、実行ごとに非常に不安定な動作になってしまっています。失敗するときの
SendMessageの戻り値及びErr.LastDLLErrorは0で返ってきます。
安定させる方法をどなたかに御教示いただければ嬉しいです。
よろしくお願いします。
環境は
VB6.0 SP6
WINDOWS XP Pro SP2
です。
おかしいと思われる症状が再現出来るコードを
提示されない限り、アドバイスは無理でしょうね。
我龍院さん、失礼しました。
確かにそうですね。コードは下記のような感じです。
Dim i As Integer
Dim Length As Long
Dim TempText As String * 256
Dim GetText As String
For i=0 To 254
If Me.Text1(i).Text <> "" Then
TempText = ""
Length = SendMessage(Me.Text1(i).hWnd, EM_GETLINE, i, ByVal TempText)
GetText = RTrim$(Left$(TempText, Length))
End If
Next
で、きちんと取れるときはLengthが0以外になるのですが、失敗するときは
なぜかLengthが0になり、GetTextが""になる次第です。
よろしくお願い致します。
横から失礼。
> Length = SendMessage(Me.Text1(i).hWnd, EM_GETLINE, i, ByVal TempText)
これって、コントロール配列にしたTextBoxが255個あって、
1番のTextBox(Me.Text1(0))の1行目
2番のTextBox(Me.Text1(1))の2行目
3番のTextBox(Me.Text1(2))の3行目
・・・・
255番のTextBox(Me.Text1(254))の255行目
を参照しているように見えますが・・・
例えば、255番目のTextBoxは、255行ありますか?
無ければ、当然0が返ってきますけど・・・
#「If Me.Text1(i).Text <> "" Then」この条件だと、
#「255行目があるかどうか」は判断できませんし・・・
大吉末吉さん、ご回答ありがとうございます。
申し訳ありません。ソースの貼付ミスです。。
貼付用に実際のやつを簡略化した際に間違えてしまいました。
Dim i As Integer
Dim Length As Long
Dim TempText As String * 256
Dim GetText As String
Dim MaxRow As Long
For i=0 To 254
If Me.Text1(i).Text <> "" Then
MaxRow = SendMessage(Me.Text1(i).hWnd, EM_GETLINECOUNT, 0&, 0&)
For j=0 To MaxRow-1
TempText = ""
Length = SendMessage(Me.Text1(i).hWnd, EM_GETLINE, j, ByVal TempText)
GetText = RTrim$(Left$(TempText, Length))
Next
End If
Next
正しくはこんな感じです。すみませんでした。。
実際にはループ中で、何か別の処理をしているのですよね?
# 提示されたコードでは、ループ中に変数の値を上書きしているので、
# 最終的な GetText の値は、Text1(254) の末尾データになってしまう。
で、コードを見る限り、いろいろと問題があるようで。
> Dim TempText As String * 256
> TempText = ""
> Length = SendMessage(Me.Text1(i).hWnd, EM_GETLINE, j, ByVal TempText)
EM_GETLINE の場合、lparam の先頭 2 バイトには、
「バッファの最大サイズ」を指定する必要があるかと。
http://msdn2.microsoft.com/en-us/library/ms672074.aspx
> GetText = RTrim$(Left$(TempText, Length))
ANSI バージョンなら、戻り値は「文字数」ではなく「バイト数」なので、
単純に Left で切り出してしまってはマズいかと。
Unicode バージョンなら「文字数」が返されますが、その場合は、
バッファは String 型ではなく、Byte 配列にしてください。
魔界の仮面弁士さん、いつもありがとうございます。
さらに調べた結果、下記コードで今のところ安定するようになりました。
http://pc2.2ch.net/tech/kako/1047/10477/1047743187.html
の871さんの書込を参照しました。
Dim i As Integer
Dim j As Integer
Dim Length As Long
Dim TempText() As Byte
Dim GetText As String
Dim MaxRow As Long
Dim Index As Long
For i=0 To 254
If Me.Text1(i).Text <> "" Then
MaxRow = SendMessage(Me.Text1(i).hWnd, EM_GETLINECOUNT, 0&, 0&)
For j=0 To MaxRow-1
TempText = ""
Index = SendMessage(Me.Text1(i).hWnd, EM_LINEINDEX, CLng(i), 0&)
Length = SendMessage(Me.Text1(i).hWnd, EM_LINELENGTH, Index, 0&)
ReDim TempText((Length - 1) + 1)
CopyMemory TempText(0), Length, 2
Length = SendMessage(Me.Text1(i).hWnd, EM_GETLINE, CLng(j), TempText(0))
GetText = StrConv(LeftB(TempText, Length), vbUnicode)
Next
End If
Next
前のコードでは正常に動いたり動かなかったりしたので、これでしばらく様子をみたいと思います。
我龍院さん、大吉末吉さん、魔界の仮面弁士さん、ありがとうございました。
ツイート | ![]() |