[リストへもどる]   [VBレスキュー(花ちゃん)]
一括表示

投稿時間:2005/03/21(Mon) 17:09
投稿者名:kuro3
Eメール:
URL :
タイトル:
リッチテキストボックスを用いたターミナル
kuro3といいます。
良く覗かせていただいておりますが、書き込むのは初めてとなります。

実は、リッチテキストボックスを使用しまして、
ターミナル関係のアプリを作り初めているのですが、障害にあたってしまいました。
できましたら知恵をお貸しいただけないでしょうか。

1)やりたいこと
  リッチテキストボックスの文字列が、501行以上になったら、
  下から500行を残して文字列を削除すること。

2)いま問題となっていること。
  ・処理が遅すぎる。
   受信文字が、すごい勢いで増えており文字列削除のスピードが
   間に合わなくなってしまいました。
  ・画面がちらつく

3)具体的処理内容
  0.タイマー処理にて受信した文字をリッチテキストボックスに追記
    (seltextにて行っております。)
  @.こちらのHPにて紹介されております行数取得の手法にて、
    リッチテキストボックス全体の行数を削除
  A.(全体の行数-500行)にて削る必要のある行数をチェック
  B.リッチテキストボックスの先頭から、削る必要がある分だけ、
    instrを用い改行コードの位置を検索
  C.Bで検索した改行コードの位置をもとにRightコマンドで、
    500行分の文字列を作成
  D.Cで作った文字列をリッチテキストボックスに貼り付け


処理がおそいのは、3−B,Dあたりでもたついていると考えているのですが、
画面がちらつくほうはなにがなにやらと言った状況です・・・。

アドバイスいただけましたら幸いです。

投稿時間:2005/03/21(Mon) 20:19
投稿者名:Say
Eメール:
URL :
タイトル:
Re: リッチテキストボックスを用いたターミナル
>    受信文字が、すごい勢いで増えており文字列削除のスピードが
>   0.タイマー処理にて受信した文字をリッチテキストボックスに追記
Timerを使っている以上、せいぜい1行10msec程度だと思いますが、
その程度の速度で処理が間に合わないことはありませんが・・・。

そもそもリッチテキストボックス上で処理しようというのが間違いです。
処理は裏でやって、リッチテキストボックスは表示に徹するべきです。

ま、こんなかんじ

Option Explicit
Private Const BUFMAX As Long = 10240
Private Const LINEMAX As Long = 499
Dim buf(BUFMAX) As String
Dim buf2(LINEMAX) As String
Dim ptr As Long
Dim richidx As Long
Private Sub Command1_Click()
     Command1.Enabled = False
    Command2.Enabled = True
   Timer1.Interval = 10
    Timer1.Enabled = True
End Sub

Private Sub Command2_Click()
    Command1.Enabled = True
    Command2.Enabled = False
    Timer1.Enabled = False
End Sub

Private Sub Form_Load()
    Dim i As Long
    For i = 0 To BUFMAX
        buf(i) = "[" & CStr(i + 1) & "]   " & String(Int(Rnd() * 10) + 5, _
                 Chr(Asc("A") + Int(Rnd() * 26)))
    Next
    richidx = 0
    ptr = 0
    For i = ptr To ptr + LINEMAX
        buf2(i) = buf(i)
    Next
    RichTextBox1(0).Visible = False
    RichTextBox1(1).Visible = False
    RichTextBox1(richidx).Text = Join(buf2, vbCrLf)
    RichTextBox1(richidx).Visible = True
    Command1.Caption = "START"
    Command2.Caption = "STOP"
    Command1.Enabled = True
    Command2.Enabled = False
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Timer1.Enabled = False
End Sub

Private Sub Timer1_Timer()
    Dim richidx2 As Long, i As Long
    richidx2 = (richidx + 1) Mod 2
    ptr = ptr + 1
    If ptr > BUFMAX - LINEMAX Then ptr = 0
    For i = ptr To ptr + LINEMAX
        buf2(i - ptr) = buf(i)
    Next
    RichTextBox1(richidx2).Text = Join(buf2, vbCrLf)
    RichTextBox1(richidx).Visible = False
    richidx = richidx2
    RichTextBox1(richidx).Visible = True
End Sub

投稿時間:2005/03/21(Mon) 23:07
投稿者名:kuro3
Eメール:
URL :
タイトル:
Re^2: リッチテキストボックスを用いたターミナル
> Timerを使っている以上、せいぜい1行10msec程度だと思いますが、
実は、5msecで3行づつ増えてました。
その段階でtimerを使う発想がよくなかったのでしょうか。

