Solved

How to convert an existing MFC dialog into re-usable control?

Posted on 2014-04-17
1
361 Views
Last Modified: 2015-02-04
Hi,

I have a MFC dialog that has few controls on it (like web browser, buttons etc).
I want this MFC dialog to be reused by other dialogs in my project.

Like, if I can convert this into an active-x control or a custom control, I can just use the whole dialog and embed it onto another parent dialog.

Is there a way I can do this?

Thanks,
0
Comment
Question by:aravindgopaluni
1 Comment
 
LVL 30

Accepted Solution

by:
Zoppo earned 500 total points
Comment Utility
Hi aravindgopaluni,

IMO building an ActiveX or a custom control makes sense when you plan to be able to use it in other projects without need to add/use the code, i.e. if you want to sell the control.

If this is not the case IMO easiest is to implement the control as a child dialog and load it at runtime in the wanted parent dialog.

To do so you'll have to implement a new CDialog-derived class and move all functionality which implements your current dialog to this new class (lets call it CMyControlDlg). Further you need to add a new Dialog to resources (in my sample below this uses IDD_MY_CONTROL as resource ID), where you'll have to following properties:
Border: None
Style: Child
Control: True

Next you should override the functions OnOk and OnCancel qnd remove the base-class calls in order to avoid the child dialog closes when these keys are used to close the parent dialog.

And you should implement a constructer like this:
class CMyControlDlg : public CDialog
{
public:
 CMyControlDlg::CMyControlDlg( CWnd* pParent = NULL )
 : CDialog( IDD_MY_CONTROL, pParent )
 {}
};

Open in new window

To use this like a control in a parent dialog you have to add a pointer as member to the parent dialog's class, instantiate it and create the child dialog and to add some code to handle the child control with some relevant messages like WM_SIZE and WM_DESTROY.

To simplify using the child dialog like a control I would suggest to implement another CDialog derived class (lets call it CMyControlParent) which acts as a wrapper and is later used as base class for parent dialogs.

The implementation of CMyControlParent could look somehow like this (only the relevant parts):
class CMyControlParent
{
 CMyControlDlg* m_pChild ;
public:
 ...
 int OnCreate(LPCREATESTRUCT lpCreateStruct);
 int OnDestroy();
 void OnSize(UINT nType, int cx, int cy); // optional (see comment below)
 void DoDataExchange(CDataExchange* pDX); // optional (see comment below)
};

int CMyControlParent::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
 if (CDialog::OnCreate(lpCreateStruct) == -1)
  return -1;

 m_pChild = new CMyControlDlg();
 m_pChild->Create(IDD_MY_CONTROL, this);
 m_pChild->ShowWindow(SW_SHOW);

 return 0;
}

int CMyControlParent::OnDestroy() 
{
 m_pChild->DestroyWindow();
 delete m_pChild;
}

void CMyControlParent::OnSize(UINT nType, int cx, int cy) 
{
 CDialog::OnSize(nType, cx, cy);

 CRect rect;
 GetClientRect(&rect);

 // some how calculate correct position and size here, this is just a dumb sample
 rect.Deflate(2, 2); 
 rect.bottom -= 20;

 m_pChild->MoveWindow(&rect);
}

void CMyControlParent::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 m_pChild->DoDataExchange(pDX);
}

Open in new window

Comments: The OnSize is only needed in resizable parent dialog, if you don't use this you should position the child dialog in a similar way in OnCreate. The DoDataExchange is only needed if CMyControlDlg uses DoDataExchange too.

The code doesn't include needed entries in the message map. As long as you use ClassWizard to override the mentioned functions/message handlers they're added autmatically, otherwise you'll have to add them manually. If you don't know how to do this please tell.

You should implement functions to pass data from/to the child dialog to the parent dialog as needed to avoid parent dialogs directly access member variables of the child dialog (at least just because it's always a good idea).

This way it should be enough to implement a new parent dialog by simply deriving it from CMyControlParent (take care to change all occurances of 'CDialog' in the new dialog to 'CMyControlParent').

Of course this can be still improved, i.e. I would implement a virtual function which is used to calculate position and size of the child control. This can be overridden in new parent dialogs if specific position is needed.

I hope this helps you getting an idea about how to do it this way. Doesn't look simple, but I promise building/using an ActiveX or a custom control is more complicated (allthough, as told above, offers possibilities which are not possible with the above suggestion).

Hope that helps,

ZOPPO


PS: The code is not tested, I just wrote it from the scratch here, so it may contain errors and/or it could be I missed something. If you have problems with it or get stuck somewhere please tell ...
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
sumHeights  challenge 17 59
Python 2.7 - French characters 6 46
C++ question 3 44
Problem to open Excel file 15 35
There is an easy way, in .NET, to centralize the treatment of all unexpected errors. First of all, instead of launching the application directly in a Form, you need first to write a Sub called Main, in a module. Then, set the Startup Object to th…
When we want to run, execute or repeat a statement multiple times, a loop is necessary. This article covers the two types of loops in Python: the while loop and the for loop.
This video teaches viewers about errors in exception handling.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

5 Experts available now in Live!

Get 1:1 Help Now