ファイルの「保存」「開く」ではじめに開かれるディレクトリ – プログラミング – Home

ファイルの「保存」「開く」ではじめに開...
 
通知
すべてクリア

[解決済] ファイルの「保存」「開く」ではじめに開かれるディレクトリ

固定ページ 1 / 2

はまち
 はまち
(@はまち)
ゲスト
結合: 23年前
投稿: 146
Topic starter  

////////////////////////////////////////////////////////////////////////////////

開発環境 : Visual C++ 6.0
動作環境 : Windows 98 Second Edition
      MFC使用  MDIベース

////////////////////////////////////////////////////////////////////////////////

今、私のプログラムでは、ファイルを保存したり開いたりするのに
一番最初に開かれるフォルダがMyDocumentです。
これをexeファイルがあるフォルダにしたいのですが、
簡単にできるのでしょうか。
今、MFCのどの部分がそれを決めているのか、探している
ところなのですが、なかなか見つからず苦労しております。
もし、どなたかわかる方がいらっしゃれば、よろしくお願いします。


引用未解決
トピックタグ
アイススケーター
 アイススケーター
(@アイススケーター)
ゲスト
結合: 22年前
投稿: 280
 

コモンダイアログで簡単にできるはずです。
オープンダイアログとか。


返信引用
monkey
 monkey
(@monkey)
ゲスト
結合: 21年前
投稿: 70
 

ファイル開く/保存で、CFileDialog(あるいはその派生クラス)を使っているのであれ
ば、DoModal関数でダイアログボックスを開く前に、データメンバm_ofn(OPENFILENAME
型)のメンバlpstrInitialDirに、最初に開きたいフォルダ名を設定してあげます。


返信引用
wood
 wood
(@wood)
ゲスト
結合: 23年前
投稿: 895
 

ご質問の勝手な解釈です
このご質問に、最低2種類含まれているようです

1.EXEの場所の取得方法はどうすれば良いか?
 >これをexeファイルがあるフォルダにしたいのですが、

 こんな関数で取得できます(引数は俺の勝手な記述)
 GetCurrentDirectory(sizeof(dir_str),dir_str);

2.「保存」や「開く」で起動される関数はどこにある?
 回答方法が2つあるんです

 1つは、
 「コーディングしているのはあなたなので、わかりません、
  ソース提示してください」
 2つめは、
  「リソース エディタ から 保存・開くのリソースIDを調べ
  クラスウィザードで関連付けされている関数を調べてください」

 つまりAppWizardが生成した関数のどの部分をいじれば良いかわからない
 と言うことでは無いでしょうか

 
 ドキュメントクラスのSerializeを調べてみてはいかがでしょうか


返信引用
はまち
 はまち
(@はまち)
ゲスト
結合: 23年前
投稿: 146
Topic starter  

アイスケーターさん、monkeyさん、woodさん、みなさん、貴重な
お返事、ありがとうございました。
早速、みなさんの助言をもとに調べてみようと思います。


返信引用
isshi
 isshi
(@isshi)
ゲスト
結合: 21年前
投稿: 41
 

>1.EXEの場所の取得方法はどうすれば良いか?
> >これをexeファイルがあるフォルダにしたいのですが、
>
> こんな関数で取得できます(引数は俺の勝手な記述)
> GetCurrentDirectory(sizeof(dir_str),dir_str);
GetCurrentDirectory はその名のとおりカレントディレクトリを取得するものであり、
exeファイルのあるフォルダを取得するものではありません。
exe を直接ダブルクリックして起動した場合は、exeのあるフォルダがカレントになりま
すが、
たとえばショートカットを使って起動した場合は、ショートカットのプロパティの
”作業フォルダ”がカレントになります。
また、exe 実行中に SetCurrentDirectory でカレントはいくらでも変更できます。

GetModuleFileName で exe のフルパスが得られるので、_splitpath を使うなりして、
exe のフォルダを抽出してください。


返信引用
wood
 wood
(@wood)
ゲスト
結合: 23年前
投稿: 895
 

これは失礼しました、フォローありがとうございます


返信引用
はまち
 はまち
(@はまち)
ゲスト
結合: 23年前
投稿: 146
Topic starter  

CDocumentから派生したCXXXDocのコンストラクタで以下のように
してみたのですがうまくいきません。SetCurrentDirectory(pathStr)
でのpathStrにはパスは入っているのですが。何か、おかしな部分があるのでしょうか。

CXXXDoc::CXXXDoc()
{
CString pathStr;
LPTSTR fileName = pathStr.GetBuffer(100);
GetModuleFileName(NULL,fileName,100);

char drive[100];
char dir[100];
char fname[100];
char ext[100];

_splitpath( fileName, drive, dir, fname, ext );

pathStr = drive;
pathStr += dir;
BOOL bJudge = SetCurrentDirectory(pathStr);

}


返信引用
アイススケーター
 アイススケーター
(@アイススケーター)
ゲスト
結合: 22年前
投稿: 280
 

pathStrの内容を確認されましたか?
ひょっとして\が抜けてませんか


返信引用
isshi
 isshi
(@isshi)
ゲスト
結合: 21年前
投稿: 41
 

そもそも、ファイル選択ダイアログはどうやって出していますか?
それが分からなければ答えようがないような。