>     RichTextBox1(0).Visible = False
>     RichTextBox1(1).Visible = False
>     RichTextBox1(richidx).Text = Join(buf2, vbCrLf)
>     RichTextBox1(richidx).Visible = True

ここの部分についてなのですが、実行しようとすると
引数の数が一致してません。または不正な値を指定しています。
と、いわれてしまいました。
これは、VB6以下で使えるコマンドなのでしょうか。
よくわかっておらず、申し訳ありません。

ちなみに、当方いまさらですが、VB6であります。

投稿時間:2005/03/22(Tue) 03:55
投稿者名:Say
Eメール:
URL :
タイトル:
Re^3: リッチテキストボックスを用いたターミナル
> > Timerを使っている以上、せいぜい1行10msec程度だと思いますが、
> 実は、5msecで3行づつ増えてました。
> その段階でtimerを使う発想がよくなかったのでしょうか。
リアルタイムで拾いたかったら、ループで拾うことになるでしょう。

> これは、VB6以下で使えるコマンドなのでしょうか。
コードを見れば、RichTextBoxがコントロール配列になっていることぐらい
わかると思いましたが・・・。

投稿時間:2005/03/22(Tue) 23:48
投稿者名:kuro3
Eメール:
URL :
タイトル:
Re^4: リッチテキストボックスを用いたターミナル
返信遅くなり申し訳ありません。

> > > Timerを使っている以上、せいぜい1行10msec程度だと思いますが、
> > 実は、5msecで3行づつ増えてました。
> > その段階でtimerを使う発想がよくなかったのでしょうか。
> リアルタイムで拾いたかったら、ループで拾うことになるでしょう。
そうですか。
ループで拾う段階で処理速度的に厳しそうな雰囲気でした。

> > これは、VB6以下で使えるコマンドなのでしょうか。
> コードを見れば、RichTextBoxがコントロール配列になっていることぐらい
> わかると思いましたが・・・。
失礼しました。気づけてしかるべき内容でした・・・。

投稿時間:2005/03/23(Wed) 02:04
投稿者名:Say
Eメール:
URL :
タイトル:
Re^5: リッチテキストボックスを用いたターミナル
> ループで拾う段階で処理速度的に厳しそうな雰囲気でした。
ループで間に合わないものがタイマーで間に合うはずもありません。
もし、取得+表示を一度に行うのに処理速度的に無理があるなら、
たとえば取得と表示のプロセスをわけて、共有メモリなどを使ってプロセス通信する、
といった工夫が必要でしょう。
(表示に若干のラグは発生するでしょうが、とりこぼしはなくせます。)

投稿時間:2005/03/23(Wed) 02:49
投稿者名:kuro3
Eメール:
URL :
タイトル:
Re^6: リッチテキストボックスを用いたターミナル
> > ループで拾う段階で処理速度的に厳しそうな雰囲気でした。
> ループで間に合わないものがタイマーで間に合うはずもありません。
そうなのでしょうか?
タイマーで受信文字を受け取ってから、文字列操作関係の処理は、
なるべくメモリ内でおこなうようにしたほうが結果的に早くなると思うのですが・・・?
極端な話を例にするとループ処理をした場合、受信文字1文字に対して処理を行う形にすると、
パフォーマンスが落ち、結果タイマーより悪くなるような印象を受けてました。
と、書いているうちに気づいたのですが、もしかすると↓で書いて
いただいている内容がそういうことでしょうか・・・。
私の能力的に、プロセスを分けられる領域に届いていないですが・・・。
がんばってみます。

> もし、取得+表示を一度に行うのに処理速度的に無理があるなら、
> たとえば取得と表示のプロセスをわけて、共有メモリなどを使ってプロセス通信する、
> といった工夫が必要でしょう。
> (表示に若干のラグは発生するでしょうが、とりこぼしはなくせます。)

投稿時間:2005/03/23(Wed) 12:40
投稿者名:Say
Eメール:
URL :
タイトル:
Re^7: リッチテキストボックスを用いたターミナル
「リアルタイムで拾いたかったら」という前提の話だったと思いますが?
結局のところ、どこでバッファリングを行い、
どの程度のリアルタイム性が必要で、
現実に単位時間あたりの情報量がどのぐらいあるのかしだいです。

バッファリングはドライバか何かで行っていて取りこぼしはありえず、
Timerで拾える程度の頻度で一括取得できればOKというなら、それでいいのでは?

投稿時間:2005/03/23(Wed) 22:08
投稿者名:kuro3
Eメール:
URL :
タイトル:
Re^8: リッチテキストボックスを・・
Sayさんへ
> 「リアルタイムで拾いたかったら」という前提の話だったと思いますが?
すみません、誤解をさせてしまったようです。
完全なるリアルタイム性は特に求めているつもりはありませんでした。

> バッファリングはドライバか何かで行っていて取りこぼしはありえず、
> Timerで拾える程度の頻度で一括取得できればOKというなら、それでいいのでは?
ここに問題がありまして、Timerで拾える程度の頻度で一括取得はできるのですが、
取得したデータをリッチテキストボックスで表現するさいにもたついてしまうことを、
一番の問題としております。
二番目の問題としましては、画面のちらつきと考えてます。

花ちゃんさんからも指摘がありましたので、一度必要条件について
記事No.2544の返信にまとめてみたいと思います。

投稿時間:2005/03/21(Mon) 20:39
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re: リッチテキストボックスを用いたターミナル
どの処理が遅いかは、実際のコード上で測定すれば解るはず。
原因が解ればするべき事も見えてくるでしょう。
又、発想を変えて実際に手作業で行を削除する場合どのようにしますか?

5Mバイトのファイルでも瞬時に削除できます。
Instr 関数を使用するとどうなるか Debug.Print InStr(RichTextBox1.Text, vbCrLf) これだけで
数秒かかってしまいます。
コピーやペーストも結構時間がかかっているはず。

Private Sub Command1_Click()
    Dim i As Long
    i = 10      '10行削除(総行数-500)
    With RichTextBox1
        .SetFocus
        .SelStart = 0
        SendKeys "+{DOWN " & i & "}"
        SendKeys "{DELETE}"
    End With
End Sub

(実際に使用する場合は SendKeys を使用しないで API を使うようにして下さい)

総行数を取得するのはAPIを使って 総行数-500 分繰り返せば実行する頻度にもよりますが
1回当たり数行を削除するだけで済むかと思います。
画面のチラツキも表示の頻度が頻繁なのが原因なのである程度の文字数を受信した時に
表示するようにすればチラツキが抑えられるのでは。

投稿時間:2005/03/21(Mon) 21:37
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^2: チラツキ防止(修正分)
改良版がUPしてあるのでこれは削除しておきます。

投稿時間:2005/03/21(Mon) 21:44
投稿者名:kuro3
Eメール:
URL :
タイトル:
Re^3: チラツキ確認
花ちゃんさんSayさん返信ありがとうございます。
ちょっと、私には難しくて即答できなさそうなので、
いったん返信させていただきました。
もう少し試した後、改めて返信させていただきたいと思います。
ありがとうございました。

投稿時間:2005/03/22(Tue) 00:11
投稿者名:kuro3
Eメール:
URL :
タイトル:
Re^3: チラツキ防止(修正分)
花ちゃんさんへ
いけそうな感じです。
ありがとうございます。

しかし、ターミナルの使用でDELキーを気かなくしているので、
少しこの後の苦労はありそうです・・・。
ちょっとがんばってみます。

投稿時間:2005/03/22(Tue) 01:29
投稿者名:kuro3
Eメール:
URL :
タイトル:
Re^3: チラツキ防止(修正分)
花ちゃんさんへ

kuro3です。
私なりにがんばってみたのですが、行き詰ってしまい、また返信させていただきました。
紹介させていただいた方法を用いてみたのですが、何点か課題が沸いて発散中です。

1)SendKeys "+{DOWN " & i & "}"の処理を行っているときに、
  リッチテキストボックスの内容の選択部分が反転処理され、
  ちらついてしまいました。
  また、この部分の処理にそれなりに時間がかかってそうな印象をうけました。


2)SendKeys "{DELETE}"にて削除する後に、
  カレットを最終に移動したくて.SelStart = 2147483647を実行すると
  SendKeys "{DELETE}"の処理がキャンセルしてしまいました。


処理自体は早くなってうれしいのですが、まだ理解しきれていないところがあり
恐縮ですが、アドバイスいただけないでしょうか。
特にまだ、SendKeys をAPIでやる方法にたどりつけていないのでAPI制御に変えただけで、
直るような内容でしたら非常に申し訳ありません。
参考に今回教えていただいた内容をもとに組んだソースを添付させていただきます。

