-
A question regarding AFX_MANAGE_STATE
As we know, if you want to launch a dialog from a dll, you have to call AFX_MANAGE_STATE to switch module state from current module state to dll module state. Here is the code,
Code:
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CMyDialog dlg;
dlg.DoModal();
Now if I want to launch another dialog called CYourDialog from CMyDialog and CYourDialog is defined from different module state, then DoModal would fail for CYourDialog. Is there any way to make DoModal work for CYourDialog in this case? Thanks.
-
Re: A question regarding AFX_MANAGE_STATE
According to http://msdn.microsoft.com/en-us/libr...tx(VS.80).aspx
Quote:
You must add the AFX_MANAGE_STATE macro at the beginning of all the exported functions in regular DLLs that dynamically link to MFC to set the current module state to the one for the DLL. This is done by adding the following line of code to the beginning of functions exported from the DLL:
Code:
AFX_MANAGE_STATE(AfxGetStaticModuleState( ))
-
Re: A question regarding AFX_MANAGE_STATE
Quote:
Originally Posted by
LarryChen
Now if I want to launch another dialog called CYourDialog from CMyDialog and CYourDialog is defined from different module state, then DoModal would fail for CYourDialog. Is there any way to make DoModal work for CYourDialog in this case? Thanks.
You should set the module state correctly before loading any resources from a DLL, so also before you create the second dialog.
-
Re: A question regarding AFX_MANAGE_STATE
Quote:
Originally Posted by
D_Drmmr
You should set the module state correctly before loading any resources from a DLL, so also before you create the second dialog.
That is exactly my question actually. In my case, Basically CMyDialog and CYourDialog exist in different module states. CMyDialog is not dismissed yet when CYourDialog needs to be launched. So in order to launch CYourDialog, I need to switch the module state from CMyDialog to CYourDialog. But I don't know what to do to achieve that. Any idea how to do that? Thanks.
-
Re: A question regarding AFX_MANAGE_STATE
You have to do it within your DLL.
-
Re: A question regarding AFX_MANAGE_STATE
Quote:
Originally Posted by
VictorN
You have to do it within your DLL.
I know I have to do it within my dll. But the problem is that in my case, the template for CYourDialog exists outside the dll. So within the dll, if I want to launch CYourDialog I need to switch the module state from dll to CYourDialog. But I don't know how to do it. Any idea? Thanks.
-
Re: A question regarding AFX_MANAGE_STATE
Strange design!
Why not to use extension dll in such a case instead?
-
Re: A question regarding AFX_MANAGE_STATE
Quote:
Originally Posted by
VictorN
Strange design!
Why not to use extension dll in such a case instead?
May I ask why you think this is a strange design? What can an extension dll do in my case? Thanks.
-
Re: A question regarding AFX_MANAGE_STATE
At least it does not need any AFX_MANAGE_STATE at all.
-
1 Attachment(s)
Re: A question regarding AFX_MANAGE_STATE
Now I like to approach this dialog launching thing step by step. I am not clear conceptually on this topic so please bear with me. First of all, I attached a project. In this project, an executable tries to launch a dialog defined in a dll. Unfortunately I got a linker error "error LNK2019: unresolved external symbol "public: virtual __thiscall CMyDialog::~CMyDialog(void)" (??1CMyDialog@@UAE@XZ) referenced in function "public: void __thiscall CtestMFCExtensionDlg::OnBnClickedStart(void)" (?OnBnClickedStart@CtestMFCExtensionDlg@@QAEXXZ)". I couldn't figure out why. Please help me fix this issue first. Thank you very much!
-
Re: A question regarding AFX_MANAGE_STATE
Did you include .lib file containing info about CMyDialog class?
-
Re: A question regarding AFX_MANAGE_STATE
Quote:
Originally Posted by
LarryChen
That is exactly my question actually. In my case, Basically CMyDialog and CYourDialog exist in different module states. CMyDialog is not dismissed yet when CYourDialog needs to be launched. So in order to launch CYourDialog, I need to switch the module state from CMyDialog to CYourDialog. But I don't know what to do to achieve that. Any idea how to do that? Thanks.
You cannot set the module state to a dialog, you set it to the instance handle of a library. Whenever you load resources from a DLL (e.g. create a dialog, which loads the dialog template from the resources), the module state needs to be set to the instance handle of that library. After the resources have been loaded, you simply set it back to the previous value. This is what AFX_MANAGE_STATE does (resetting the instance handle at scope exit.
When you use an extension DLL, the story is different. See the MSDN docs.
-
1 Attachment(s)
Re: A question regarding AFX_MANAGE_STATE
The sample goes. Resource only DLL includes IDD_YOUR dialog template. Regular DLL includes IDD_MY dialog template, but implements both classes, CMyDialog and CYourDialog. Hope this close enough to what you're trying to implement.
-
Re: A question regarding AFX_MANAGE_STATE
Quote:
Originally Posted by
VictorN
Did you include .lib file containing info about CMyDialog class?
Yes. I included .lib file by setting Linker/input/Additional dependencies. If you check the project, you will see it. Anything wrong or missing? Thanks.
-
Re: A question regarding AFX_MANAGE_STATE
Quote:
Originally Posted by
D_Drmmr
You cannot set the module state to a dialog, you set it to the instance handle of a library. Whenever you load resources from a DLL (e.g. create a dialog, which loads the dialog template from the resources), the module state needs to be set to the instance handle of that library. After the resources have been loaded, you simply set it back to the previous value. This is what AFX_MANAGE_STATE does (resetting the instance handle at scope exit.
When you use an extension DLL, the story is different. See the MSDN docs.
I tried to do it like this,
Code:
HMODULE hDll = GetModuleHandle(_T("MyDll.dll"));
AFX_MANAGE_STATE((AFX_MODULE_STATE*)&hDll);
CYourDialog dlg;
dlg.DoModal();
Here MyDll.dll is the dll where CYourDialog is defined. But I got an exception in AfxFindResourceHandle. What is wrong? Thanks.
-
Re: A question regarding AFX_MANAGE_STATE
Quote:
Originally Posted by
Igor Vartanov
The sample goes. Resource only DLL includes IDD_YOUR dialog template. Regular DLL includes IDD_MY dialog template, but implements both classes, CMyDialog and CYourDialog. Hope this close enough to what you're trying to implement.
Thanks for your sample. Actually CMyDialog and CYourDialog are defined in two different dll. Basically what happens is that an exe launches CMyDialog defined in MyDll.dll and then when CMyDialog is NOT dismissed, CYourDialog is launched from defined in YourDll.dll. I would really appreciate it if you can post a sample by using MFC. Thank you very much!
-
Re: A question regarding AFX_MANAGE_STATE
Quote:
Basically what happens is that an exe launches CMyDialog defined in MyDll.dll and then when CMyDialog is NOT dismissed, CYourDialog is launched from defined in YourDll.dll. I would really appreciate it if you can post a sample by using MFC.
I wonder if you weren't able to look at the sample. In there, exe launches CMyDialog defined in regular dll, and CYourDialog is launched from the CMyDialog when the latter is NOT dismissed. And the sample is all about using MFC classes. Larry, you really should pay some more attention to communication you're participating in.
-
1 Attachment(s)
Re: A question regarding AFX_MANAGE_STATE
Quote:
Originally Posted by
LarryChen
Basically what happens is that an exe launches CMyDialog defined in MyDll.dll and then when CMyDialog is NOT dismissed, CYourDialog is launched from defined in YourDll.dll.
It doesn't matter where you launch your dialog from. Once you know how to launch it from exe, the same technique is applicable to launching from dll. Sample attached. Here you can see how CYourDialog gets launched from client.exe and my.dll using the same AFX_MANAGE_STATE.
-
1 Attachment(s)
Re: A question regarding AFX_MANAGE_STATE
Quote:
Originally Posted by
Igor Vartanov
It doesn't matter where you launch your dialog from. Once you know how to launch it from exe, the same technique is applicable to launching from dll. Sample attached. Here you can see how CYourDialog gets launched from client.exe and my.dll using the same AFX_MANAGE_STATE.
Thanks for your sample code. When I run the make file in my computer from command line, the system complained that "rc" and "cl" is not recognized as an external or internal command. And then I create a MFC dialog based project in VC2010 and put all of your files into the project. When I build this project, I got a linker error " LNK1104: cannot open file 'my.lib' ". I attached this project with this post. Would you please tell me what I am missing? Thanks.
-
Re: A question regarding AFX_MANAGE_STATE
Well, the answer to the make issue is Visual Studio Command Prompt.
-
Re: A question regarding AFX_MANAGE_STATE
Quote:
Originally Posted by
Igor Vartanov
Well, the answer to the make issue is Visual Studio Command Prompt.
Actually I tried to run vcvarsall.bat from the folder C:\Program Files\Microsoft Visual Studio 10.0\VC. Then if I run your make.bat in project folder, I still got the same errors. It looks like vcvarsall.bat didn't set up the environment for me to run make.bat. What am I missing here?
BTW, I have fixed the dialog launching problem. It turns out that one of my DLLs to launch the dialog is a MFC extension dll. I couldn't use AFX_MANAGE_STATE like regular dll. So I have to manually set up the resource handle for this dll. It works. Thank you very much!
-
Re: A question regarding AFX_MANAGE_STATE
Quote:
Actually I tried to run vcvarsall.bat from the folder C:\Program Files\Microsoft Visual Studio 10.0\VC. Then if I run your make.bat in project folder, I still got the same errors. It looks like vcvarsall.bat didn't set up the environment for me to run make.bat. What am I missing here?
I'm currently able to build with the make.bat same successfully in standard Command Prompts of VS2010 and VS2012 Tools, as well as VS .NET2003. In fact I use this approach to make since Visual Studio 4, and never had any problem with this.
-
Re: A question regarding AFX_MANAGE_STATE
Hi LarryChen,
Its interesting and , I feel that you want to just check out all possibilities in MFC and VC++ .
Anyways,
Your scenarios is Application A loads dll D1 contains dialog "Mydialog"
then dll D1 loads D2 that contains "YourDialog".
Now App is able to load MyDialog from D1 and you want to load YourDialog from D2 in the code of D1.
I agree to the solutions given by Igor , Victor and all others.
Apart from that just one suggestion is instead of doing DOModal() on YourDialog try to invoke it as modal less.
or may be invoking both the dialogs modal less.