ViViはVC++等のエディタと同じようにドキュメントを編集するとタイトルバーに "*" が表示されます。 保存を行うと消去され、undo/redo でもちゃんと更新されます。ドキュメントが変更され、 かつ未保存状態であることがすぐに解るので大変便利な機能です。
例によって最初はウィンドウタイトルの文字列を変更する方法が分からず苦労しましたが、
目的とするメソッドは、CDocument::SetTitle(LPCSTR) です。
これを使用するとMDIでも正しくタイトル文字列を更新してくれます。SetWindowText ではうまくいきません。
更新はビューでドキュメントを修正し、CDocument::SetModifiedFlag をコールするタイミングで行っています。
プログラムは以下のような感じです。
void CViviView::setModifiedFlag(BOOL flag) { CViviDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CString title = pDoc->GetTitle(); // 現在のタイトル文字列を取得 if( flag ) { // ドキュメントが更新された場合 if( title.GetLength() < 2 || title.Right(2) != " *" ) { title += " *"; // " *" を付加する pDoc->SetTitle(title); } } else { if( title.GetLength() > 2 && title.Right(2) == " *" ) { title = title.Left(title.GetLength() - 2); // " *" を削除 pDoc->SetTitle(title); } } pDoc->SetModifiedFlag(flag); // ドキュメントのフラグを更新 pDoc->redrawAllViews(this); }
undo/redo でも状態表示を更新しなくてはいけません。そのために各 undo item は undo/redo
を行ったときにモディファイフラグをOFFにするかどうかの情報を保持しています。
情報は独立な2ビットで表現されます。ひとつは undo でフラグがOFFになるかどうか、
もうひとつは redo でOFFになるかどうかです。それぞれ UNDO_MF_OFF, REDO_MF_OFF で表します。
たとえば状態#Nで保存された場合、undo item のフラグは以下のように設定されます。
: : : ┏━━━━━━━━━━━━┓ ┃ドキュメント状態#N−2┃ ┗━━━━━━━━━━━━┛ ↑│ undo││redo │↓ ┏━━━━━━━━━━━━┓ ┃ドキュメント状態#N−1┃ ┗━━━━━━━━━━━━┛ ↑│ undo││redo REDO_MF_OFF │↓ ビットを立てる ┏━━━━━━━━━━━━┓ ┃ ドキュメント状態#N ┃ ┗━━━━━━━━━━━━┛ ↑│ UNDO_MF_OFF undo││redo ビットを立てる │↓ ┏━━━━━━━━━━━━┓ ┃ドキュメント状態#N+1┃ ┗━━━━━━━━━━━━┛ ↑│ undo││redo │↓ ┏━━━━━━━━━━━━┓ ┃ドキュメント状態#N+2┃ ┗━━━━━━━━━━━━┛ : : : |
undo/redo の処理を行うときは、このフラグを参照し、モディファイフラグの更新を行います。
また、編集操作により undoItem を追加するときは、ドキュメントのモディファイ状態をチェックし、
クリーン状態ならば UNDO_MF_OFF ビットを立てます。
void CUndoMgr::addUndoItem(CUndoItem *undoItem, CViviDoc *pDoc) { if( !pDoc->IsModified() ) undoItem->m_flags |= UNDOITEM_UNDO_MF_OFF; ..... }
Copyright (c) 1997 by Nobuhide Tsuda, All Right Reserved.
このホームページに関するご質問、ご要望、バグレポート等は
ntsuda@beam.or.jp
までメールをいただければ幸いです。