Solved

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

Posted on 2014-04-17
1
371 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 31

Accepted Solution

by:
Zoppo earned 500 total points
ID: 40014310
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
count8 challlenge 13 118
mapAB Challlenge 35 127
Least Squares Curve Fitting 4 61
operator overload: incompatible type and too many params 5 63
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
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.
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

896 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

13 Experts available now in Live!

Get 1:1 Help Now