VB6 ActiveX stopped working from MFC after breaking compatibility - visual-c++

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.

Related

what is the use of AfxInitRichEdit2(); in mfc application

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.

Programming wpf xaml vs windows rt with c# and xaml

Ok. I know wpf and am learning programming windows runtime via c# and xaml.
Both use xaml that have the same namespace. Win rt is new and has the same namespace declared at the root element.
What are the similarities and differences.
Here are some of the differences between WPF and WinRT:
Different XML namespace declaration in XAML code (Instead of using a clr-namespace:/assembly= qualifier set for code-to-XAML namespace references, you use the using: qualifier. XAML namespaces no longer reference specific assemblies)
Missing Expression SDK in WPF
Missing Property-/DataTriggers in WPF
Reduced BindingMode enum
Missing Multi/Priority Binding in WPF
Missing RoutedCommands in WPF
Missing InputBindings in WPF
DependencyProperty value calculation goes without coercion and validation
There are lot more differences. You can check this link to know further.

Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED)): ActiveX and C# Console Application

So, I am playing around with ActiveX and C# and ways how both of them can work together. the thing is I have hit the wall right in the beginning with mentioned error. Steps I have followed:
In VS2010 I selected MFC ActiveX Control project. Then I added a method "SHORT Multiply( SHORT a, SHORT b);" by clicking the Add method option in the menu that pops when you right click _DProjectname under ProjectnameLib in solution explorer. The code for the method is as follows:
SHORT CSampleProgramActivex01Ctrl::Multiply(SHORT a, SHORT b)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// TODO: Add your dispatch handler code here
return ( a * b);
}
Now I have created a simple C# console application that references the generated COM file and when I try to use the method, the application stops with the above mentioned error. I have searched the error on the internet but no clear solution is mentioned. Any help appreciated. If you guys want clarification, let me know.
I don't know whether this is considered as solving the problem or not but I found a workaround:
First instead of C# console application, I created C# windows form application. After creating the form, I have added the whole ocx as component in the toolbox. You do this by right-clicking the Toolbox types in Toolbox menu. In the new menu, you click Choose Items. This pops up new menu and in that select the COM tab and in that check your COM component and the COM component will be added to the Toolbox menu. Now drag and drop the component on the menu and you should be good to go.
This seems to be workaround that everybody is following. Not neat but that is the norm I think.
look at here: How to use an OLE control as an automation server in Visual C++
http://support.microsoft.com/kb/146120/en-us

Creating a shared MFC Dialog: Regular DLL or MFC extension DLL

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.

What is the Best Practice for converting a vb6 standard exe to a activex exe?

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.

Resources