• 締切済み

DlgDirSelectComboBoxEx

VC++2010 でMFCアプリケーションを作成しているのですが、 DlgDirListComboBox関数によって一覧が表示されているコンボボックスから、 現在選択されている項目(ディレクトリ名、ドライブ名)を取得する処理で、 DlgDirSelectComboBoxExを使用するとアプリケーションが強制終了してしまいます。 何が悪いのかが解らず困っています。 詳しい方がいましたらご教授お願いします。 以下は私が作成したサンプルコードとなります。 BOOL CComboBoxTestDlg::OnInitDialog() { CDialogEx::OnInitDialog(); CString work; work = L"C:\\*.*"; DlgDirListComboBox( work.GetBuffer(), IDC_COMBO1, 0, DDL_DIRECTORY | DDL_DRIVES | DDL_EXCLUSIVE); m_ComboBox.SetWindowText(L"C:\\"); } void CComboBoxTestDlg::OnCbnSelchangeCombo1() { wchar_t str[1024]; memset(str, 0x00, sizeof(str)); DlgDirSelectComboBoxExW( this->m_hWnd, (LPTSTR)str, 1024, IDC_COMBO1); AfxMessageBox(str); }

みんなの回答

  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.5

>XPビジュアルスタイルを設定すると DlgDirSelectComboBoxExを呼び出した後 スタックが壊れるようです 逆アセンブルリストは…見ても判りませんでした。 # っていうか68000のアセンブラしか勉強したことない。 現象的には…OS側のバグですよねぇ。 XPどころか7でも修正されていない不具合って一体……。 # 誰もレポート上げていない…とか??

super_champ
質問者

お礼

DlgDirSelectComboBoxEx自体あまり使われていないのかもしれませんね。 今回はこのAPIを使わず、自前で関数を作成します。 ありがとうございました。

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.4

XPビジュアルスタイルを設定すると DlgDirSelectComboBoxExを呼び出した後 スタックが壊れるようです インラインアセンブラで PUSH 0などを書き加えてやると 一般保護違反は起きなくなるのですが 今度は DlgDirSelectComboBoxExが失敗して WNDが無効とか Control IDが見つからないなどのエラーになってしまいました AnsNo3の Wr5氏の回答を参考に 自前の関数を作成してみるとか …

super_champ
質問者

お礼

そうですね。 Wr5さんの回答を参考にして自前の関数を作成することにしました。 ありがとうございました。

  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.3

追加で実験してみました。 No.2はWindows7 Professional SP1 64Bitでエアロスタイル有効でしたが、 今度はWindowsXP Professional SP3で。 ・クラシックスタイル+ビジュアルスタイル使用のマニュフェストなし  正常に取得できました。(表示はクラシックスタイル) ・クラシックスタイル+ビジュアルスタイル使用のマニュフェストあり  一般保護違反で落ちました。(表示はクラシックスタイル) ・ビジュアルスタイル+ビジュアルスタイル使用のマニュフェストなし  一般保護違反で落ちました。(表示はビジュアルスタイル有効) ・ビジュアルスタイル+ビジュアルスタイル使用のマニュフェストあり  一般保護違反で落ちました。(表示はビジュアルスタイル有効) なんというか……どうにもならないって感じですな。 ディレクトリ(フォルダ)選択にはSHBrowseForFolder()とかを使用する。 というのが一般的になりつつありますので、DlgDirSelectComboBoxEx()を使用している人自体が少ないのかも知れません。 # 新たなダイアログを開く必要がない。とかそういう利点はありますけど……。 DlgDirListComboBox()が掲示のオプションの場合、最初に設定したドライブ以外のディレクトリは選択できませんし。 取得した文字列もディレクトリ名だけでドライブ名や上位のディレクトリ名も取得出来ませんから……。 取得した結果が':'で終わっていればドライブを選択された。 ということで、フィルタ文字列を変更してDlgDirListComboBox()で再設定を行えば、該当ドライブのディレクトリ一覧に更新できますが……。 選択されたのがディレクトリの場合は、別に保存しておいた上位のディレクトリ名と結合していけばパス名は構築できるでしょう。 # SHBrowseForFolder()とかの方がお手軽ですけどね。 # GetOpenFileName()をディレクトリ名取得に使う。という変則技もありでしょう。 DlgDirSelectComboBoxEx()を使用せずに、そのままコンボボックスの文字列を取得して自前で処理する。 というのも、アリと言えばアリですかね。 ディレクトリ名に'['や']'を使われていると面倒ですが。 # C:\-x- なんてディレクトリがあった場合も。 取得した文字列のディレクトリが存在するか確認して、無ければ前後の'['と']'をカット。 その後の文字列でさらにディレクトリが存在するか確認して、先頭と最後の文字が'-'だったらドライブ名が選択された。として先頭と最後の文字が'-'を削除して':'を最後に追加。 ディレクトリが存在した場合は最後に'\'を追加。 サブディレクトリの一覧を出す場合はさらに手間…ですかね。

  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.2

対処方法は不明ですが… ビジュアルスタイルにしているとDlgDirSelectComboBoxEx()API内で死ぬようです。 DLL側の問題なんでしょうかねぇ? # ググってもちょっと見つけられませんでした。 ところで…… >DlgDirListComboBox( work.GetBuffer(), IDC_COMBO1, 0, DDL_DIRECTORY | DDL_DRIVES | DDL_EXCLUSIVE); はCWnd::DlgDirListComboBox()で、 >DlgDirSelectComboBoxExW( this->m_hWnd, (LPTSTR)str, 1024, IDC_COMBO1); はWin32APIを使用。 というのはちぐはぐですね。 CWnd::DlgDirSelectComboBox()を使用するべきではありませんかね? # まぁ、いずれにしろちゃんと実行できないのですが…。

super_champ
質問者

お礼

>CWnd::DlgDirSelectComboBox()を使用するべきではありませんかね? そうですね。 ご指摘ありがとうございました。 対処方法については、もう少し調べてみます。

noname#251971
noname#251971
回答No.1

実際試したわけでなく、問題点の確信があるわけでもありませんが、 コードを見てここを変えてみてはどうかと思う点について回答いたします。 DlgDirListComboBox() のほうは、CWndクラスのメンバ関数を利用しており、 DlgDirSelectComboBoxExW()のほうは、Windows APIを直接利用されているようですが、 取得のほうも CWnd クラスのメンバ関数である DlgDirSelectComboBox() を 利用してみてはどうでしょうか。

関連するQ&A