CFileDialogの使い方 – プログラミング – Home

通知
すべてクリア

[解決済] CFileDialogの使い方

固定ページ 1 / 2

いろは
 いろは
(@いろは)
ゲスト
結合: 22年前
投稿: 43
Topic starter  

いつも勉強させて頂いています。

CFileDialogを用いて、ユーザーにファイル名を入力してもらっています。
今まで気づかなかったのですが、ユーザーが使用していて不思議な現象が出ました。

開発環境
 Windows2000Sp4 + VC6Sp5(MFC使用)

現象
 例えば、C:\tempにAAA.CSVが保存されています。
 下記に提示するコードを用いてファイル保存ダイアログを表示します。
   (以下単にダイアログと記述します)
 ダイアログのリストからAAA.CSVを選択します。
   (テキストボックスにAAA.CSVが設定されますよね。)
 保存をせずに、リスト、コンボボックスを操作してデスクトップを選択します。
   (デスクトップにはAAA.CSVは存在しません。)
 ここで、保存ボタンをクリックすると、なんと上書き確認のメッセージが
 表示されてしまいます。  ←これが問題!!!

ソース抜粋
 // ファイル保存ダイアログ
 CFileDialog FileDlg( false, CSV,NULL,
           OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST,
           CSV File (*.CSV)|*.CSV||,
           NULL );
 if( FileDlg.DoModal() == IDOK ){

ちょっと文章では伝えにくいのですが、理解していただけたでしょうか?

私がデバッグしたところによると、
 直接テキストボックスに入力しても現象は確認できません。
 デスクトップのパス(C:\defaults and....)を指定したときは発生しません。
 APIのGetSaveFileNameも試してみましたが、同じ現象を確認しました。

何か使い方が間違えていますか?それともMicrosoftの…
対応法をご存知の方がいらっしゃったら、お力をお貸しください。

よろしくお願いします。


引用未解決
トピックタグ
秋衛門
 秋衛門
(@秋衛門)
ゲスト
結合: 22年前
投稿: 6
 

あらん、そんなん起こるんやん……と試してみるものの再現せず。
XP+VC6 で現象確認できずというあまり役に立たない情報まで


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

> 保存をせずに、リスト、コンボボックスを操作してデスクトップを選択します。
>   (デスクトップにはAAA.CSVは存在しません。)
> ここで、保存ボタンをクリックすると、なんと上書き確認のメッセージが
> 表示されてしまいます。  ←これが問題!!!

> デスクトップのパス(C:\defaults and....)を指定したときは発生しません。

どっち?
なんかおかしくない?


返信引用
aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
 

マイドキュメントやマイコンピュータの上位にあるデスクトップでは発生するけれど、
C:\Documents and Settings\... のデスクトップフォルダでは発生しないということか
な。


返信引用
ひろぴー
 ひろぴー
(@ひろぴー)
ゲスト
結合: 22年前
投稿: 182
 

うわぁ!本当だ!
因みに私の環境ではGetSaveFileName()で左横にOutLookショートカットバー(って言うんでし
たっけ?)出ていましたので、ソコのデスクトップを押すと上書き確認はされません。
う~ん、怪しい....。
↑解決になってませんが

Win2000 SP4 VC++6 SP5


返信引用
いろは
 いろは
(@いろは)
ゲスト
結合: 22年前
投稿: 43
Topic starter  

秋衛門 様、シャノン 様、ひろぴー 様 情報ありがとうございます。

>秋衛門 様
>XP+VC6 で現象確認できずというあまり役に立たない情報まで

手近にXP(というか他のOS)が無いので、他のOSでは確認できていないのです。
情報ありがとうございました。

>シャノン 様
>マイドキュメントやマイコンピュータの上位にあるデスクトップでは発生するけれど、
>C:\Documents and Settings\... のデスクトップフォルダでは発生しないということか
>な。

はい。そういうことです。ちょっとわかりにくい文章でしたね。

>ひろぴー 様
>うわぁ!本当だ!
>因みに私の環境ではGetSaveFileName()で左横にOutLookショートカットバー
>(って言うんでしたっけ?)出ていましたので、ソコのデスクトッ
>プを押すと上書き確認はされません。

「APIを使用しても同じだ~」という事しか確認していなかったので、
後ほど試してみます。

う~ん…どのように対処したら良いかわからない…。
「どうやらMicrosoftの…」という事で終わりにしてしまおうか…


返信引用
瀬戸っぷ
 瀬戸っぷ
(@瀬戸っぷ)
ゲスト
結合: 22年前
投稿: 160
 

以前、どかの掲示板でみたような記憶があります。
その時に試しましたが……
Windows98SE(COMDLG32.DLL Ver4.72.3510.2300)では再現せず…でした。<さっきまた試し
た。

APIのレベルで発生しているので、バグと思われますが……
ちなみにWindows2000 SP4(COMDLG32.DLL Ver5.00.3315.3727)では発生しました。
プレースバーは無しの状態…です。


返信引用
いろは
 いろは
(@いろは)
ゲスト
結合: 22年前
投稿: 43
Topic starter  

いろはです。

瀬戸っぷ様、情報ありがとうございました。

現在GetSaveFileNameの方で、再度確認中です。
すると、GetSaveFileNameを使用すると現象が出ないようです。
(最初に質問したときに、同様の現象が出るというのは嘘だったようです…)

という事で、CFileDialogを使用するのをあきらめて、APIを使用するように
方針転換することにしました。

一応、解決といたします。ありがとうございました。


返信引用
瀬戸っぷ
 瀬戸っぷ
(@瀬戸っぷ)
ゲスト
結合: 22年前
投稿: 160
 

> 現在GetSaveFileNameの方で、再度確認中です。
> すると、GetSaveFileNameを使用すると現象が出ないようです。
> (最初に質問したときに、同様の現象が出るというのは嘘だったようです…)
> という事で、CFileDialogを使用するのをあきらめて、APIを使用するように
> 方針転換することにしました。

私の方ではGetSaveileName()API使用でも出ましたが。(Windows2000の方で)
CFileDialogでも最終的にGetOpenFileName()/GetSaveFileName()が使用されるので、
APIに切り替えても同じハズです。
(どちらが使用されるかは、CFileDialogのコンストラクタのbOpenFileDialog引数によります)
詳しくは…MFCのソース(DLGFILE.CPPのCFileDialog::DoModal())を見て下さい。


返信引用
いろは
 いろは
(@いろは)
ゲスト
結合: 22年前
投稿: 43
Topic starter  

いろはです。

瀬戸っぷ 様、情報ありがとうございます。

>私の方ではGetSaveileName()API使用でも出ましたが。(Windows2000の方で)

おや、そうですか?
昨日は私がデバッグした限りではAPIを使用すれば、現象は出ませんでした。

こんなソースです。

(抜粋)
TCHAR strFile[MAX_PATH];
::memset( strFile, 0, sizeof(strFile) );

OPENFILENAME ofn;
::memset( &ofn, 0, sizeof(OPENFILENAME) );
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
ofn.lpstrFilter = CSV File(*.CSV)\0*.CSV\0\0;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFile = strFile;
ofn.lpstrDefExt = CSV;
::GetSaveFileName( &ofn );

>CFileDialogでも最終的にGetOpenFileName()/GetSaveFileName()が使用されるので、
> 以下略
MFCのソースは追っていましたので、これはわかっていました。

Windows2000からOPENFILENAME構造体が拡張されましたよね。
今回の問題は、これが絡んでいるのではないかと思っています。


返信引用
瀬戸っぷ
 瀬戸っぷ
(@瀬戸っぷ)
ゲスト
結合: 22年前
投稿: 160
 

> Windows2000からOPENFILENAME構造体が拡張されましたよね。
> 今回の問題は、これが絡んでいるのではないかと思っています。

プレースバー…でしたか、拡張されていますね。
私は使っていませんが…
#ifndef OPENFILENAME_SIZE_VERSION_400
stGofn.lStructSize = sizeof(OPENFILENAME);
#else
stGofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
#endif
こんなコトして強制使用しています。

ちなみに、その辺の関係かMFC7.0(VC++.net)では
CFileDialogのコンストラクタで引数が1つ増えていたりします。
MFC6.0環境からのソースをコンパイルした場合に、条件によっては問題が出るらしいです。
(Googleで検索すると、その問題を調べたページがみつかるかと)

ちなみに、テストした時のOPENFILENAME構造体の設定は…
OPENFILENAME stGofn;
char szTemp[MAX_PATH];

ZeroMemory(szTemp, MAX_PATH);
ZeroMemory(&stGofn, sizeof(OPENFILENAME));
#ifndef OPENFILENAME_SIZE_VERSION_400
stGofn.lStructSize = sizeof(OPENFILENAME);
#else
stGofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
#endif
stGofn.hwndOwner = hwnd;
stGofn.lpstrFilter = 全てのファイル(*.*)\0*.*\0;
stGofn.nFilterIndex = 1;
stGofn.lpstrTitle = 名前を付けて保存・てすと;
stGofn.lpstrFile = szTemp;
stGofn.nMaxFile = (MAX_PATH-3);
stGofn.Flags = OFN_OVERWRITEPROMPT | OFN_ENABLEHOOK |
OFN_EXPLORER | OFN_PATHMUSTEXIST;
stGofn.lpstrDefExt = TXT;
stGofn.lpfnHook = (LPOFNHOOKPROC)OFNHookProc;
GetSaveFileName(&stGofn);
です。(VC++6.0 SDKです。)
フックを使用していますが、各状態での内容を調べる為…なので、今回の問題には無関係です。


返信引用
いろは
 いろは
(@いろは)
ゲスト
結合: 22年前
投稿: 43
Topic starter  

私が提示したソースに嘘がありました。

>ofn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
保存なのにOFN_FILEMUSTEXISTって…
正解はこちらです。
ofn.Flags = OFN_PATHMUSTEXIST|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;

このように修正した結果、やはり出ました。現象が…
プレースバーのデスクトップを選ぶと大丈夫なのですがね。

結局、バグという事ですかね。
ありがとうございました。


返信引用
三毛猫
 三毛猫
(@三毛猫)
ゲスト
結合: 22年前
投稿: 7
 

UINT CALLBACK OFNHookProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM
lParam) {
OFNOTIFY* lpOFNotify = (OFNOTIFY*)lParam;

switch( message ) {
case WM_NOTIFY:
if( lpOFNotify->hdr.code == CDN_SELCHANGE ) {
HWND hEdit = GetDlgItem( GetParent( hwnd ), edt1 );
if( hEdit ) {
char FileName[32000];
GetWindowText( hEdit, FileName, 32000 );
SetWindowText( hEdit, FileName );
}
}
break;
}
return 0;
}

