• ベストアンサー

CFIleDialgを使う前後で作業ディレクトリが変わってしまう?

いつもお世話になっています。 MFCでプログラミングをしています。 CFileDialogで ファイルをダイアログで選択すると、 ファイルを選んだディレクトリが 作業ディレクトリに変わってしまい、 データの出力が当該ディレクトリになってしまいます。 MSDNやWEBでCFileDialogを調べたのですが、 それに関する事項が見つかりませんでした。 元のディレクトリを メンバ変数として保持していおく以外に 方法はないのでしょうか? できるだけ余計な変数を減らして 効率的なプログラムに仕上げたいです。 どなたか、カレントディレクトリを 変えない方法/元に戻す方法について アドバイス又は参考URL等ご教示お願いします。 char path[256]; ::GetCurrentDirectory(255,path); CFileDialog dialog(TRUE,_T("out"),_T("particle_data.out"), OFN_FILEMUSTEXIST, "Outputファイル(*.out)|*.out|テキストファイル(*.txt)|*.txt|全ファイル(*.*)|*.*||", NULL); dout = dialog.DoModal(); ::GetCurrentDirectory(255,path);

質問者が選んだベストアンサー

  • ベストアンサー
  • BILLY-J
  • ベストアンサー率57% (60/105)
回答No.3

#2さんと被りますが、「カレントディレクトリ」という考え方は 一回捨てましょう。 CFileDialog を使わなくともカレントディレクトリが毎回同じという 保証は有りません。 そのプログラムが起動される方法、 ・エクスプローラで直接ダブルクリック ・ショートカットから起動 ・コマンドプロンプトからフルパス指定で起動 ・VCのデバッガから起動 ・サービスから起動 ・その他別のプログラムから起動 等によって初っ端のカレントディレクトリが違う場合が有ります。 ファイルを扱う場合は、起動時に GetModuleFileName 等で自身の フルパスを覚えておくか、自分自身の位置に関係無く特定の場所を 使うならその基点をレジストリに保存しておく等した方が良いです。 また、省略可能な物、或いは一見無駄に見えるコードや変数でも、 それが有る事によって拡張性、汎用性、メンテナンス効率が上がる 事が多々有りますよ。

zico2
質問者

お礼

ご教示ありがとうございます。 そもそもの考え方が間違っていたことが 良く分かりました。 今後ともよろしくお願いします。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.2

>元のディレクトリを >メンバ変数として保持していおく以外に >方法はないのでしょうか? 無いです。 というか、カレントディレクトリに依存しないつくりにするのが一番いいんですけど。

zico2
質問者

お礼

ご教示ありがとうございます。 そもそもの考え方が間違っていることに 気が付きました。 どうもありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
回答No.1

こんにちは。  回答ではありません。  path[256]ですが、limits.hのPATH_MAXを使いましょう。256文字は「ドライブレターを含まない」パスの最大で、ドライブレター「C:\」を含むと超えてしまいます。

zico2
質問者

お礼

