matthias_k
August 21st, 2003, 06:49 AM
Hello,
we are currently migrating to .NET and want to save as much code as possible. Our former ActiveX controls used MFC property pages to make changes at design time using these custom property pages. The code describing these dialogs contains several thousand lines of code, so we want to keep these MFC dialogs instead of rewriting them as Windows Forms.
For testing purposes I created a .NET Control Library project using Microsoft Visual Studio 2003 and put a simple pushbutton on the control. Furthermore I added a MFC dialog resource to the project and instantiated this dialog in the event handler of the .NET control pushbutton. The code compiles with no errors (tho many warnings...), but when I now start a new C# or VB .NET project and drag and drop my control on the Form, compile and run and click the button, then I will get an unhandled exception.
I debugged the code and recognized that in CDialog::DoModal() the call on AfxGetResourceHandle() will fail.
For better understanding, here's some code (I have highlighted the important section):
// My test .NET control
#pragma once
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
#include "TestDialog.h"
namespace test
{
/// <summary>
/// Summary for testControl
/// </summary>
///
/// WARNING: If you change the name of this class, you will need to change the
/// 'Resource File Name' property for the managed resource compiler tool
/// associated with all .resx files this class depends on. Otherwise,
/// the designers will not be able to interact properly with localized
/// resources associated with this form.
public __gc class testControl : public System::Windows::Forms::UserControl
{
public:
testControl(void)
{
InitializeComponent();
}
protected:
void Dispose(Boolean disposing)
{
if (disposing && components)
{
components->Dispose();
}
__super::Dispose(disposing);
}
private: System::Windows::Forms::Button * button1;
private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container* components;
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->button1 = new System::Windows::Forms::Button();
this->SuspendLayout();
//
// button1
//
this->button1->Location = System::Drawing::Point(16, 16);
this->button1->Name = S"button1";
this->button1->Size = System::Drawing::Size(120, 112);
this->button1->TabIndex = 0;
this->button1->Text = S"button1";
this->button1->Click += new System::EventHandler(this, button1_Click);
//
// testControl
//
this->Controls->Add(this->button1);
this->Name = S"testControl";
this->ResumeLayout(false);
}
private: System::Void button1_Click(System::Object * sender, System::EventArgs * e)
{
TestDialog dlg;
dlg.DoModal();
}
};
}
Here's the dialog's code:
// .h
#pragma once
#include "resource.h"
// TestDialog dialog
class TestDialog : public CDialog
{
DECLARE_DYNAMIC(TestDialog)
public:
TestDialog(CWnd* pParent = NULL); // standard constructor
virtual ~TestDialog();
// Dialog Data
enum { IDD = IDD_DIALOG1 };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
};
// .cpp
// TestDialog.cpp : implementation file
//
#include "stdafx.h"
#include "resource.h"
#include "TestDialog.h"
// TestDialog dialog
IMPLEMENT_DYNAMIC(TestDialog, CDialog)
TestDialog::TestDialog(CWnd* pParent /*=NULL*/)
: CDialog(TestDialog::IDD, pParent)
{
}
TestDialog::~TestDialog()
{
}
void TestDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(TestDialog, CDialog)
END_MESSAGE_MAP()
// TestDialog message handlers
Nothing spectacular.
I have no idea where to look for a solution, do you know what's going wrong here?
we are currently migrating to .NET and want to save as much code as possible. Our former ActiveX controls used MFC property pages to make changes at design time using these custom property pages. The code describing these dialogs contains several thousand lines of code, so we want to keep these MFC dialogs instead of rewriting them as Windows Forms.
For testing purposes I created a .NET Control Library project using Microsoft Visual Studio 2003 and put a simple pushbutton on the control. Furthermore I added a MFC dialog resource to the project and instantiated this dialog in the event handler of the .NET control pushbutton. The code compiles with no errors (tho many warnings...), but when I now start a new C# or VB .NET project and drag and drop my control on the Form, compile and run and click the button, then I will get an unhandled exception.
I debugged the code and recognized that in CDialog::DoModal() the call on AfxGetResourceHandle() will fail.
For better understanding, here's some code (I have highlighted the important section):
// My test .NET control
#pragma once
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
#include "TestDialog.h"
namespace test
{
/// <summary>
/// Summary for testControl
/// </summary>
///
/// WARNING: If you change the name of this class, you will need to change the
/// 'Resource File Name' property for the managed resource compiler tool
/// associated with all .resx files this class depends on. Otherwise,
/// the designers will not be able to interact properly with localized
/// resources associated with this form.
public __gc class testControl : public System::Windows::Forms::UserControl
{
public:
testControl(void)
{
InitializeComponent();
}
protected:
void Dispose(Boolean disposing)
{
if (disposing && components)
{
components->Dispose();
}
__super::Dispose(disposing);
}
private: System::Windows::Forms::Button * button1;
private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container* components;
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->button1 = new System::Windows::Forms::Button();
this->SuspendLayout();
//
// button1
//
this->button1->Location = System::Drawing::Point(16, 16);
this->button1->Name = S"button1";
this->button1->Size = System::Drawing::Size(120, 112);
this->button1->TabIndex = 0;
this->button1->Text = S"button1";
this->button1->Click += new System::EventHandler(this, button1_Click);
//
// testControl
//
this->Controls->Add(this->button1);
this->Name = S"testControl";
this->ResumeLayout(false);
}
private: System::Void button1_Click(System::Object * sender, System::EventArgs * e)
{
TestDialog dlg;
dlg.DoModal();
}
};
}
Here's the dialog's code:
// .h
#pragma once
#include "resource.h"
// TestDialog dialog
class TestDialog : public CDialog
{
DECLARE_DYNAMIC(TestDialog)
public:
TestDialog(CWnd* pParent = NULL); // standard constructor
virtual ~TestDialog();
// Dialog Data
enum { IDD = IDD_DIALOG1 };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
};
// .cpp
// TestDialog.cpp : implementation file
//
#include "stdafx.h"
#include "resource.h"
#include "TestDialog.h"
// TestDialog dialog
IMPLEMENT_DYNAMIC(TestDialog, CDialog)
TestDialog::TestDialog(CWnd* pParent /*=NULL*/)
: CDialog(TestDialog::IDD, pParent)
{
}
TestDialog::~TestDialog()
{
}
void TestDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(TestDialog, CDialog)
END_MESSAGE_MAP()
// TestDialog message handlers
Nothing spectacular.
I have no idea where to look for a solution, do you know what's going wrong here?