CFileDialogのopenでディレクトリが戻せない?

[戻る]
らら 2006/10/05(木) 14:55:54
CFileDialogの初期ディレクトリの変更で困っています。VC++6.0

MFC(SDI)で作ったプログラムの実行時、

(1)「開く」を実行(ID_FILE_OPENの処理はMFCに任せています)
(2)「サンプルを開く」(下のソース)を実行
  (一時的に固定のディレクトリを指定して
   CFileDialogでファイルを選択する)
(3)もう一度(1)をする。

上記手順で操作した場合に、
(1)で選択したファイルのディレクトリを(3)で表示するようにしたいのですが、
どうしても(2)で選択したファイルのディレクトリになってしまします。
CFileDialogでカレントディレクトリが変更されるとの情報があったので
SetCurrentDirectory()を使って元に戻してみたのですがダメでした。
何か良い方法がありますでしょうか?


void CMyApp::OnFileSample() 
{
    CString backDir;    
    CString sampleDir = _T("c:\\tmp\\sample");

    //↓カレントディレクトリのバックアップ
    ::GetCurrentDirectory( MAX_PATH, backDir.GetBuffer(MAX_PATH) );

    CString newName;
    CFileDialog dlg( TRUE, "", "", OFN_NOCHANGEDIR | N_HIDEREADONLY | 
OFN_OVERWRITEPROMPT, szFilter );

    //↓固定ディレクトリの指定
    dlg.m_ofn.lpstrInitialDir = sampleDir;
    if ( dlg.DoModal() == IDOK )
    {
        CString newName = dlg.GetPathName();
        //・・・ファイルに対する処理・・・
    }

    //↓ディレクトリを戻す
    ::SetCurrentDirectory(backDir);
}

よろしくお願い致します。

PATIO 2006/10/05(木) 15:33:17
OFN_NOCHANGEDIRを指定して置くとカレントディレクトリは移動しません。
で、dlg.m_ofn.lpstrInitialDir = sampleDir;をやっているわけですから
いくらSetCurrentDirectoryをやっても同じでしょう。
最後に選択した所を次の時に出したいのであれば、
dlg.m_ofn.lpstrInitialDirに設定する値は、毎回前回開いたファイルの位置になるように
変更する必要があります。つまりそのためのパスを保存しておく必要があります。

あと気がついたんですが、
CString内で確保されているバッファはCString側の都合で移動されたりする事もありえると
思うので、
dlg.m_ofn.lpstrInitialDir = sampleDir;
という使い方はしない方が無難だと思います。
素直にcharの配列を取るか、const宣言した物を使った方がよろしいかと。
但し、上記のように前回のパスを保存するのであれば、メンバー変数に
charの配列を確保しておくのが良いでしょう。

PATIO 2006/10/05(木) 15:44:13
ああ、すいません。
勘違いしてました。
メニューの開くの話ですね。
確か、共通ダイアログを使ってしまうと前回の表示位置を
共通ダイアログが覚えていて使ってしまうという事があったと思います。
なのでこれに関してはカレントディレクトリは関係ないはずです。
私も今のところ対処方法は知らないです。

PATIO 2006/10/05(木) 15:46:34
どうしても前回の位置を指定したいのであれば、
既存のID_FILE_OPENをオバーライドして前回のパスを指定して
ダイアログを開くように改造するしかないかもしれません。
やろうと思えばできない話ではないと思います。

PATIO 2006/10/05(木) 16:15:11
MSDNのOPENFILENAMEの説明を読むとこの内容に関する記述がありますので参考にすると
良いと思います。

lpstrInitialDirの説明の部分ですが、動作するOSによって挙動が違うようです。
OS側の挙動なのでこの挙動そのものを変える事は無理みたいですね。
MFCを使っていてこの挙動を変えるとなるとID_FILE_OPEN時の挙動をきちんと理解した上で
CFileDialogを使用している部分の実装を乗っ取って変更するとか、ID_FILE_OPENの挙動
そのものを丸ごと自分で実装するとかしないと難しそうですね。
Document-Viewを使っている場合はいろいろとこれ絡みの管理クラス等が絡みそうなので
ややこしそうですね。

PATIO 2006/10/05(木) 16:29:07
最新のMSDNにはID_FILE_OPENに対する基本的なMFC上の処理の流れが説明されている
ところがありますからそれを参考にすると良さそうです。
それを見る限りではどうもCWinAppクラスに手を入れる必要がありそうな感じですね。
この辺は御自分で確認してみてください。

らら 2006/10/05(木) 17:45:26
丁寧にありがとうございます。
CFileDialogが前回のディレクトリ覚えているのを
こちらから操作できる方法を探していたのですが
CFileDialogのDoModalの中で呼ばれている
::GetOpenFileName()の中なので追いかけられなくて
レジストリを検索してもあるような無いような・・・
といった具合でした。

ID_FILE_OPENのオーバーライドするか、
またはアプリケーションの仕様を変更することにします。
PATIO様、ありがとうございました。

らら 2006/10/05(木) 17:48:48
[[解決]]
解決チェックわすれました ^^;

[解決]かどうか分かりませんが、
直接的な対処方法がなさそうどいうことで納得はできましたので。
ありがとうございました!

古いスレッドには追加発言できません。