We help IT Professionals succeed at work.

Overlay a dialog box from a dll

apostrophe27
apostrophe27 asked
on
I'm creating a dialog box in a dll, and I want to overlay it on a portion of the dialog box of the executable. How do I do that? The dll is an MFC extension dll.
Comment
Watch Question

Commented:
This actually is not that tough.  The first thing you need to do is export a dialog from your DLL, then create this dialog over a designated area of your parent dialog.  A key thing to remember is that the dialog in the DLL must be of Child style; otherwise you will not be able to position it correctly on the parent.

The code below shows some snippets from this general procedure, but please download the linked zip for a complete project (VS 2003) (link will only remain valid for seven days from today!)

http://www.yousendit.com/download/bFFQYkJ1K3hLVld4dnc9PQ

HTH
//
// DLL Source
//

// DLL header file; defines export symbol macros
#ifdef __cplusplus 
extern "C" 
{ 
#endif // __cplusplus 

#ifdef BUILDING_DLL
#define DLL_SPEC _declspec(dllexport)
#else
#define DLL_SPEC _declspec(dllimport)
#endif

#ifdef __cplusplus 
} // extern "C" 
#endif //__cplusplus

// Exported class definition.  Classwizard generated with one exception; the
// new Create() function
class DLL_SPEC CDialogInDLL : public CDialog
{
public:
   	virtual BOOL Create ( CWnd* pParent );

  //...
};

/*virtual*/ BOOL CDialogInDLL::Create ( CWnd* pParent )
{
	return CDialog::Create ( CDialogInDLL::IDD, pParent );
}

//
// Executable source
//

// Create the child dialog, then position it over the static control
// Assuming we have a member m_wndChildDlg of type CDialogInDLL, and 
// a DDX CStatic m_wndStaticPlaceholder, that is linked to the control
// you wish to create the child dialog over.

VERIFY ( m_wndChildDlg.Create ( this ) );
CRect rcChildDlg;
m_wndStaticPlaceholder.GetWindowRect( &rcChildDlg );
ScreenToClient ( &rcChildDlg );

m_wndChildDlg.MoveWindow ( rcChildDlg );
m_wndChildDlg.ShowWindow(SW_SHOW);

Open in new window

Commented:
NB Creating a child dialog over part of a parent dialog is actually a very useful technique when space is limited.  I have used this in the past; a combo control determines which "sub dialog" to display on the main dialog; changing the combo selection changes the child dialog.  It is also used in some application's property pages; a tree view down the left hand side is wired up to a designated area of the dialog; clicking a different node changes what child dialog is displayed.

Author

Commented:
Thanks. I'll probably try it over the weekend or early next week -

Commented:
Have you tried this at all yet?

Author

Commented:
Sorry, I just tried it yesterday. This project got pushed back a little.

That works, but I need to explicitly link to the dll, using LoadLibrary. How do I call the dialog box in the dll once it's loaded?

Commented:
This is a very interesting question.  I don't actually know the answer to this but I will adhere to find out.

The technique I am using involves having an exported function which can be loaded with GetProcAddress().  This function then creates the dialog.  Whereas this works fine for a modal dialog and DoModal(), it does not work for a modeless dialog (strange access violations, most likely to do with the message map being confused about which module it is in).  Since you have now got my attention with this, I will get it solved to satisfy my own curiosity.

Watch this space...

Commented:
Because I want to get this solved to satisfy my own curiosity, I am asking for help from other experts.  If you are interested, see http:Q_25993604.html

Commented:
We have finally got this sorted; it turns out I was making a very silly mistake in releasing the dynamically loaded DLL too soon, causing the loaded dialog to be invalid.

A new project is located at https://www.yousendit.com/download/OHo3S3dwbWdWRC92Wmc9PQ which does exactly what you want.

I have asked the expert who helped me solve this, pgnatyuk, to comment here.  Please include him in your points allocation.

Author

