- ベストアンサー
【VC++6.0(MFC)】適切なSHBrowseForFolder使用方法について教えてください。
- VC++6.0(MFC)でのSHBrowseForFolderの正しい使用方法について教えてください。
- 質問者はVC++の初心者で、SHBrowseForFolderを使用しているとデバッグモードでエラーが発生していることに困っています。エラーメッセージは「例外処理 (初回) は XXXX.exe (NTDLL.DLL) にあります: 0xC0000005: Access Violation」というものです。質問者はMSDNのドキュメントを参照し、COMの初期化が必要であることを知りましたが、初期化後のサンプルコードが見つかりませんでした。
- 質問者はSHBrowseForFolderのサンプルコードを探しています。質問者は既にコードの一部を記述し、フォルダの選択ダイアログを表示するところまで進めています。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
こんばんは。お礼頂きました。 ・MFCプロジェクトへのCoInitialize()/CoUninitialize()の必要性 MFCにおいては、必要無い筈です。 COMを使用する際には必ずCoInitizlize()等による初期化が必要です。 其のまま使用すると、その場でプログラムがクラッシュしたりするので直ぐに分かります。 MFCでは初期化無しでも動いたのですから、MFCアプリがスタートする際に、呼び出されている筈です。 ただし、何処で呼び出されているのかを特定する時間が無かったので、敢えて言及しませんでした。
その他の回答 (4)
- machongola
- ベストアンサー率60% (434/720)
こんばんは。補足頂きました。 以下にインストール方法が載っていました(*.msiをダブルクリックするのでは無い見たいです)。 http://none-real-sidem.spaces.live.com/Blog/cns!C9E5DAD61969AED4!245.entry 昔、当方がインストールしたのはCD版のPSDKでした(自動的に正しくインストールされる)。 今現在、CD版のPSDKが配布されていない為、.cabファイルを手動インストールするタイプの方を使用するしか道が無いのですが、正直な所、当方も今回が初めてですので、詳しくは分りません。
お礼
追伸です。 何台かのPCのNTDLL.DLLのバージョンを調べてみました。 ViolationがでるPC、でないPCのNTDLL.DLLのバージョンは 関係なさそうです。 (5.1.2600.xxxxのxxxxの値がそれぞれのPCで違いましたが、 値が大きいものでもViolationが発生したり、 値が小さいものでもViolationが発生しなかったりしています。) Violationが出るPC、出ないPCに共通する点は、 某セキュリティソフトが起因していそうです。 (出るPCにはみんなそのソフトがインストールされています。) (これは私の勝手な見解です。) 本件について長い間、ご相談させていただきましたが、 一度こちらの質問を閉じさせて頂きます。 今までご協力して頂きありがとうございました。
補足
ご回答、ありがとうございます。 (返信遅れて、すみませんでした。) ご紹介頂いたページを確認しました。 教えて頂いた内容を実行すると #2の「この回答へのお礼」の現象が発生し、 インストールできませんでした。 (しかし、CoreSDK-x86.msiの実行でそれらしいことが 出来ているので、根拠はありませんが、問題ないのかな、 とも思っています。) 話を戻して、 「例外処理 (初回) は XXXX.exe (NTDLL.DLL) にあります: 0xC0000005: Access Violation」 というエラーが出ているので、NTDLL.DLLを調べてみました。 まず、自分のPCで「NTDLL.DLL」で検索すると、何個かのNTDLL.DLLが ヒットしますが、実際に使用されているのは、WINDOWS\system32内の NTDLL.DLLでしょうか。 また、WINDOWS\system32\NTDLL.DLLのバージョンを調べると 以下のようになりました。 エラーが出ないPCのNTDLL.DLLのバージョン:5.1.2600.2180 エラーが出る PCのNTDLL.DLLのバージョン:5.1.2600.5755 このバージョンの違いは関係あるのでしょうか。
- machongola
- ベストアンサー率60% (434/720)
こんばんは。補足頂きました。 どうやら、PSDKサイト内の説明がおかしい上、ダウンロードしたPSDK-FULL.?.cabファイル群のうちの幾つかの拡張子がhtmになってしまっている様です。 ・Cドライブにpsdkフォルダを作成する ・psdkフォルダ内にtmpフォルダを作成する ・psdkフォルダにPSDK-FULL.?.cabを置く(拡張子がおかしくなっている場合は拡張子をcabに直す) ・DOSプロンプトを立ち上げる ・DOSプロンプトをC:\psdkへ移動 ・DOSプロンプトからC:\psdk>PSDK-FULL.bat C:\psdk\tmpを実行 ・C:\psdk\tmp\setupフォルダ内のPSDK-x86.msiをダブルクリック で出来ませんか。 ・includeとlinkの参照設定について 此れに関しては、vc6.0で、今まで使用していたインクルードやリンクのパスの代わりに、新しくインストールしたPSDKに対してインクルードやリンクのパスを設定するという事です。 新しいPSDKを導入してもアクセスバイオレーションが発生したのならば、当方はギブアップという事になります。
お礼
追伸です。 やはりViolationが発生してしまいました。 ちなみに、includeとlinkの参照設定については、 以下のページを参照させて頂きました。 http://www.noppi.jp/diary/?date=20080114 (もし、設定の仕方が違うようならば、ご指摘いただけると嬉しいです。) また、今回の場合についてMFCプロジェクトへのCoInitialize()/CoUninitialize()の 必要性も教えて頂きたくお願いします。 当分は、 デバグでもリリースでも、 「Microsoft Foundation Class 」を 「共有のDLLでMFCを使用」から 「MFCスタティックライブラリを使用」に変更して使用していこうと思います。 ご教授、ありがとうございました。
補足
ご回答、ありがとうございます。 早速試してみます。 先の質問に戻りますが、MFCプロジェクトでコーディングしている場合、 CoInitialize()/CoUninitialize()は必要なのでしょうか。 他のサイトを参照すると、必要ないような事が書かれていましたので。 (他のプロジェクト、例えば、「Win32 Application」などを 使用している場合は必要になるらしいのですが。)
- machongola
- ベストアンサー率60% (434/720)
こんにちは。補足頂きました。 書いている途中に追伸が着ましたので、先に追伸の方から返答すると、 ・「共有のDLLでMFCを使用」から ・「MFCスタティックライブラリを使用」に変更すると出なくなりました。 確証はありませんが、vc6.0に付属しているPlatform SDKが古くてxpにそぐわないのが理由の様な気がします。 vbaとxp(sp3)でSHBrowseForFolder()を実行するとアクセスバイオレーションが発生すると言った記事を見ました。 http://www.eggheadcafe.com/software/aspnet/30395489/shbrowseforfolder-call-cr.aspx 当方の、 vc6.0 windows2000(sp4) vc2008 windows xp(sp3) では実行出来ています。 以下補足に対してですが、試すとすれば、 (1)リリースビルドして実行してみる (2)UNICODEでビルドしてみる (3)Platform SDKをvc6.0が利用出来る中で最新のものにしてみる http://ja.wikipedia.org/wiki/Microsoft_Windows_SDK 位でしょうか。 (1)は言語が違うのですが、 http://www.activebasic.com/forum/viewtopic.php?p=79&sid=a6ba9c0303767391dd7d77a7595100c1 に因んで、試してみると言う事です。 (3)は以下のサイトから http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm を落として来て、vc6.0に付属しているPlatform SDKの代わりに使用します(includeとlinkの参照設定も行います)。
お礼
追伸です。 >(1)リリースビルドして実行してみる。 こちらは、メニューの「プロジェクト」、「設定」の 「プロジェクトの設定」画面内の 「設定の対象」を「Win32 Debug」でも「Win32 Release」でも 「Microsoft Foundation Class」を 「共有DLLでMFCを使用」にすると、Violationが発生し、 「MFCのスタティックライブラリを使用」にすると、Violation発生しませんでした。 >(3)Platform SDKをvc6.0が利用出来る中で最新のものにしてみる >6. Run Setup.exe to install the Platform SDK using the SDK Update interface. C:\psdk内のSetup.Exeということですね。 (ぼけていました。) しかし、実行すると、IE8が現れ、インストールできませんでした。 タイトル: 「IEXPLORE.EXE - アプリケーションエラー」 内容: 「"0x04ae0068"の命令が"0x04ae0068"のメモリを参照しました。 メモリが"written"になることはできませんでした。 プログラムを終了する場合は「OK」をクリックしたください。、、、」
補足
ご回答、ありがとうございます。 >(1)リリースビルドして実行してみる エラー(Access Violation)は発生しませんでした。 ※一応、実行時、メニューの「デバッグ」、「例外処理」で 「Access Violation」を「常に停止」に変更しましたが、 途中で落ちることはありませんでした。 >(2)UNICODEでビルドしてみる debugビルドで実行: エラー(Access Violation)は発生しました。 リリースビルドで実行 エラー(Access Violation)は発生しませんでした。 (3)Platform SDKをvc6.0が利用出来る中で最新のものにしてみる 教えて頂いたページの5まで実行しました。 しかし6の「Setup.exe」とは何を指すのでしょうか。 6. Run Setup.exe to install the Platform SDK using the SDK Update interface. >vc6.0に付属しているPlatform SDKの代わりに使用します(includeとlinkの参照設定も行います)。 とは、具体的にどういうことなのでしょうか。 初歩的な質問ですみません。
- machongola
- ベストアンサー率60% (434/720)
こんばんは。 CoInitialize()/CoUninitialize()の事ではないでしょうか。 http://msdn.microsoft.com/en-us/library/ms678543(VS.85).aspx http://msdn.microsoft.com/en-us/library/ms688715(VS.85).aspx 取り敢えず、C???App::InitInstance()の中に置いて試して見ては如何でしょうか。 BOOL C???App::InitInstance() { ::CoInitialize(NULL); //省略 //... //省略 ::CoUninitialize(); return FALSE; }
お礼
追伸です。 メニューの「プロジェクト」、「設定」で 「プロジェクトの設定」画面を出し、 その中の「一般」タブの「Microsoft Foundation Class 」を 「共有のDLLでMFCを使用」から 「MFCスタティックライブラリを使用」に変更すると出なくなりました。 ※しかし、別のPCでは「共有のDLLでMFCを使用」の設定でも エラーは出力されていません。 これから何か分かりませんでしょうか。
補足
御回答、ありがとうございます。 試してみましたが、まだエラーが出てしまいます。 何か他に、対応策はありませんでしょうか。
補足
御回答、ありがとうございます。 >MFCにおいては、必要無い筈です。 安心しました。 だから、SHBrowseForFolderを説明している他のサイトでも MFCの場合は、CoInitialize()/CoUninitialize()を使っていないのですね。 あと、もう1つ以下の事を確認させて頂けませんでしょうか。 >・C:\psdk\tmp\setupフォルダ内のPSDK-x86.msiをダブルクリック と助言頂きましたが、#3の「この回答へのお礼」で書いた http://www.noppi.jp/diary/?date=20080114 の内容と異なるため、 「C:\psdk\tmp\setupフォルダ内のCoreSDK-x86.msiをダブルクリック」 も上記に加えて実行しました。 PSDK-x86.msiでなく、CoreSDK-x86.msiが正しいのではないのでしょうか。 (せっかく教えて頂いてるのに、すみません。) (PSDK-x86.msiとCoreSDK-x86.msiで何が違うかまったく理解していませんが、、、) (しかしながら、結局「Access Violation」が発生しました。)