たとえば ID_FILE_OPEN のメッセージハンドラがデフォルトのままなら、
MFCが勝手にダイアログを出しますが、このダイアログでの初期フォルダを
任意に設定したいということでしょうか?
その場合、SetCurrentDirectory ではできませんでした。(SDIならできた。)
メッセージハンドラを独自のものに変えて、自分でダイアログを出す必要が
ありそうです。
(他にも方法があるかもしれませんが。)


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

文字バッファの領域を適切なものに変えたほうがいいかもしれません。それとcharの配
列で領域をとる場合は初期化したほうがいいでしょう。

以下のコードはCStringを使ってexeのディレクトリ名を取得しています。(起動確認はし
ていませんw)

CString strPathName; // exeのフルパス

// exeのパスを取得
::GetModuleFile( NULL, strPathName.GetBuffer( _MAX_PATH ), sizeof( TCHAR )
* _MAXPATH );
// 文字列長の調整
strPathName.ReleaseBuffer();

CString strDrive; // ドライブ名
CString strDir; // ディレクトリ名

// ドライブ名、ディレクトリ名の取得
::_splitpath( strPathName, strDrive.GetBuffer( _MAX_DRIVE ),
strDir.GetBuffer( _MAX_DIR ), NULL, NULL );
// 文字列長の調整
strDrive.ReleaseBuffer();
strDir.ReleaseBuffer();

CString strModuleDir; // exeディレクトリ名

// exeのディレクトリ名を作成
::_makepath( strModuleDir.GetBuffer( _MAX_PATH ), strDrive, strDir, NULL,
NULL );
// 文字列長の調整
strModuleDir.ReleaseBuffer();


返信引用
はまち
 はまち
(@はまち)
ゲスト
結合: 23年前
投稿: 146
Topic starter  

みなさん、ご丁寧な説明、大変申し訳ないです。Blueさんに至っては
コードまで書いていただきとても参考になりました。

Blueさんのコードに従ってやってみたのですが、やはりダメのようでした。
デバッグで見る限りでは、うまくパスが入っているのですがカレントディレクトリは
MYDOCUMENTのままでした。

実はファイル選択のダイアログについては何も行っておりません。CFileDialogなどは
あまり扱った経験がなく、通常、MFCが作ってくれるダイアログを初めから
exeファイルがあるところにできないものかと思っておりました。
今思えば、アイスケーターさんやmonkeyさんが始めに指摘されていたことも
このことだったのではと思います。

実は、目的のプログラムは「ファイルをexeファイルがあるディレクトリに保存する」
という作業が極端に多いのでなんとかならないものかと思っておりました。
一度、プログラムを実行させたあとにディレクトリを変えるという作業は
ほとんどないので、常に、保存時にexeファイルがあるところを開いてくれる
というものでも全く構わないという状況です。

もう少し調べてみます。


返信引用
isshi
 isshi
(@isshi)
ゲスト
結合: 21年前
投稿: 41
 

>通常、MFCが作ってくれるダイアログを初めから
>exeファイルがあるところにできないものかと思っておりました。
これについては私はわかりませんが、上で私が書いた
>メッセージハンドラを独自のものに変えて、自分でダイアログを出す必要
>がありそうです。
のやり方を書いておきます。
(とりあえず、「開く」の場合について)

ClassWizard のメッセージマップの「クラス名」で CXxxApp、
「オブジェクトID」で ID_FILE_OPEN、「メッセージ」で COMMAND
を選択し、「関数の追加」ボタンを押す。

メンバ関数名を指定してOKボタンを押す。

「コード編集」ボタンを押し、上で指定したメンバ関数の中身を
以下のように記述する。

void CXxxApp::OnFileOpen()
{
// TODO: この位置にコマンド ハンドラ用のコードを追加してください
CString pathStr;
LPTSTR fileName = pathStr.GetBuffer(100);
GetModuleFileName(NULL,fileName,100);

char drive[100];
char dir[100];
char fname[100];
char ext[100];

_splitpath( fileName, drive, dir, fname, ext );

pathStr = drive;
pathStr += dir;

CFileDialog dlg(TRUE); // コンストラクタのデフォルト引数は省略しています。
// 必要に応じて適切な引数を指定すること。
// とりあえずこれでも動きます。
dlg.m_ofn.lpstrInitialDir = pathStr;
if (dlg.DoModal() == IDOK){
OpenDocumentFile(dlg.GetPathName());
}
}

Xxx.cpp の

BEGIN_MESSAGE_MAP(CTestMDIApp, CWinApp)
...
// 標準のファイル基本ドキュメント コマンド
...
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) // *1
...
END_MESSAGE_MAP()

の *1 の行をコメントアウトする。
(VC6ではコメントアウトしなくても動きましたが一応。
VC7.1ではコメントアウトが必要でした。)

(WinXP Home SP1, VC6SP6, MDI で動作確認済み)


返信引用
isshi
 isshi
(@isshi)
ゲスト
結合: 21年前
投稿: 41
 

>(VC6ではコメントアウトしなくても動きましたが一応。
>VC7.1ではコメントアウトが必要でした。)
VC6でコメントアウトしなくても動いたのは、
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
の前に、独自のメッセージハンドラのエントリ
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
が追加されたからでした。
(VC7.1ではうしろに追加されていた。)
ということで、基本的にコメントアウトは必要です。
失礼しました。。。


返信引用
アイススケーター
 アイススケーター
(@アイススケーター)
ゲスト
結合: 22年前
投稿: 280
 

さっきの続きで

pathStr += *.txt;

CFileDialog dlg( TRUE, TXT, pathStr);
dlg.DoModal();

としたらいかがでしょう


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました