アプリ版:「スタンプのみでお礼する」機能のリリースについて

現在、Visual Studio 2005の、Visual C#、C++/CLI、MFCを使ったシステムを構築しています。
具体的には、MFCで書かれた(拡張DLL)でダイアログを表示。これをC++/CLIでラップし、C#から呼び出して使いたいと思っております。
そこで、http://soudan1.biglobe.ne.jp/qa3834982.htmlを参考にして、以下のように作ったのですが、DLL内のdlg.DoModal()のコールで、
AfxGetResourceHandle()でASSERTが発生してしまいます。

//// C#のフォーム
using LogGphWrap;
namespace DllTestApp {
public partial class Form1 : Form {
private void button1_Click(object sender, EventArgs e) {
Wrapdll.Wrapper.DlgOpen(this.Handle.ToInt32());
}
}
}

//// Wrapdll(CRLのクラスライブラリ) [Wrapdll.h]
[DllImport("MFCdll.dll")]
bool dspDlg(int hDib);

namespace Wrapdll {
public ref class Wrapper
{
public:
static bool DlgOpen(int hDib) {
return ( dspDlg(hDib) ) ;
}
};
}

//// MFCdll(MFCの拡張DLL) [MFCdll.h]
#include "resource.h"
bool dspDlg(HWND hDib);

//// MFCdll(MFCの拡張DLL) [MFCdll.cpp]
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{

  デフォルトのまま

}
bool dspDlg (HWND hDib) {
AFX_MANAGE_STATE(AfxGetAppModuleState());
AfxMessageBox(_T("ちょっとお試し"), 0, 0) ;

 CTestDlg *dlg = new CTestDlg(CWnd::FromHandle(hDib));
 dlg->Create(IDD_DIALOG) ; <====この部分でASSERTが発生!!

 return TRUE ;
}

ご存知の方がいらっしゃれば、ご教授ください。
よろしくお願いします。

A 回答 (2件)

こんにちは。


異なる言語を使ったプログラムは組んだことないのですが、多分同じではないかと思ってレスさせてください。


質問で書かれているプログラムでは、恐らくDLL側にリソースエディタでダイアログを作成されたと思いますが、DLL側から参照使用としているリソースはそのままではアプリケーション側(呼出元)のリソースを参照としているためにASSERTが発生します。DLL側にセットされたリソースを読もうとはしていません。

これを回避するためにはDLLのインスタンスハンドルを取得して直接読むようにするのが良いと思います。

HMODULE  hModule ;
HRSRC   hResource ;

hModule    = ::GetModuleHandle( モジュール名 ) ;
hResource   = ::FindResource( hModule, MAKEINTRESOURCE( リソースID ), RT_DIALOG ) ;
m_hResGlobal  = ::LoadResource( hModule, hResource ) ;

m_hResGlobalをクラスのメンバーとして保持しておき、

CTestDlg::Create( CWnd* const lpwndParent )
{
   CDialog::CreateIndirect( m_hResGlobal, lpwndParent ) ;
}

とすればちゃんと表示されると思います。
各関数についてはヘルプを見てください。
    • good
    • 0
この回答へのお礼

takupyさん、レス有難うございました。
ご指摘のように、インスタンスハンドルを取得したのですが、
やはり、ASSERTが発生してしまいます。
デバックでチェックする限りでは、モジュールもリソースも
取得できているようなのですが・・・

HMODULE  hModule ;
HRSRC   hResource ;

hModule    = ::GetModuleHandle( _T("MFCdll") ) ;
hResource    = ::FindResource( hModule, MAKEINTRESOURCE(IDD_DIALOG), RT_DIALOG ) ;
m_hResGlobal  = ::LoadResource( hModule, hResource ) ;

CTestDlg::Create( CWnd* const lpwndParent )
{
   CDialog::CreateIndirect( m_hResGlobal, lpwndParent ) ;<=====この要求時のAfxGetResourceHandle()でASSERTが発生・・・
}

お礼日時:2009/07/14 13:25

マネージドから呼び出した場合にMFC周りの初期化がうまくいっていないのが原因のようですよ



VC++で Win32APPやMFCEXEで お作りになったMFCDLL.DLLのdispDlgを呼ぶようなアプリを作ってみてはいかがでしょう
多分アサートはされないはずです

このとき dlg->Createから呼ばれたCDialog::Createで呼ばれる
_AfxCheckDialogTemplate関数でAfxFindResourceHandleを呼び出します
この中でAfxGetModuleStateで取得した pModuleStateメンバーの値と

マネージから呼ばれた場合とで比較してみましょう
マネージから呼ばれた場合 m_hCurrentResourceHandleなどのメンバーがNULLになっているようです
    • good
    • 0
この回答へのお礼

redfox63さん、有難うございます。
いろいろと試してみたのですが、結局、
マネージDLLで作り直す方向で考えています。
ご指導有難うございました。

お礼日時:2009/07/15 23:37

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


このQ&Aを見た人がよく見るQ&A