ご教示ありがとうございました。 勉強になりました。 今後ともよろしくお願いします。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • CFileDialogの最初のディレクトリ設定

    Visual C++のMFCです。 CFileDialogを使ってファイルを指定して開くと、カレントディレクトリの位置が変化して、次回、CFileDialogで開くときは、その変化したあとの最新のディレクトリが開きますね。 このカレントディレクトリは、GetCurrentDirectory で、調べることができました。 しかし、特定のディレクトリ(フォルダ)をCFileDialogで開きたいとき、SetCurrentDirectory で設定しようとしても、これでは、CFileDialogで開くフォルダ位置を変更できません。 CFileDialogで開きたいフォルダ位置を変更するコマンドを教えてください。 DoModal()をする以前に設定したいので、CFileDialogクラスとは別の関数、できれば、SDKの関数等であれば、いいです。

  • メインダイアログを表示させずにファイル選択ダイアログを表示

    VC++2005のMFCダイアログベースでプログラムを作成しています。 自動生成されたプログラムを何も変更しないまま実行すると、 メインのダイアログが表示されますが、 そのダイアログを表示させずに、ファイル選択ダイアログを表示させたいのです。 自分で実装しビルド実行したところ、期待動作をしましたが、 ファイル選択ダイアログを閉じた後に、画像のようなエラーが発生してしまいます。 エラーを発生させず、期待動作をさせる良い実装方法をご存知の方おられましたら、 ご教示お願い致します。 【変更実装(エラー発生)】 BOOL CtestApp::InitInstance() { … CtestDlg dlg; m_pMainWnd = &dlg; // INT_PTR nResponse = dlg.DoModal(); //コメントアウト dlg.OnBnClickedButton1(); //ファイル選択ダイアログを表示する関数 //if (nResponse == IDOK) //コメントアウト //else if (nResponse == IDCANCEL) //コメントアウト … } void CtestDlg::OnBnClickedButton1() { CFileDialog ReadDlg( TRUE, NULL, "*.txt", OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, "txtファイル(*.txt)", this ); … }

  • 特殊文字「\」の変換の方法

    VC++2005のMFCにてプログラムを作成しています。 CFileDialogにてテキストファイルを読み込み、 読込んだファイルパスの「\」を「\\」になるように変換したいのですが、 実装の方法が分かりません。 ===================================== 例)C:\test\hoge.txt ⇒ C:\\test\\hoge.txt と変換する。 ===================================== 下記にファイルパスをCstring型で読み込み、 char型に変換するまでのプログラムを記載します。 理想としては、char型配列の中に、 「C:\\test\\hoge.txt」のような変換後のファイルパスを 入れたいのです。 解決方法をご存知の方おられましたら、ご教示お願いできませんでしょうか。 【プログラム】 /* ファイルオープンダイアログを表示 */ CFileDialog ReadDlg( TRUE, NULL, "*.txt", OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, "txtファイル(*.txt)", this ); CString filepath; if( ReadDlg.DoModal() == IDOK ) { filepath = ReadDlg.GetPathName(); // ファイルのフルパス名を取得 } CFile cfile; CFileException ex; if( !cfile.Open( filepath, CFile::modeRead , &ex ) ) { AfxMessageBox( "ファイルを開くのに失敗しました" ); // エラーメッセージを表示 return; } char st[255] = ""; strcpy( st, filepath );

  • ファイルの保存ダイアログでデフォルト命名したい

    ファイルの保存ダイアログでデフォルト命名したい Win32API(C言語)編 第55章 ファイルを開く・保存のコモンダイアログ http://www.geocities.jp/ky_webid/win32c/055.html をみてファイルの保存ダイアログを出せるようになりました。 しかし、たまーにフリーソフトなどでもファイルを保存する際に、 デフォルトのファイル名が初期値として指定されているものもあります。 私のソフトでもそのようにしたいのですが、色々な部分に文字列を 入れてみて試してみても、思ったとおりの結果にはなりませんでした。 下記は上記サイトに記載されている ファイルを保存する際のダイアログの出し方から引用したものですが、 これをどのようにしたらダイアログが開いた際にファイル名部分に デフォルト命名された状態で開けるのでしょうか? static OPENFILENAME ofn; static TCHAR filename_full[MAX_PATH]; // ファイル名(フルパス)を受け取る領域 static TCHAR filename[MAX_PATH]; // ファイル名を受け取る領域 // 構造体に情報をセット ZeroMemory( &ofn, sizeof(ofn) ); // 最初にゼロクリアしておく ofn.lStructSize = sizeof(ofn); // 構造体のサイズ ofn.hwndOwner = hWnd; // コモンダイアログの親ウィンドウハンドル ofn.lpstrFilter = _T("text(*.txt)\0*.txt\0All files(*.*)\0*.*\0\0"); // ファイルの種類 ofn.lpstrFile = filename_full; // 選択されたファイル名(フルパス)を受け取る変数のアドレス ofn.lpstrFileTitle = filename; // 選択されたファイル名を受け取る変数のアドレス ofn.nMaxFile = sizeof(filename_full); // lpstrFileに指定した変数のサイズ ofn.nMaxFileTitle = sizeof(filename); // lpstrFileTitleに指定した変数のサイズ ofn.Flags = OFN_OVERWRITEPROMPT; // フラグ指定 ofn.lpstrTitle = _T("名前を付けて保存");// コモンダイアログのキャプション ofn.lpstrDefExt = _T("txt"); // デフォルトのファイルの種類 // 名前を付けて保存コモンダイアログを作成 if( !GetOpenFileName( &ofn ) ) { MessageBox( hWnd, _T("エラー"), _T("エラー"), MB_OK ); SendMessage( hWnd, WM_CLOSE, 0, 0 ); }

  • VC++でファイルが開けないんです

    以下のようなプログラムを作っています。 実行内容としては、 MessageBoxでYesNo選択 ↓ Yesなら~~という処理、 Noなら、ファイルの選択画面を立ち上げて、ファイルを選択。ReStartという関数にそのファイル名を渡す ↓ そのあと、現在時間を取得して、filename4というファイルに追加書き込みをする。 という処理です。 ここで、私はfilename4=./time/AAA.timeと指定しているのですが、 Yes処理のあとはうまくfileが開けて書き込めるのですが、No処理のあとはfileが開けないんです。 おそらくは、No処理の中のファイル選択で、VC++のプロジェクトがあるディレクトリと違うディレクトリから選択しているせいだと思うんですが、これを解消する方法はありますでしょうか?? VC++短いんで、もし単純でしたら申し訳ないですが、どうぞよろしくお願いします。 ------------------------------------------- ・・・ if(MessageBox("はじめから?", "message", MB_YESNO)==IDYES){ ~~} else{ CFileDialog fd(TRUE,"","",OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_LONGNAMES, "位置ファイル (*.POSI)|*.POSI|" "全てのファイル(*.*)|*.*||", NULL); if(fd.DoModal()==IDOK){ posifilename = fd.GetPathName(); } ReStart(posifilename); } stream4 = fopen(filename4,"a"); if(stream4 == NULL ){ MessageBox("Cannot Open the File!!", "error", MB_OK); } strwork4.Format("%ld,",time(NULL)); fprintf(stream4,strwork4); fclose(stream4);

  • Win32API ファイルの書き込み、保存

    Win32APIを使って、ファイルの保存ダイアログを表示→ファイルを指定→保存ボタンを押す→指定されたファイルに書き込む→指定したファイルを保存 というプログラムを作りたいと考えています。しかし、ファイルに書き込んだ後どう保存すればいいかわからないので教えてください。s[256]をfilename_fullに書き込んで保存したいです。この場合プログラムは抜粋したものなので、s[256]に文字が格納してあると考えてください。 char s[256]; FILE *fp; static OPENFILENAME ofn; static TCHAR filename_full[MAX_PATH]; // ファイル名(フルパス)を受け取る領域 static TCHAR filename[MAX_PATH]; // ファイル名を受け取る領域 // 構造体に情報をセット ZeroMemory( &ofn, sizeof(ofn) ); // 最初にゼロクリアしておく ofn.lStructSize = sizeof(ofn); // 構造体のサイズ ofn.hwndOwner = hWnd; // コモンダイアログの親ウィンドウハンドル ofn.lpstrFilter = _T("text(*.txt)\0*.txt\0All files(*.*)\0*.*\0\0"); // ファイルの種類 ofn.lpstrFile = filename_full; // 選択されたファイル名(フルパス)を受け取る変数のアドレス ofn.lpstrFileTitle = filename; // 選択されたファイル名を受け取る変数のアドレス ofn.nMaxFile = sizeof(filename_full); // lpstrFileに指定した変数のサイズ ofn.nMaxFileTitle = sizeof(filename); // lpstrFileTitleに指定した変数のサイズ ofn.Flags = OFN_OVERWRITEPROMPT; // フラグ指定 ofn.lpstrTitle = _T("名前を付けて保存");// コモンダイアログのキャプション ofn.lpstrDefExt = _T("txt"); // デフォルトのファイルの種類 // 名前を付けて保存コモンダイアログを作成 if( !GetSaveFileName( &ofn ) ) { MessageBox( hWnd, _T("エラー"), _T("エラー"), MB_OK ); SendMessage( hWnd, WM_CLOSE, 0, 0 ); }else{ if((fp=fopen(filename_full,"w")) == NULL) { MessageBox( hWnd, _T("エラー"), _T("エラー"), MB_OK ); SendMessage( hWnd, WM_CLOSE, 0, 0 ); exit(0); /* (3)エラーの場合は通常、異常終了する */ } /*ここからがわかりません*/     /*s[256]をファイルに書き込んで、保存するプログラムを教えてください。

  • ファイル名の取得について

    以下のサンプルで、選択したファイル名を任意の変数に取得したいのですが、どこに手を加えると取得できますでしょうか。 void OpenImgFiles(HWND hWnd) {   OPENFILENAME ofn;   memset(&ofn, 0, sizeof(OPENFILENAME));   ofn.lStructSize = sizeof(OPENFILENAME);   ofn.hwndOwner = hWnd;   ofn.lpstrFilter = "BMP files(*.bmp)\0*.bmp\0All Files(*.*)\0*.*\0\0";   ofn.lpstrFile = FileName;   ofn.nMaxFile = MAX_PATH;   ofn.Flags = OFN_FILEMUSTEXIST;   ofn.lpstrDefExt = "bmp";   ofn.nMaxFileTitle = 64;   ofn.lpstrFileTitle = FileTitle;   ofn.lpstrTitle = "ファイルを開く";   if (GetOpenFileName(&ofn)) {     show = 1;     InvalidateRect(hWnd, NULL, TRUE);   }   return; } ひょっとして簡単すぎるのかも知れませんが・・・ どうかよろしくお願いします。

  • ディレクトリ構造の表示

    任意のディレクトリ構造を分析してその構造(ファイル名をkey)をXMLなりハッシュに吐き出すことができるモジュールなり方法を模索しています。 XMLでいうXML::Simpleみたいなものです。 参考------------------------------------------------------ 【XML分析:XML::Simple】→【ハッシュ:Data::Dumper】 【XML分析:XML::Simple】→【XMLファイル:XML::Simple】 ---------------------------------------------------------- グーグルなどで検索してみた限りでは、任意のディレクトリ内分析をしてくれてXMLなりハッシュに吐き出してくれるモジュールはなさそう。 そこでFile::Pathを使ってディレクトリ内を洗ってその構造を動的にハッシュにしたいと考えいます。しかし残念なことに予め構造がわかっている規則的なデータを動的にハッシュにすることはできるのですが、実際に分析するまでその階層すらわからない不規則なツリー状のデータ構造を動的にハッシュ化するプログラミング能力を持ち合わせていません。 そこで質問しかないということになりました。ぜひお知恵をお借りしたいと思っています。よろしくお願いいたします。 本当に簡単ですがこのような不規則なディレクトリ構造を動的にハッシュにしたいと思っています。この例ではディレクトリ構造がわかってますが、分析するまでわからないものとしてみて頂ければと思います。 test1(dir)―――――test2(dir)――――――――data1.txt(file)            |           |            ―data1.txt(file)   ―data2.txt(file)            |            ―data2.txt(file) $test1 = {       'test2' => {            'data1' =>                          {                       'path' => 'test1/data.txt',                       'parent_dir' => 'test2'                         },            'data2' =>                          {                       'path' => 'test2/data.txt',                       'parent_dir' => 'test2'                         },                 },       'data1' =>                     {                  'path' => 'test1/data.txt',                  'parent_dir' => 'test1'                    },       'data2' =>                     {                  'path' => 'test2/data.txt',                  'parent_dir' => 'test1'                    }     };

    • ベストアンサー
    • Perl
  • シェル ディレクトリ内検索について

    お世話になっております。 solarisでシェル作成に辺り教えてください。 あるディレクトリの新しいファイルから3つ目の ファイルを移動(mv)したいと考えているのですが 良い方法は無いでしょうか? 例 testディレクトリ内 ファイル.txt.051025 ファイル.txt.051024 ファイル.txt.051023  ←このファイルをmv処理 ファイル.txt.051022 ファイル.txt.051021 ファイル.txt.051020 ディレクトリ内のタイムスタンプで最も新しいファイルから3つ目を移動させたい場合は、どの様にしたら良いでしょうか?方法はあるのでしょうか? お願いします。

  • VB.NET 最下位のディレクトリ名を取得する方法

    こんにちは ディレクトリのパス 「D:\ディレクトリ1\ディレクトリ2\テキストファイル.txt」から ファイル名「テキストファイル.txt」が存在する、最下位のディレクトリ名「ディレクトリ2」 を取得したいのですが、このような機能を提供する関数をご存知の方がいらっしゃいま したらお教え願います。