こんな感じで CDN_SELCHANGE 通知時にエディットボックスの内容を
上書きしたら、不要な上書き確認は表示されなくなりました。

# フックを使ったらプレースバーが表示されなくなりましたけど、
# 自前でダイアログを書き換えないとダメなのでしょうか。


返信引用
瀬戸っぷ
 瀬戸っぷ
(@瀬戸っぷ)
ゲスト
結合: 22年前
投稿: 160
 

> 自作のアプリをXP上で起動し、起動した状態でデスクトップ
> テーマの変更を行うと、フォントをいじっている
> スタティックコントロールが汚く表示されてしまいます。
> なにか解決策はないのでしょうか?

XPは使ったことないですが…
デーマを変更した時になにかメッセージが飛んできませんか?
それらに応答する処理を追加してみてはどうでしょうか?
画面のプロパティのデザインで変更すると、
WM_SYSCOLORCHANGEやWM_SETTINGCHANGEが飛んできたりとかしますが。
Spy++で監視していると関連するメッセージがわかるかも知れません。

> こんな感じで CDN_SELCHANGE 通知時にエディットボックスの内容を
> 上書きしたら、不要な上書き確認は表示されなくなりました。

ソレをヒントにいぢってみました。
 エディトボックスにEM_SETMODIFYで更新フラグを設定してみる……失敗。
 親ウィンドウにEN_CHANGEとEN_UPDATEを送ってみる……成功。
 親ウィンドウにEN_UPDATEを送ってみる……失敗。
 親ウィンドウにEN_CHANGEを送ってみる……成功。