Commented:

That's closer to what I need, but not quite there yet. I think maybe I haven't been explaining it well enough. I'll go a little further into what I'm doing.

I'm creating an executable that is the front end for some tests, and hopefully will remain unchanged over time. I will be creating many dlls over time to work with the executable. Each dll will have a different number of dialog boxes (all the same dimensions) depending on how many tests are in it. The executable won't know ahead of time how many dialog boxes are in the dll or what their names are. I can't include any files from the dll in the executable project.

What I need to be able to do is pass the location of m_wndStaticPlaceholder to the dll, then have the dll create the dialog box and overlay it on the executable.

Thank you for spending so much time helping me.
Commented:
OK.

I have created pretty much exactly what you ask for (I certainly deserve these points ;) )

The project has been updated to VS2008; if you don't have that I can provide info on how to open it in 2005; try not to use 2003 where possible :o)

The DLL exports two functions: CreateDialogInDLL(), which is responsible for the creation of a dialog, and GetNumDialogs(), which is responsible for retrieving the number of different dialogs that are in the DLL.  Since you are creating the DLLs, you have control over this.

A new class, CDialogManager, has been added, which is the "engine" for dialog creation.  This stores runtime-class information about all the dialogs which can be created.  CDialogManager::Init() is responsible for adding each runtime class to internal storage; you are free to add as many here as you wish.  I have wrapped the information about each dialog in another class, CDlgData, which is a simple container class for the runtime-class information, and a pointer to the actual dialog which has been created.  Note that all the dialogs derive from the common class CBaseDLLDialog.  Note also that every class you add must have the macros DECLARE_DYNCREATE and IMPLEMENT_DYNCREATE, since we create them dynamically within CDialogManager::CreateDialogAtIndex().

The exported function CreateDialogInDLL() forwards the work onto CDialogManager.  To this function, you need to pass the index of the dialog you wish to create (0 based).  This is why I have provided GetNumDialogs(): you can simply loop from index 0 to the value returned by GetNumDialogs(), like I do in the updated CTestEXEDlg::OnBnClickedButtonCreate().  Thereby, you can create every dialog there is within the DLL.

Hopefully the code is fairly straightforward.  If you have any queries, please ask.

VS2008 project at https://www.yousendit.com/download/OHo1eFVVdkd3TGp2Wmc9PQ

Author

Commented:
Hi,

I'm still running VS2005. What do I need to do.

I do really appreciate all the time you've put in on this.

Commented:
Converting VS2008 to VS2005:

1) Open the SLN file.  The first two lines,

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008

need replacing with

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005

2) Open each VCPROJ file (there are two, one for the DLL, one for the EXE).  Find the lines that state

Version="9.00"

and replace them with

Version="8.00"

3) Check the icon for the SLN in Windows Explorer.  It should have a little '8' in it.

Author

Commented:
Excellent! Just what I'm looking for. Thanks for your help.

Commented:
Glad to help.  If you have any more questions, let me know :o)

Commented:
A follow up to this question was asked at https://www.experts-exchange.com/questions/29065918/I-am-trying-to-do-something-similar-to-this-Is-the-ZIP-file-mentioned-in-the-solution-still-available.html; since the original zip file I uploaded is now no longer available, I have attached it here.  The answer marked as the solution here (https://www.experts-exchange.com/questions/25752850/Overlay-a-dialog-box-from-a-dll.html#a32153164) gives a suitable explanation as to what is going on; moreover, the code is heavily commented.  Hope this helps anyone else wanting to do the same thing in the future!

Commented:
Dialog-from-DLL-on-exe-dialog.zip

The following files need to be renamed to remove the .txt from their filename:

DLL.vcproj.txt
DLL.def.txt
TestEXE.vcproj.txt
DLL.rc2.txt
TestEXE.rc2.txt
TestEXE.ico.txt

Explore More ContentExplore courses, solutions, and other research materials related to this topic.