CEditのスクロールバーの制御について。

解決


めるめる  2004-12-08 19:07:44  No: 55544  IP: [192.*.*.*]

初めて書き込みします、宜しくお願いします。

現在、エディットボックス(マルチライン)にログを書き出してます。
ログが追加された際にはスクロールを行い、常に最新のログが最下行に
表示されるようにしています。
しかし、過去のログを参照したい場合に(上方へ)スクロールした場合、
見ている最中にログが追加された場合は強制的にスクロールしてしまいます。
(当たり前ですが。)
そこで「スクロールバーが最下にない場合はスクロールしない」と言う動作
にしたいのですが、CEditのメンバを使って出来る方法はあるのでしょうか?
MSDNともにらめっこしてるのですが・・・

過去ログで関連事項を見つけましたがこのような事をしないと制御
できないのでしょうか?
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200211/02110041.txt

環境:W2K、VC6SP3です。
宜しくお願いします。

編集    削除
RAPT  2004-12-09 11:50:34  No: 55545  IP: [192.*.*.*]

サブクラス化して自前で処理をするしかないでしょう。
文字列長を求めて、カーソルの位置を算出して、と。

編集    削除
なーめ  2004-12-09 15:56:35  No: 55546  IP: [192.*.*.*]

ログの追加をシミュレートするため、OnTimer になっていますが、
以下の要領でどうでしょう。
(呼び出しは SetTimer(1,1000,NULL);)
m_csText は CString を IDC_TEXT (EditControl) に割り付けたもの。
m_cedText は CEdit を同じく IDC_TEXT に割り付けたものです。
なお、縦スクロールのみの対応ですが。
GetSel() なので、選択領域もクリアされません。

void CCednoscDlg::OnTimer(UINT nIDEvent) 
{
  if( nIDEvent == 1 )
  {
    int s,e,l,k = m_cedText.GetFirstVisibleLine(); // 先頭行保存
    m_cedText.GetSel( s,e ); // カーソル位置保存
    UpdateData(TRUE);
    CTime ct = time(NULL);
    m_csText += ct.Format( "%y/%m/%d %H:%M:%S\r\n" ); // ログの追加
    UpdateData(FALSE);
    l = m_cedText.GetFirstVisibleLine(); // アップデート後の先頭行
    m_cedText.LineScroll( k-l,0 ); // 先頭行がずれた分だけスクロール
    m_cedText.SetSel( s,e );  // カーソル位置を復元
  }
  CDialog::OnTimer(nIDEvent);
}

編集    削除
なーめ  2004-12-09 16:14:22  No: 55547  IP: [192.*.*.*]

訂正:
×カーソル位置
○キャレット位置

DOSじゃないのだから...

編集    削除
めるめる  2004-12-09 19:09:36  No: 55548  IP: [192.*.*.*]

回答ありがとうございます。
丁度GetFirstVisibleLine()を使うのを、
昨晩考えてました。
なーめさんの回答を元に、ちょっと頑張って見ます。
ありがとうございました。

編集    削除
めるめる  2004-12-10 00:49:06  No: 55549  IP: [192.*.*.*]

出来ました。折角なのでソースを。
エディットボックスはm_Editとしました。
また、エディットボックスの高さは52行に設定してます。
--------------------------------------------------
// 現在表示してるログの最上位のIndexを取得
TopLineIndex = m_Edit.GetFirstVisibleLine();
m_Edit += "hogehoge"; // ログ更新
UpdateData( FALSE );
iLineCnt = m_Edit.GetLineCount(); // 現在の行数取得

// スクロール
if (m_nLogTopLineNo < (UINT)iLineCnt - 53){←※
     m_Edit.LineScroll(TopLineIndex );
}else{
     m_Edit.LineScroll(iLineCnt);
}
--------------------------------------------------
※53行目が追加された場合は、if内部が0 < 0となる為
普通にスクロールします。(最新を表示する。)
またこの状態で、スクロールバーを戻して1行目を設定すると、
54行目が追加された場合でも、if内部が0 < 1となる為、
TopLineIndex分しかスクロールしません。

取り合えずこれで・・・いいかな?って感じです。
ありがとうございました。

編集    削除