というコトで…
case WM_NOTIFY:
if( lpOFNotify->hdr.code == CDN_SELCHANGE ) {
HWND hEdit = GetDlgItem( GetParent( hwnd ), edt1 );
if( hEdit ) {
SendMessage(GetParent( hwnd ), WM_COMMAND, MAKEWPARAM(edt1,
EN_CHANGE), (LPARAM)hEdit);
}
}
で行けました。
まぁ、EN_CHANGEのあとにEN_UPDATEも送っておいた方がよさそうですけど。

> # フックを使ったらプレースバーが表示されなくなりましたけど、
> # 自前でダイアログを書き換えないとダメなのでしょうか。

消えますね。
なんらかの方法で可能なハズ(秀丸では表示させている)と思われますが…
ちょっと調べきれなかったです。
(秀丸のテンプレートではプレースバーは入っていませんでした…)


返信引用
瀬戸っぷ
 瀬戸っぷ
(@瀬戸っぷ)
ゲスト
結合: 22年前
投稿: 160
 

げ……
テキストファイルで編集してから貼り付けていますが……
要らないモノまで貼り付けてしまいました(^_^;)

> 自作のアプリをXP上で起動し、起動した状態でデスクトップ
から
Spy++で監視していると関連するメッセージがわかるかも知れません。
までは無視して下さい(汗)


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

返信する

投稿者名

投稿者メールアドレス

タイトル *

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