2012-04-28 14 views
0

私はVisual C++で作成しようとしているかなり大きなアプリケーションを持っており、元に戻す/やり直し機能を追加しようとしています。Visual C++の元に戻す操作とやり直し操作

イベント(ボタンクリックやラベルテキストの変更など)がかなり多いため、すべての機能にコードを追加することなく元に戻す/やり直す方法を見つけたいと思います。 インスタンスの場合、すべてのイベントを読み込んで自動的に保存できるクラスが必要です。その後、私の元に戻す/やり直しのイベントでは、私はちょうど最新のアクションを保存することができます。

これが可能でない場合は、私は別の方法を気にしません。

助けが必要ですか?

+2

エラー処理のように取り消しをやり直すことは、後から改築するよりも、最初から建設すること。がんばって! – Cameron

答えて

2

2つの操作、つまり取り消しとやり直しを表すクラスを宣言します。 また、そのクラスの2つのベクトルを作成します。

元に戻す/やり直しを適用する操作ごとに、そのクラスのインスタンスを元に戻します。取り消したいオプリメントと同数の派生クラスが存在する必要があります。

例えば、ボタンをクリックすると背景が緑色に塗りつぶされた場合、metdoが背景を前の色に塗りつぶすundoのクラスインスタンスを作成し、そのredoメソッドが背景を緑色に塗りつぶして元に戻す。 元に戻すと、最後のクラスのインスタンスがポップアップされ、元の色にバックグラウンドをペイントするundoメソッドが呼び出されます。次に、それをやり直しベクトルにプッシュします。

あなたがやり直しをすると、上のクラスインスタンスのやり直しベクトルがポップされ、そのやり直しメソッドが呼び出され、取り消しベクトルに戻されます。

いくつかのコーナーケース(境界)があり、遭遇したとき、あなたがそれらに取り組むだろうが... :-)

+0

ありがとうございました。マウスクリックイベントを自動的に取得できるように、実際にイベントを自動的に呼び出す方法が望まれていましたが、それは不可能だと思います。 +1が受け入れられました。 – SuperPrograman

1

あなたのすべてのイベントは、いくつかの種類のキューを通過するのですか?デフォルトではC++にはこのようなキューはありません(Windows OSレベルのイベントキューがありますが、これはおそらくC++では使用できなくなり、cliであり、これがあなたの問題に密接に関連しているかどうかを示していないでしょう)私が知らない他の構成体。

セントラルキューがある場合は、イベントが通過するときにキャプチャし、各アクションを元に戻す方法を知るだけです。中央のキューが存在しない場合は、取り消し可能な各関数を変更してある種の取り消しオブジェクトを作成し、それを格納して元に戻すキューよりも簡単な方法はありません。

大きなセントラルワークキューを持たない純粋なネットやC++環境では、元に戻すためのメソッド/メンバ関数を実装するクラスと、元に戻すメソッドと、別のオブジェクトをやり直す/実行するクラスを作成します。しかし、単に元に戻す機能のために、これはちょうど.netデリゲートかCスタイルの関数ポインタと引数のリストかもしれません。アクションを元に戻す/やり直すクラスを作成する場合は、do/undo関数へのポインタ/デリゲートを格納するテンプレートやジェネリック、および元々呼び出されたときの引数のリストを使用できます。

これを実行すると、実行されたアクションを元に戻すことができます。それらは何らかの種類のキューコンテナに挿入されます。コンテナの種類は順序を保持するほど長くはないようですが、アプリケーションに最適なstd、.net、またはその他のコンテナを選択する必要があります。古いものはもはや必要がなくなったら廃棄することができます。実行時に、一貫性を保つために最後にキューに挿入されたエントリを削除する必要があります。

また、やり直し機能が必要な場合は、完了したアクションのキューが反復可能でなければならず、そのクラスを使用するのが最も簡単で、アクションにはメソッド/メンバ関数があり、あなたは、あなたが元に戻した距離を示す何らかの種類のイテレータ、ポインタ、インデックス、またはマーカーを持っています。取り消しが要求されるたびに、マーカーを後方に(時間順に)戻し、その時点で取り消しコマンドを実行する必要があります。 redoが要求された場合、指定された現在の項目はredo命令を実行し、イテレータはキューを順方向(時間順)に進められます。キューの最前部にある場合は無視されます(私は推測します)。

あなたが望む方法がない深いところから離れたい場合は、アクションキューの周りにアプリを集中させることができます。このアプローチを実装する機能を変更する必要はありません。あなたのユーザーインターフェイス(私は、あなたのAPIと同じように簡単かもしれません)を実装し、アクションを(実行と元に戻すことをサポートする)キューに挿入し、キューにコマンドを実行します。副作用がわかっていて元に戻すことができれば、既存の機能を変更する必要はありません。ただし、直接呼び出すのではなく、すべての呼び出し元を変更してアクションを実行する必要があり、元に戻す操作を行う相手を記述する必要があります。

1

私は小さな実験的なライブラリ:https://github.com/d-led/undoredo-cppのようなものを実現しようとしました。それにはCodeChordsの男性と同様のTransactionStoreの実装が含まれています。取り消し可能なオブジェクトのそれぞれに実際に機能を追加する必要があるかもしれません。また、オブジェクトの作成や破棄が必要な場合にオブジェクトのライフタイムを処理する必要があります。

+0

ありがとう!私はそれをチェックします。本当に面白いです。 – SuperPrograman