Private Sub Timer1_Timer()

    '受信文字がないときはなにもしない
    '10msecで5行くらい増えることがあり。
   'インターバルは10msecで設定
    If RS_recv = "" Then 'RS_recv は受信バッファです
        Exit Sub
    End If


    Dim strtmp As String
    Dim MaxRow As Integer
    Dim logbufRow As Long

    On Error GoTo HELL
    
  strtmp = RS_recv
  RS_recv = ""
   Moni_Text.SelStart = 2147483647
  Moni_Text.SelText = Replace(strtmp, Chr(&HD), vbCrLf)
  RS_recv = ""

    '総行数を取得する
    MaxRow = SendMessage(Moni_Text.hwnd, EM_GETLINECOUNT, 0&, 0&)
    'いらない行数をチェックする。
    If MaxRow >= logbuf_max.Text + 1 Then  '505行を超えたら処理開始
        logbufRow = logbuf.Text + 1
        senddel = 1 'delキーを一時的に使えるように
        With Moni_Text
            .SetFocus
            .SelStart = 0
            SendKeys "+{DOWN " & (MaxRow - logbufRow) & "}" '500行を超えた分で処理
            SendKeys "{DELETE}"
       '.SelStart = 2147483647  '左記を実行するとDELがキャンセルされる。
        End With
    End If
    Exit Sub

    
