Solved

Exporting a Dialog class  (w/ activex control) from a DLL explicilty

Posted on 2003-10-31
35
310 Views
Last Modified: 2013-11-20
Hi,

I need to create an application that will call a dialog from a dll, in which the dialog has an embedded activex inside.

Is there someone here that knows how export a dialog class from a DLL explicitly?

Thanks,
Mhelinx

0
Comment
Question by:mhelinx09
  • 15
  • 14
  • 4
  • +1
35 Comments
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9656385
declare your class in the dll (MFC Extension dll)
class AFX_EXT_CLASS CMyDlg : public CDialog

make this header available to your app eg.
#include "..\\ext_dll\\ext_dll_dlg.h"

Now in the app
CMyDlg dlg(this);
dlg.DoModal();
0
 

Author Comment

by:mhelinx09
ID: 9656411
Hi Andy,

In the DLL, I'm not going to use any header file. In my application, my only source is the DLL. Using LoadLibrary, I will call the global functions inside my DLL. But the problem is how about returning the dialog class since im application it is only processing function, not returing the dialog class.

I hope I did not make any confusion,
Mhelinx
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9656442
Don't export the dialog class, this creates resource problems. Export ShowDialog function (global, or some class member - doesn't matter) and show dialog from it:

void CSomeClass::ShowDialog(CWnd* pParent)     // exported
{

    CMyDlg dlg(pParent);

    HINSTANCE h = AfxGetResourceHandle( );

    // set here Dll handle, this ensures that dialog template is found in current Dll resource
    AfxSetResourceHandle(hDll);                      

    dlg.DoModal();

    AfxSetResourceHandle(h);                           // restore caller's current resource handle
}
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9656449
hDll is HINSTANCE hinstDLL from DllMain.
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9656463
Hi Alex,
What do you do if you if you want to populate the dialog with info/return info from the dialog.  
Exporting the class enables one to do that without a problem.
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9656472
Hi mhelinx09,
I don't think you can export a dialog class through a function.
0
 

Author Comment

by:mhelinx09
ID: 9656488
Hi guys,

How about this, I have a activex controls included in the dialog. I have no problem running one instance of the dialog. The problem is when I have two or objects of that dialog, the first is working fine but the other is not.

Any ideas?
Mhelinx
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9656495
Something like this:

BOOL CSomeClass::ShowDialog(CWnd* pParent,
                                             INPUTINFO* pInputInfo,             // [in]
                                             OUTPUTINFO* pOutputInfo)       // [out]
{

    CMyDlg dlg(pParent);

    dlg.SetInputInfo(pInputInfo);
    dlg.SetOutputInfo(pOutputnfo);

    HINSTANCE h = AfxGetResourceHandle( );
    AfxSetResourceHandle(hDll);                      

    int n = dlg.DoModal();

    AfxSetResourceHandle(h);

    return ( n == IDOK );
}

where INPUTINFO, OUTPUTINFO are some structures. Dialog user [in] pInputInfo to initialize it's controls and writes to [out] pOutputnfo results of it's work.
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9656517
Thanks Alex.
I prefer to export the dialog directly.  I make certain resource ID's are unique when I add them (eg IDC_1_EDIT for use in dll1 ...)
0
 

Author Comment

by:mhelinx09
ID: 9656526
Hi Alex,

Sorry but I cannot understand your implementation. Is it ok if you could explain in detail. I'm just a new guy in mfc.

I give an example:
I have a start counter and a show counter in activex. Wht I want is I will create to instances of this dialog (w/ activex)

Now when these two instances are running, I will check the counter of both.

Right now, I only have instance correct since they are using on instance of the dialog (I created an instance of the dialog globally)

I hope someone could help me,
Mhelinx
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9656536
Keeping unique resource ID's among different projects is not a simple task. This is not generic way, but may be good for some situations. mhelinx09 may decide what way is better.
0
 

Author Comment

by:mhelinx09
ID: 9656566
Hi guys,

Also, it is modeless dialog that's why I can create two instance of the dialog.

I hope someone can help.

Mhelinx
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9657151
'Keeping unique resource ID's among different projects is not a simple task'

