Click to See Complete Forum and Search --> : How to access MFC Dialogs from a .NET Control in a Managed C++ Environment?


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?

Andreas Masur
August 21st, 2003, 07:14 AM
[Moved thread]

MooNull
August 21st, 2003, 01:35 PM
System::Windows::Forms::MessageBox

Its a simple dialog box. The Show public member function of it takes many params that will enable you to customize it quite well.

Otherwise, managed classes CAN have unmanaged members, or in the least call them.

matthias_k
August 23rd, 2003, 08:54 AM
I dont really see in how far your answer is related to my question. I was not talking about Message Boxes at all, but how to display MFC property pages in a managed C++ environment.