HELL:
    MsgBox ("エラー
End Sub

投稿時間:2005/03/22(Tue) 08:09
投稿者名:
Eメール:
URL :
タイトル:
Re^4: チラツキ防止(修正分)
…ところで、他のコントロール(リストボックスとか、普通のテキストボックスとか)では代用できない
ん?
もしくは、そのようなコントロールを作る、とか…

投稿時間:2005/03/22(Tue) 23:51
投稿者名:kuro3
Eメール:
URL :
タイトル:
Re^5: チラツキ防止(修正分)
> …ところで、他のコントロール(リストボックスとか、普通のテキストボックスとか)では代用でき
ない
> ん?
いろいろ考えたのですが、使い方を考えるとリッチテキストになってしまいました。
確かにリストボックスを使うと消すのは早かったりするのですが、
多めにログをとりたい場合もありまして・・・。

> もしくは、そのようなコントロールを作る、とか…
それだけの力があればいいのですが ToT

投稿時間:2005/03/23(Wed) 01:57
投稿者名:Say
Eメール:
URL :
タイトル:
Re^6: チラツキ防止(修正分)
> 確かにリストボックスを使うと消すのは早かったりするのですが、
> 多めにログをとりたい場合もありまして・・・。
だから、コントロール上にログを蓄える、というのが間違いなのです。
ログは配列にとって、ListBoxは表示に徹すれば、
行数が足りないなんてことはないのでは?
何万行も一度に表示しても使いにくいだけです。

投稿時間:2005/03/23(Wed) 03:08
投稿者名:kuro3
Eメール:
URL :
タイトル:
Re^7: チラツキ防止(修正分)
アドバイスありがとうございます。

> > 確かにリストボックスを使うと消すのは早かったりするのですが、
> > 多めにログをとりたい場合もありまして・・・。
> だから、コントロール上にログを蓄える、というのが間違いなのです。
> ログは配列にとって、ListBoxは表示に徹すれば、
> 行数が足りないなんてことはないのでは?
> 何万行も一度に表示しても使いにくいだけです。
いまいろいろ、実験して確かにコントロールにもつのは失敗かと思い始めてきました。
実際、ログはは数万とはいらないですが、多いときは1万行程度のログはとりたい思ってます。
また、ほかに、
・検索をしたいこと
・部分のコピーを行いたいこと(文字単位)
・色をつけたいこと
から、リッチテキストを選んだのですが.seltextで追記しているだけでも、
1万行も書いているともたつくという現実にうちひしがれておりました。

投稿時間:2005/03/22(Tue) 08:15
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^4: チラツキ防止(修正分)
もう少し発想を変えて見ます。
受信中500行に拘る必要もなさそうなので、受信処理の前後に500行にカットする
ようにして、受信中は文字数で管理します。
下記のように追加書き込みするのではなく置き換え処理をします。追加書き込みより
処理も早く、チラツキがまったくありません。
"あ" の部分に書き込む文字を指定して下さい。

Private Sub Timer1_Timer()
    Dim n As Long
    RichTextBox1.SelStart = 2147483647
    '現在の文字数を取得
    n = Len(RichTextBox1.Text)
    '現在の文字列を現在の文字列+追加書き込みした文字数で置き換える
    RichTextBox1.Text = Right$(RichTextBox1.Text & "あ", n)
End Sub

投稿時間:2005/03/23(Wed) 00:24
投稿者名:kuro3
Eメール:
URL :
タイトル:
Re^5: チラツキ防止(修正分)
返信ありがとうございます。
ためしてみたのですが、残念ことにNGでした。
まず、この手法ですと実際にはリターンコードがまじり改行が生じると、
ちらついてしまいました。
また、説明不足で申し訳ないのですが、一行の文字数はそれなりに違いまして、
文字での管理はあまり望ましくないのいった状態です・・・。
ただ、確かに文字での処理をしたほうが早いという印象を受けました。

ちらつきに関しましては、実際にはスクロールバーがすごい勢いで動きまして、
画面も流れている感じにならないのです。
具体的には、下記コードを実行いただけましたら体感いただけると思います。
もし、改善策が浮かびましたもう暫しお付き合いいただけたらありがたいです。


'前処理
'RichTextBox1.ScrollBars を 3に設定願います。
Private Sub Form_Load()

   'リッチテキストに複数行をデータを用意しておく。
   RichTextBox1.Text = "hjkljfajslkfjal" + vbCrLf + _
   "hjkljfajslkfjal" + vbCrLf + "hjkljfajslkfjal" + vbCrLf + "hjkljfajslkfjal" + vbCrLf + _
     〜中略〜
   "hjkljfajslkfjal" + vbCrLf   


End Sub

Private Sub Timer1_Timer()
    Dim n As Long
    RichTextBox1.SelStart = 2147483647
    '現在の文字数を取得
    n = Len(RichTextBox1.Text)
    '現在の文字列を現在の文字列+追加書き込みした文字数で置き換える
    RichTextBox1.Text = Right$(RichTextBox1.Text & "あ" + vbCrLf, n)  
    RichTextBox1.SelStart = 2147483647
    '現在の文字数を取得
    n = Len(RichTextBox1.Text)
    '現在の文字列を現在の文字列+追加書き込みした文字数で置き換える
    RichTextBox1.Text = Right$(RichTextBox1.Text & "しくしくしく" + vbCrLf, n)

End Sub

投稿時間:2005/03/23(Wed) 10:21
投稿者名:ダンボ
URL :
タイトル:
SelStartとSelTextの利用
質疑応答の前の部分は読んでいません。従って的外れかも。

ただTimer1_Timerの部分のコーディングは、あまりにも非効率で、
これでは処理も遅いしちらつくのも当然と思います。
下記でよいのでは。

Private Sub Timer1_Timer()
    '現在の文字列の最後にカーソルを持っていく
    RichTextBox1.SelStart = Len(RichTextBox1.Text)
    RichTextBox1.SelText = "あ" + vbCrLf
    RichTextBox1.SelText = "しくしくしく" + vbCrLf
End Sub

投稿時間:2005/03/23(Wed) 22:10
投稿者名:kuro3
Eメール:
URL :
タイトル:
Re: SelStartとSelTextの利用(修正)
ダンボさんへ
申し訳ないです、ターミル処理をしたさいのちらつきの
再現を意識して作成したコードでした。

投稿時間:2005/03/23(Wed) 11:06
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
必要条件(どうしても譲れない)は?
> まず、この手法ですと実際にはリターンコードがまじり改行が生じると、
> ちらついてしまいました。
私はチラツキではなく処理が早いので流れる感じだと思っておりますが。

> また、説明不足で申し訳ないのですが、一行の文字数はそれなりに違いまして、
> 文字での管理はあまり望ましくないのいった状態です・・・。
少し多めに設定しておいて、受信完了後希望の行数に設定すればいいのでは
受信中の行数はどうせ解らないし影響があるとは思えませんが?

> ただ、確かに文字での処理をしたほうが早いという印象を受けました。
ファイルサイズが大きくなれば処理速度が極端に落ちるようでこのままでは
使えないかと思います。
(500行と10000行ではまったく動作が違ってきますから)

> ちらつきに関しましては、実際にはスクロールバーがすごい勢いで動きまして、
> 画面も流れている感じにならないのです。
同じ文字を表示しているせいですね。

1行当たり受信文字数はどの位でしょうか? 半角だけでしょうか?
大よそのファイルサイズはどの位でしょうか? この辺が大きく影響してきますので。
510行以上に位になったら500行にカットするといった方法でもいいのでしょうか?
その他、譲れない条件を書いて頂かないと・・・・・・・。
Timer1.Interval はどの位に設定されているのでしょうか?
処理が遅れた場合データの取りこぼしはおこらないのでしょうか?
1回の受信は1行分なのでしょうか? どの時点で改行がはいるのでしょうか?

限定できる条件等は書いていただいた方がより早い方法が出てくるかも知れません。

たとえば、新しいデータを先頭行に書き込み最後の行を削除するような方法でも
いいとか(これですと処理が早く無駄の動きが少ないのでチラツキも少ないかと)

受信はテキストボックスでしながら、時々その受信したデータをリッチテキストボックスに
書き込みといった方法でもいいのかとか

どうせ受信中は編集できないのだから受信はテキストボックスでして受信終了後
必要な行数をリッチテキスト移すのではだめでしょうか?


タイマーコントロールを2個使って受信と削除の処理を別けるとか
といった色々な方法が考えられるので、どれがいいかは条件次第になるかと。

投稿時間:2005/03/23(Wed) 23:05
投稿者名:kuro3
Eメール:
URL :
タイトル:
Re: 必要条件(どうしても譲れない)は
花ちゃんさんへ
返信ありがとうございます。
> 私はチラツキではなく処理が早いので流れる感じだと思っておりますが。
そうですか・・・、当方WIN2KとVB6の環境なのですが、
RichTextBox1.SelStart = 2147483647
↑の処理を行った瞬間カレットは、リッチテキストボックス内の
一番下に移動し、(スクロールバーも一番したにスクロールされます。)次に、
RichTextBox1.Text = Right$(RichTextBox1.Text & "あ" + vbCrLf, n) 
の処理を行った瞬間カレットは、リッチテキストボックス内の
一番上に移動する(スクロールバーも一番したにスクロールされます。)と、
いった現象となっております。
その結果、スクロールバーが一番上と下をいききしてちらついておりました。


> 少し多めに設定しておいて、受信完了後希望の行数に設定すればいいのでは
> 受信中の行数はどうせ解らないし影響があるとは思えませんが?
実は受信文字については、一行あたり改行コードを除くと、
最小で0文字
最大は無制限(ただし基本的に50〜100文字程度)
と、ばらつきが大変多い状況なんです・・・。
そこで、行数単位での処理を行いたいと考えました。

> > ただ、確かに文字での処理をしたほうが早いという印象を受けました。
> ファイルサイズが大きくなれば処理速度が極端に落ちるようでこのままでは
> 使えないかと思います。
> (500行と10000行ではまったく動作が違ってきますから)
ご指摘のとおりです。
現状500行ですら悩んでいる状態で10000行単位での同等処理は、
厳しいとは悟りはじめました。

> > ちらつきに関しましては、実際にはスクロールバーがすごい勢いで動きまして、
> > 画面も流れている感じにならないのです。
> 同じ文字を表示しているせいですね。
文頭のほうで書かせていただいたような現象で、当方の環境では、
スクロールバーおよびカレットが上下を行き来することで、
ちらついてみえました。

> 1行当たり受信文字数はどの位でしょうか? 半角だけでしょうか?
改行コードを除いて
最小で0文字
最大は無制限(ただし基本的に50〜100文字程度)
と、なっており、受信文字は半角限定です。
ただし、送信時には全角も使用しておりまして、そのために、
リッチテキストボックス内の状態としては、全角/半角交じりとなっております。

> 大よそのファイルサイズはどの位でしょうか? この辺が大きく影響してきますので。
一行の文字数が、違いすぎて明確な解答はできないのですが、多い場合で、
50文字×行数(今は500行)くらいと思います。
(実際に、全角を送信をする機会は少ないので文字数としては無視してよいと
 考えております。)

> 510行以上に位になったら500行にカットするといった方法でもいいのでしょうか?
よいです。(が、品格的にどちらかというと501→500行がのぞましいと考えてます。)

> その他、譲れない条件を書いて頂かないと・・・・・・・。
すみません。
一度まとめて、記事No.2544に返信という形で追記するようにいたします。

> Timer1.Interval はどの位に設定されているのでしょうか?
現状は10msecとしております。

> 処理が遅れた場合データの取りこぼしはおこらないのでしょうか?
現状は、500行ではないです。
最初の記事で記載させていただいた処理の
  B.リッチテキストボックスの先頭から、削る必要がある分だけ、
    instrを用い改行コードの位置を検索
  C.Bで検索した改行コードの位置をもとにRightコマンドで、
    500行分の文字列を作成
  D.Cで作った文字列をリッチテキストボックスに貼り付け
ここのあたりの処理でもたつき、表示が遅くなりますが・・・。
理論的な話ですと、データを取りこぼしについては発生します。
ただし、別途通信分でチェックしワーニング処理を行います。
(基本的に、取りこぼしは起きないようにしたいと思っております。)

> 1回の受信は1行分なのでしょうか? どの時点で改行がはいるのでしょうか?
両方の解答となりますが、特に決まっておりません。
タイマーでポーリングしたタイミング次第となっております。

> 限定できる条件等は書いていただいた方がより早い方法が出てくるかも知れません。
了解しました。

> たとえば、新しいデータを先頭行に書き込み最後の行を削除するような方法でも
> いいとか(これですと処理が早く無駄の動きが少ないのでチラツキも少ないかと)
みずらくなるので、避けたいと考えております。

> どうせ受信中は編集できないのだから受信はテキストボックスでして受信終了後
> 必要な行数をリッチテキスト移すのではだめでしょうか?
実は受信中も編集できるようにしてました・・・。
(即時処理というわけではないですが、キー入力を受け付けて文字を相手がたに
 送信して、そのログはリッチテキストボックスに表示されるようにしております。)

投稿時間:2005/03/23(Wed) 23:41
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
続きは新しいスレッドで
> ↑の処理を行った瞬間カレットは、リッチテキストボックス内の
> 一番下に移動し、(スクロールバーも一番したにスクロールされます。)次に、
> RichTextBox1.Text = Right$(RichTextBox1.Text & "あ" + vbCrLf, n) 
> の処理を行った瞬間カレットは、リッチテキストボックス内の
> 一番上に移動する(スクロールバーも一番したにスクロールされます。)と、
> いった現象となっております。
> その結果、スクロールバーが一番上と下をいききしてちらついておりました。

どこが違うのでしょうかね。私の環境ではスクロールバーは動きません。

とりあえず、レスが長くなり見づらくなったので パートU と言う事で
新しいスレッドで質問するようにして下さい。

投稿時間:2005/03/23(Wed) 13:46
投稿者名:K.J.K.
Eメール:akiya@koalanet.ne.jp
URL :
タイトル:
Re: リッチテキストボックスを用いたターミナル
同様の意見も出ていますが、一応。

まず、RichTextBoxにしなければならないのか?
500行固定、というのであれば、ListBoxのがむしろ向いている
かもしれません。表示や編集で問題がなければ、ですが。

で、Windows2000以降の環境でVB6のRichTextBoxコントロールを
使うと、速度面での問題がでてきます。文章が短い場合はそれ
ほどでもありませんが、長くなると顕著になります。

その原因は、内部でUnicode-Ansi-Unicode-Ansiと無駄な変換を
何度も繰り返すからです。対策としては、Sel???プロパティを
一切使わず、全てAPI関数を直接呼び出すこと、などが挙げられ
ます。もしくは、EichEdit Ver2.0以降をOCX化したコントロール
を探して使う、辺りでしょうか。

投稿時間:2005/03/23(Wed) 23:11
投稿者名:kuro3
Eメール:
URL :
タイトル:
Re^2: リッチテキストボックスを用いたターミナル
K.J.K.さんへ
返信ありがとうございます。

> まず、RichTextBoxにしなければならないのか?
> 500行固定、というのであれば、ListBoxのがむしろ向いている
> かもしれません。表示や編集で問題がなければ、ですが。
文字単位でのコピーを行いたいので、リッチテキストを選んでみました。
たしかに、リストボックスの方が削除処理等早いと考えております。

> で、Windows2000以降の環境でVB6のRichTextBoxコントロールを
> 使うと、速度面での問題がでてきます。文章が短い場合はそれ
> ほどでもありませんが、長くなると顕著になります。
最近、体感中です・・・。

> その原因は、内部でUnicode-Ansi-Unicode-Ansiと無駄な変換を
> 何度も繰り返すからです。対策としては、Sel???プロパティを
> 一切使わず、全てAPI関数を直接呼び出すこと、などが挙げられ
そうですね、それが一番よいのかもしれないです。
ただ、情けない話現在、まだ私のレベルはそこに到達できておりません。

> ます。もしくは、EichEdit Ver2.0以降をOCX化したコントロール
> を探して使う、辺りでしょうか。
情報ありがとうございます。
週末あたり探してみようと思います。

投稿時間:2005/03/23(Wed) 23:42
投稿者名:ガッ
Eメール:
URL :
タイトル:
Re^3: リッチテキストボックスを用いたターミナル
> 文字単位でのコピーを行いたいので、リッチテキストを選んでみました。
> たしかに、リストボックスの方が削除処理等早いと考えております。
ノ<ココらで代用品を少し考えて見しょう。

1テキストボックスで代用することを考えてみる。
細かな書式が必要なく、文字列を表示するだけならばテキストボックスのほうが楽。
なんとなく速い気もする。標準コントロールである。
などから、私はこれを推奨します。

2リストボックスで代用することを考えてみる。
編集(書き込み or 切り取り)を行わず、文字単位でコピーする必要が無いならば、
リストボックスで複数選択可能にして、行単位でコピーしてみるとかは?
ノ<コピー操作はClipBoard.Clearした後に、ClipBoard.SetTextで出来ます。

…操作のデザインをしっかり組めば、
(コピー&閲覧用の)単行テキストボックス&(高速な追加&削除用の)リストボックスで代用が可能かと

…なんとなく思いましたw;

投稿時間:2005/03/24(Thu) 09:05
投稿者名:Say
Eメール:
URL :
タイトル:
Re^4: リッチテキストボックスを用いたターミナル
> 1テキストボックスで代用することを考えてみる。
> 細かな書式が必要なく、文字列を表示するだけならばテキストボックスのほうが楽。
> なんとなく速い気もする。標準コントロールである。
> などから、私はこれを推奨します。
TextBox.textは最大128KB(64K文字)までしか格納できません。
「10000行扱いたい」という条件を満たすのはきびしいかも。

投稿時間:2005/03/25(Fri) 01:47
投稿者名:kuro3
Eメール:
URL :
タイトル:
Re^5: リッチテキストボックスを用いたターミナル
> > 1テキストボックスで代用することを考えてみる。
> > 細かな書式が必要なく、文字列を表示するだけならばテキストボックスのほうが楽。
> > なんとなく速い気もする。標準コントロールである。
> > などから、私はこれを推奨します。
> TextBox.textは最大128KB(64K文字)までしか格納できません。
> 「10000行扱いたい」という条件を満たすのはきびしいかも。

正直な気持ちとたぶんベースな解答では、Sayさんの言われるとおりテキストボックスは、
厳しいと考えてました。
また、テキストに色をつける野望がありまして・・・。
最初に条件の明確化を行っておらず申し訳ありませんでした。

また、パートUのスレッドを作成させていただきましたので、
できましたら、おすすめ案がありましたらパートUに記載いだだけたら、
大変うれしいです。

投稿時間:2005/03/23(Wed) 23:40
投稿者名:kuro3
Eメール:
URL :
タイトル:
リッチテキストボックスを用いたターミナル(必要条件を補足しました。)
kuro3です。
必要条件につきまして補足で記載させていただきました。
かじょ書き状態でまとめさせていただきました。
できましたら、ご一読いただけないでしょうか。

テキスト表示系
・文字単位でのコピーを行うこと。
 (3行目の5文字目から、6行目の3文字目など)
・文字を色分けできること。
・文字は、半角/全角混じりです。

ターミナルとして、絶対やりたいこと。
・500行程度のログをちらつきなしで、表示したい。
 (目視したい)
・多少ちらついても、1万行オーバーのログをとりたい。
・ログは上から下にながし、
 受信文字の最終行を、一番したに表示すること。
 

送受信環境(参考です)
・受信文字列は、半角のみ。
・送信文字列は、全角あり。(使用頻度小)
・送信文字の改行コード間の文字数は、
 0〜無制限(実際は、0〜100文字程度です。)
・受信文字は、1秒で400行程度更新されております。
 もっと、あがる可能性はありますが・・・。

OSなど
・win2k pro + vb6

以上です。

以下、元記事です。
> kuro3といいます。
> 良く覗かせていただいておりますが、書き込むのは初めてとなります。
>
> 実は、リッチテキストボックスを使用しまして、
> ターミナル関係のアプリを作り初めているのですが、障害にあたってしまいました。
> できましたら知恵をお貸しいただけないでしょうか。
>
> 1)やりたいこと
>   リッチテキストボックスの文字列が、501行以上になったら、
>   下から500行を残して文字列を削除すること。
>
> 2)いま問題となっていること。
>   ・処理が遅すぎる。
>    受信文字が、すごい勢いで増えており文字列削除のスピードが
>    間に合わなくなってしまいました。
>   ・画面がちらつく
>
> 3)具体的処理内容
>   0.タイマー処理にて受信した文字をリッチテキストボックスに追記
>     (seltextにて行っております。)
>   @.こちらのHPにて紹介されております行数取得の手法にて、
>     リッチテキストボックス全体の行数を削除
>   A.(全体の行数-500行)にて削る必要のある行数をチェック
>   B.リッチテキストボックスの先頭から、削る必要がある分だけ、
>     instrを用い改行コードの位置を検索
>   C.Bで検索した改行コードの位置をもとにRightコマンドで、
>     500行分の文字列を作成
>   D.Cで作った文字列をリッチテキストボックスに貼り付け
>
>
> 処理がおそいのは、3−B,Dあたりでもたついていると考えているのですが、
> 画面がちらつくほうはなにがなにやらと言った状況です・・・。
>
> アドバイスいただけましたら幸いです。