<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Recent changes to AutoSave</title><link>https://sourceforge.net/p/sakura-editor/wiki/AutoSave/</link><description>Recent changes to AutoSave</description><atom:link href="https://sourceforge.net/p/sakura-editor/wiki/AutoSave/feed" rel="self"/><language>en</language><lastBuildDate>Sun, 11 Nov 2012 01:51:31 -0000</lastBuildDate><atom:link href="https://sourceforge.net/p/sakura-editor/wiki/AutoSave/feed" rel="self" type="application/rss+xml"/><item><title>WikiPage AutoSave modified by novice123</title><link>https://sourceforge.net/p/sakura-editor/wiki/AutoSave/</link><description>[内部構造](Design)＞自動保存 

# 自動保存 #
2000/10/15

サクラエディタの自動保存は指定された間隔で上書き保存を呼び出すだけのものです．

## CPassiveTimerクラス ##
クラス名は**CPassiveTimer**ですが，ファイル名はCAutoSave.(cpp|h)です．なぜなら，このクラス自身は時間の経過を管理するだけでファイルの保存とは無関係だからです．

このクラスは指定された時間が経過したら決められた動作をするものですが，自分ではWindowsのタイマーを管理しません．**CheckAction**メソッドが呼び出されたときにのみ経過時間をチェックします．

自動保存の間隔は分単位で精度は要求されていないため，既にファンクションキー表示やDrag&amp;Dropで使っているタイマーを利用しています．

### データ構造 ###

    DWORD nLastTick; // 最後にチェックしたときの時刻
    int nInterval; // Action間隔 (分)
    bool bEnabled; // 有効かどうか


計測の開始時に**GetTickCount**で得られた値を**nLastTick**に保存しておき，**CheckAction**が呼ばれたときに**GetTickCount**で得られた値と**nLastTick**との差分を計算して**nInterval**を越えていないか確認します．

TickCountの値は49日でカウンタが一周してしまいますが， unsignedな変数を使っているので，結果が負数になることはありません．

### bool CheckAction() ###
タイマーで定期的に呼び出される箇所でこのメソッドを定期的に呼び出します．**SetInterval**で設定された時間が経過しているとtrueが，まだ経過していなければfalseが返ります．呼び出し元では戻り値がtrueの時に何かを行うようにすれば定期実行が可能になります．

規定時間が経過してtrueを返したときは，そこから新たに計測を開始します．

### void Enable(bool flag) ###
タイマーの有効／無効を設定します．設定値の読み出しは IsEnabledで行います．

無効に設定されているときは**CheckAction**で必ずfalseが返ります．また，false→trueに設定を変更すると内部カウンタがリセットされてそこから時間のカウントが始まります．というよりも，リセットされたときと現在との差分しか見ていないので途中まで経過した時間の続きからという器用なことは出来ないのです．

## 自動保存の動作 ##
実際に**CPassiveTimer**を使ってどのように自動保存が行われているかを説明します．

### 初期化 ###
**CEditDoc**クラスの1要素として**CPassiveTimer**クラスの**m_cAutoSave**が宣言されています．

共有データの値を**m_cAutoSave**に設定する**CEditDoc::ReloadAutoSaveParam**が**CEditDoc**のコンストラクタから呼び出されます．また，設定の変更メッセージ(MYWM_CHANGESETTING)を受けたときには**CEditWnd::DispatchEvent**から呼び出されます．

**CEditDoc::ReloadAutoSaveParam**では間隔を設定してタイマーを有効にします．

コンストラクタでタイマーを有効にしてしまうと
  1. 共有メモリに正しいデータが入っていない
  1. 他のオブジェクトが初期化される前に呼び出されてしまう
といった危険性があるように思えますが，**CEditWnd**が生成される前に**WinMain**で設定の読み出しが行われていることと，規定時間経過後の実行は**CEditWnd**のタイマーメッセージが来て初めて行われることから，このような問題は起こらないと信じています．（弱い(^^ゞ）

### 時間の監視 ###
定期的なタイマー呼び出しにより，**CEditWnd::OnTimer**が呼び出されます．この中から**CEditDoc::CheckAutoSave**が呼ばれます．

**CEditDoc::CheckAutoSave**では**m_cAutoSave**の**CheckAction**を呼び出して戻り値をチェックします．戻り値がtrueのときは自動保存を一旦Disableにしてから**SaveFile**を呼び出し，保存終了後に再びEnableにします．保存時にDisableにするのは保存時にダイアログボックスが表示された状態で所定の時間が経過することによって**SaveFile**が二重に呼び出されるのを防ぐためです．
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">novice123</dc:creator><pubDate>Sun, 11 Nov 2012 01:51:31 -0000</pubDate><guid>https://sourceforge.net62c517ae6f2a4505dd164cb75164fb3290ed773b</guid></item></channel></rss>