Create your extension dll
edit resource.h, set the _APS_NEXT_RESOURCE_VALUE etc. to start at say 10000, 11000...
use a naming convention like IDC_1_EDIT

No problems, not very difficult to do either.
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9657170
Hi Mhelinx,

If you use my approach you can create as many copies of the modeless dialog as you wish.

CMyDlg* pDlg1 = new CMyDlg;
pDlg1->Create(....);
pDlg1->ShowWindow(SW_SHOW);

repeat for other pDlg2, pDlg3...

0
 

Author Comment

by:mhelinx09
ID: 9657498
Hi Andy,

But the problem is I have a function that will monitor the activex control. Actually I dont need to display it. It should run w/o a dialog.

I'll show a scenario

DLL:
In global, I have a dialog instance

CmyDialog dlg

In my global function

ShowDialog
{
          if ( !IsWindow(dlg.m_hWnd) )
             dlg.Create(IDD...,Afx..)                // creation of dialog and creation of activex instance
         
           dlg.Start()                      // function inside the dialog with activex functionalities

Another Global function:

Stop
{
        dlg.stop()                         // function inside the dialog that stop the activex from running
}

My problem is if I have to instance, the second instance will not call the dlg.Create since the dialog is already initialized. Therefore, that's my error.

I hope someone can help me.

Mhelinx
0
 

Author Comment

by:mhelinx09
ID: 9657542
Hi,

My problem is if I have two instance, the second instance will not call the dlg.Create since the dialog is already called at the first instance.

Mhelinx
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9657577
You only have one dlg variable - so when you call ShowDlg the second time it is already being shown.
You require something like an array of pointers of your CMyDialogs, in the ShowDlg create a new one with new, display it and return an index to the exe.
The stop requires this index to know which dlg to close down and delete.
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 

Author Comment

by:mhelinx09
ID: 9657603
Hi Andy,

Still if I will create and instance in the ShowDialog global function, I need to create also in the "Stop" global function to call the "Dlg.Stop".

Also, I need to get the instance in the ShowDialog and use that in the Stop function.

Maybe you have some ideas how to implement it.

Thanks again for your help.
Mhelinx
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9657654
CmyDialog dlg
In my global function
ShowDialog
{
          if ( !IsWindow(dlg.m_hWnd) )
             dlg.Create(IDD...,Afx..)                // creation of dialog and creation of activex instance
         
           dlg.Start()                      // function inside the dialog with activex functionalities

Another Global function:
Stop
{
        dlg.stop()                         // function inside the dialog that stop the activex from running
}


How about
CArray arDlgs;  //You will have to construct an array that can hold pointers to CWnds.

ShowDialog
{
CMyDlg *pDlg = new CMyDlg;
arDlgs.Add[pDlg];
pDlg->Create(...)
           
           pDlg->Start()                      // function inside the dialog with activex functionalities

return the index of the top of your array

Stop(int nIndex)
{
        (CMyDlg*)arDlgs[nIndex]->stop()                         // function inside the dialog that stop the activex from running
  delete arDlgs[nIndex];//clean up
}

0
 

Author Comment

by:mhelinx09
ID: 9657802
Hi Andy,
About this code:
CArray arDlgs;  //You will have to construct an array that can hold pointers to CWnds.

I think I'm just dumb not to understand this. Can you give an example.

Thanks again,
Mhelinx
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9658049
Try CDWordArray

then
arDlgs.Add[pDlg];
should be
arDlgs.Add((DWORD)pDlg);
0
 

Author Comment

by:mhelinx09
ID: 9668317
Hi Andy,

It seems that your idea doesnt work or I have no idea how to implement.

I hope you can give much detail about this.

Thanks again.
Mhelinx
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9669162
Implementing a modeless dialog in a dll is much more difficult than a modal dialog.
I would strongly recommend you export the class and create your modeless dialogs in the app.
0
 

Author Comment

by:mhelinx09
ID: 9669320
Hi Andy,

Can you give me a sniffet on how to export the Dialog class in a dll?

Thanks again,
Mhelinx
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9669414
This was my first post in this thread

declare your class in the dll (MFC Extension dll)
class AFX_EXT_CLASS CMyDlg : public CDialog

make this header available to your app eg.
#include "..\\ext_dll\\ext_dll_dlg.h"

Now in the app
CMyDlg dlg(this);
dlg.DoModal();



For a modeless dialog you would need something like the following
CMyDlg* pDlg;
pDlg = new CMyDlg(this);
pDlg->Create(.....);
pDlg->ShowWindow(SW_SHOW);

//You could use a CDWordArray in your app as a member variable (because you wanted a number of dialogs)
m_arDlgs.Add((DWORD)pDlg);//cast the pointer to a DWORD for storage


//And when you cleanup or do something with them recast the DWORD back to a pointer
((CMyDlg*)m_arDlgs[0, 1...n])->DoSomething();

0
 

Author Comment

by:mhelinx09
ID: 9670435
Hi Andy,

It seems that I dont get your idea in exporting. Maybe my idea is not correct. How about returning the dialog class in the application?

Example:

In global function:
extern "C" __declspec(dllexport) void ReturnClass()
{

0
 

Author Comment

by:mhelinx09
ID: 9670462
Hi Andy,

It seems that I dont get your idea in exporting. Maybe my idea is not correct. How about returning the dialog class in the application?

Example:

In global function:
extern "C" __declspec(dllexport) void ReturnClass()
{
 new CMyDlg();
}

In my app:

typedef  CAbstractDlg* (* FnShowDialog)();

FnSaveDlg pfnSaveDlg;

pfnSaveDlg = (pfnSaveDlg)GetProcAddress(Hmod, TEXT("ReturnClass"));

pfnSaveDlg->Start();

But my problem is my CAbstractDlg since I dont know how will I create an abstract dialog.

I tried to create an abstract class that inherits a dialog but it is not working properly.

Do you have an idea?

Thanks again for your patience,
Mhelinx


0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9670594
Hi mhelinx09
please could you let me have your e-mail adress, I'll create a minor proj and mail it to you tomorrow.
Mine is info@ainscow.ch if you didn't want to publicise yours here.
0
 

Author Comment

by:mhelinx09
ID: 9675960
Hi Andy,

I already learned returning the dialog from the dll. It seems that I have only one part left to do.
How to get the resource template from the dll?

I hope you have suggestions.

Mhelinx
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9677185
I have tried to send you an e-mail, it got bounced back from my mail server as an invalid address.
I'll try again soon.
0
 

Author Comment

by:mhelinx09
ID: 9677238
Hi Andy,

I solved the problem. What I did is made the dialog resource ID of the DLL the same as the dialog resource ID in the application.

Right now, it running smoothly.

I'll send you my solution to you through email.

Do you think my idea is correct?

Thanks again for your effort.

Mhelinx
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9677273
Do you think my idea is correct?

NO!  That is a dangerous hack to make it work.
Have you got my e-mail with the attatchment - that will show you how to do it.
0
 

Author Comment

by:mhelinx09
ID: 9677303
Hi Andy,

Based on your implementation, it seems that it is implicit and I have no problem on that. My problem is explicitly linking the dll on my application and get the dialog in the dll.

Once I have the dialog object, I'll call the Create function to dynamically create the activex control.

It seems that I dont have problems with that. Right now, I can create many instances of the dialog by using the vector template and manipulate using the template.

About the resource ID, I have tried to use AfxSetResourceHandle() function just to get the resource dialog inside the dll but it doesnt work. So, what I did I made a Abstract Dialog class. This dialog uses a resource ID the same as the resource ID of the dialog inside the DLL.

That's why I dont have much problem on the implementation.

Maybe you have another approach on this. I will really gld if you can give an detailed idea on what will be my problem.

It seems that it is working pretty well.

Thanks again for your effort.
Mhelinx
0
 
LVL 1

Accepted Solution

by:
GhostMod earned 0 total points
ID: 10376701
Closed, 200 points refunded.
GhostMod
Community Support Moderator
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

707 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

15 Experts available now in Live!

Get 1:1 Help Now