When creating a MFC DLL project in VC++ 2005, you get a screen "application settings" with a choice of Regular DLL with static/dynamic MFC, or an MFC Extension DLL.
We want a DLL that contains a few common dialogs, so we can use them in other projects e.g:
CGetNameDlg *dlg = new CGetNameDlg();
dlg->doModal();
string name = dlg->getName();
delete dlg;
We're not sure whether this requires an extension DLL... if those are specifically for adding new controls to enhance MFC itself, or if we just do a regular DLL project linking to MFC dynamically, like we would if it was an EXE project.
Personally, I'd create a regular DLL. I find that a regular DLL gives a much greater separation of code than an extension DLL, with the added complexity of having the use the AFX_MANAGE_STATE() macro at the entry point of each call into the DLL.
And if you design your code well (eg. pass only native objects to/from the DLL), you can use the same DLL in a plain win32 app/C# app/VB app with little trouble.
You'll be fine to do it as a regular DLL rather than an MFC extension and would be my preferred choice.
Related
I want to know what are the different scenarios where AfxInitRichEdit2() method can be called.
It just loads a specific DLL and with this DLL some window classes are registered into the current process.
In the past calling AfxInitRichEdit and AfxInitRichEdit2 was the way to distinguish between two existing RTF window classes (Version 1.0:RICHED32.DLL and version 2.0: RICHED20.DLL). Just read the MSDN about the Rich Edit window class.
Opening a VB6 Project, I get errors like:
Errors during load. Refer to xyz.LOG
I open the log file and see these errors:
Line 42: Class Threed.SSPanel of control XYZ was not a loaded control
class.
In this case I can see the problem is due to the Sheridan 3D Controls: C:\WINDOWS\system32\THREED32.OCX
I thought the project was missing a component so, VB6 > Project > Components > tick the Sheridan 3D Controls and got this error:
---------------------- Microsoft Visual Basic ---------------------------
Name conflicts with existing module, project, or object library
--------------------------- OK Help ---------------------------
I will give you the best way to get rid of this problem. I came across many ways, but this is the most best way to deal with..
Close the project. Right click on the vb project and open with notepad (not with vb). This Project file will only consist of all the references, libraries and information about forms and modules used in the project.
Now just remove the conflicting module or component file, you have problem, by just deleting the entire line.. Save and close it
and now open the project and add component. I swear you wont get that error.
Thank you. Enjoy
The way to troubleshoot this problem is to start a new VB6 project > Project Menu Components > tick the Components that are selected in the affected project until you get the error.
---------------------- Microsoft Visual Basic ---------------------------
Name conflicts with existing module, project, or object library
--------------------------- OK Help ---------------------------
You need to narrow it down to the two OCX's that are conflicting.
In my case I narrowed it down to Sheridan 3D Controls / THREED32.OCX and Outrider Spin Control / SPIN32.ocx
To fix the problem I used RegSvr32 to unregister the OCXs - make sure you UNregister with the /u flag.
REGSVR32 "C:\WINDOWS\system32\THREED32.OCX" /u
I then copied the OCX's to the project folder and registered them again using:
REGSVR32 "C:\Dev\Project\THREED32.OCX"
Then in the project with the problem > Project Menu Components > select the item in the listbox Sheridan 3D controls / THREED32.ocx (you cant tick without getting the error or untick the conflicting one that is selected as its in use) > click Browse and reference it from the project folder rather than C:\WINDOWS\system32\
Another trick is close the project and unregister the affected ocx - make sure you UNregister it with the /u flag, eg
RegSvr32 "c:\Windows\system32\mscomctl.ocx" /u
Then open the project > Components > and you should see the "Microsoft Windows Common Controls 6.0 (SP6)" is using a OCX file in C:...\Microsoft Vi..\VB98\mscomctl.ocx" rather than c:\Windows\system32\mscomctl.ocx.
The project should then load without these errors:
Errors during load. Refer to xyz.LOG
Try unchecking the latest object library / reference from the references and check it again and then go for your desired reference (vb6 has few bugs which can be countered by a reverse process). I solved the error mentioned using this process.
I have VB6 ActiveX (e.g. MyActiveX) that is used from MFC:
m_pControl = new CWnd;
m_pControl->CreateControl("MyActiveX.MainControl",
"",
WS_VISIBLE,
rc,
this,
5000,
NULL,
FALSE,
NULL);
When I remove some unused function or move variable (not used outside VB ActiveX), VB6 warns about breaking compatibility. I chose to break compatibility but now the VB6 ActiveX is not shown properly from MFC application.
As I understand, breaking compatibility will create new UUID for the interface and type library. That is fine as long as I can do something to make it work again, and since I am using a string ProgID MyActiveX.MainControl, I think my MFC app shouldn't get affected.
Edit:
As I understand from Resetting project compatibility in vb6, breaking compatibility is okay as long as I rebuilt projects that refer to it. But from MFC, I only refer to the VB project using a string MyActiveX.MainControl so I don't see why I should rebuild my MFC app; and even after rebuilding my C++ MFC app, the VB ActiveX is still not properly shown.
Only two functions in VB6 ActiveX that are actually used from C++ MFC side. That's why I removed/moved some other functions and variables that are only used from within VB6 ActiveX. So I'm not sure why it stopped being displayed properly
No. VB6 is right. The Problem is about the Interface you use, the properties and Events.
It depends on how you integrated the Control into the MFC. As Long as all DispIds (dispatch Ids from the IDispatch Interface) are stable, and as Long as all function you use are still available you don't have a problem.
If DispIDs are changing, function prototypes change, you will get into Problems.
I want to add a new class to my Visual C++ 6 project using Class Wizard. I don't want this class to inherit from anything. My class has a function to accept input as integer, and process it
The Class Wizard requires me to add a base class and a DialogID . Which one of the base classes and dialog ID shoud I select? I'm a C# developer and find it really annoying. Should I mannually add my class? How do i do it in Visual C++ 6
Don't use Class Wizard (which is for creating visual dialogs and is why it wants a dialog id).
Use Project->Add from the menu. There are several other types of things you can add to your project that don't involve visual dialogs, like header (.h) and source code (.cpp) files.
i have a legacy massive vb6 editor with plenty of 3rd party libraries and controls and recently there is a need to set it up to make it multi thread so i can run a few other forms independently from the main editor form. Basically there's minimum communication between these other forms and the main editor except for running the other forms on a click of a button from the main page.
So from a lot of googling i found a method which converts the current app into a multi threading one by setting it up as an activex exe and adding a class set to global-multi-use to allow this to happen. Now while doing editing and testing via debugging mode, i found that when i exit a lot of weird crash will happen sometimes.
'main.frm - button click call
'On the button click, create a new object
Set obj = CreateObject("MyApp.clsThread")
Call obj.NewThread
'clsThread
' Create a new form and load it to run on a new thread
Public Sub NewThread()
Dim frm As Object
Set frm = New frmDogbert
Load frmDogbert
frm.show
Set frm = Nothing
End Sub
So what do i absolutely must know when i do this,i.e. potential problems,etc?, as i'm fearing that the app seems to be getting more unstable. Or is there a better way to do this?
Updates:
Instead of forcefully hacking my app into a pseudo multithreading app, i've taken the advice from the good people here and refactor out the component into standard exe and reverted back my app to a standard exe and call them via shell. Works beautifully :)
Thanks
Visual Basic 6 is not multi threading in of itself. The difference in the multi-tasking behavior between a ActiveX EXE and a ActiveX DLL is only apparent when referenced from another VB6 EXE. Objects instantiated from a Global Multi-Use Class defined in a ActiveX EXE run in their own context. Object instantiated from a ActiveX DLL are run in the context of the calling EXE.
Now multi-threading can be hacked into VB6 but it is very touchy and has a lot of don't (for example you can't use the stop button in the IDE to stop a debugging session or the program will crash).
What a ActiveX EXE is good is for spawning a separate but related instance that can run separately without halting the main program. Based on your brief description I would say your best best is to keep your EXE as is but more the forms/modules/classes to a separate EXE and have the original EXE reference the ActiveX EXE.
Note that you don't have to compile down to .EXE you can change the extension to .DLL and it is still a activeX EXE. You do this so that the user doesn't mistakely run the ActiveX EXE by itself.
Can you clarify the question a bit? I don't understand why it needs to be multi-threaded? Why can't you just display the forms non-modal, then they will all be visible and responsive at the same time. Unless you have some background processing operating all the time in your main form, which sounds unlikely from your question as it would lock up the main form as well as the others.
Melaos says: Well the main editor frm is the main thing here and I need to allow the user to run additional forms to do some other stuff like uploading things to our server and convert video files to other formats. And these forms use shell to call other exes. And the running time takes quite a while.
In that case I recommend making the other forms into separate EXEs rather than use multithreading, which is difficult. You say there's little communication from the main form to the subforms - it just shows them. Therefore you don't even need to make the subforms ActiveX EXEs. Just make them standard EXEs and shell them from the main form.