[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1021
  • Last Modified:

ActiveX addons

Hi,
First let me tell what I must do. I have been asked to do one application that can program many kinds of hardware devices.
Some of them I know, others I do not. This mean that my application must be prepared for new devices.
Furthermore, the programming software for each device should be available for other applications.
Ok, after this I began studying controls (activeX controls).
It seems to me that if I could make each programming software one activex then the problem of using in other environments
will be solved. Further, if a new device appears then I will just have to do another activeX.
Of course, the activeX interfaces would have to be the same for everybody.
Here is my big problem. How can I do my application to accept addons whithout the .h files!?!
Ok, my question is a bit weird but I am new to this world.
I have been able to make some simpler activex controls. But I have many problems in using them. This is
because my application can only meet them on runtime.
I think that what I want is something like the MMC functionality. That is we can add things on runtime.

So, lets suppose that I have the following CString OCXFile. This has been filled by one user action to lets say
c:\whatever\ocx\addon\addon_numb3.ocx.
Lets suppose also that each of my addons will have the methode AboutBox.
How can I call this method by simpling knowing the name of the ocxFile!?
Maybe I am wrong but I am thinking like C++. That Is I Have on class purely virtual with the names of the methods.
My addons are all derived from this class. On creation of the addon is the selection of it.

From what I have read one way is to insert the activex in a dialog box.
But for me this is impossible because the application must stablish the contact on run.

Every comments and solutions will be mostly appreciated.
I am giving a significant amount of points because I am looking for good comments to guide me and not just lines
of code.

My thanks for reading this.

0
lsimaozinho
Asked:
lsimaozinho
  • 7
  • 5
1 Solution
 
_mb_Commented:
There are two steps for using an activeX component:

1. The declaration of a DispatchDriver class. You get it, if you creates a new class from your component's type library (.tlb file) using the class wizard. You said all of your activeX will get the same structure. So you can take a type library of an arbitrary activeX you created. The declaration will works with all others.

2. Connect the DispatchDriver class with you activeX. It looks like similar to this:

IMyDispatchClass     m_Idsp;  //IMyDispatchClass is your DispatchDriver class

if( m_Idsp.CreateDispatch("<programmatic identifier>") )
{
      m_Idsp.MethodOfActiveX(...); //usage
}

The programmatic identifier refers to your activeX (such as "Excel.Application") and you can use all of your activeX by inserting of their programmatic identifier.
0
 
lsimaozinhoAuthor Commented:
Thanks mb,
I will now try your comment.
But there are two doubts that I still have:
How can my application automatically register the activex? Or is it better to have it register with regsrv32.exe?
Also the programmatic identifier can be retrieved from the registry or from the file?

The programmatic identifier is related with the CLSID of the object in the activeX?

0
 
lsimaozinhoAuthor Commented:
I am getting the following error when invoking AboutBox.
"Warning: constructing COleException, scode = E_UNEXPECTED ($8000FFFF).
First-chance exception in Teste.exe: 0xE06D7363: Microsoft C++ Exception.
Warning: Uncaught exception in WindowProc (returning 1)."

My activex is windowless. Must I do something before invoking methods that create windows!?

From my last comment:
I have been trying things and I Think I can register each activex in my application with LoadLibrary/Dllregister.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
lsimaozinhoAuthor Commented:
For the problem that I am having with AboutBox call, I have found
the following:
The code :
"
// allow subclass to disable Invoke
if (!pThis->IsInvokeAllowed(dispid))
      return E_UNEXPECTED;
"
in STDMETHODIMP COleDispatchImpl::Invoke(
      DISPID dispid, REFIID riid, LCID lcid,
      WORD wFlags, DISPPARAMS* pDispParams, LPVARIANT pvarResult,
      LPEXCEPINFO pexcepinfo, UINT* puArgErr)

file:Oledip1.cpp.

is returning E_UNEXPECTED because (and here is the code of IsInvokeAllowed)
"
BOOL COleControl::IsInvokeAllowed(DISPID)
{
      return m_bInitialized;
}
"

m_bInitialized is FALSE!

I have only found one place where m_bInitialize is made TRUE:
"HRESULT COleControl::LoadState(IStream* pstm)"

This is what I have discovered, but I still do not know why is properties initialization
being tested by the library when I invoke one method!
Also what must I do to make LoadState be called?
And finally, I feel that LoadState is for persistence.
What function must I call to serialize and give one IStream (or like it)?


Sorry about my confusion but has I sayed I am new to this :)

0
 
_mb_Commented:
I'll try answer to your comments.

registration:
I think you need regsvr32 to register an activeX, because there are registry entrys necessary.
The programmatic identifier refers to the activeX like the CLSID. It built from the activeX application name and it's automation class name. You can also use the CLSID, but it's easier to work with the programmatic identifier.

exception error:
The application, that calls an activeX need the function call AfxOleInit(); to initialisize OLE automation. A good place for it is the InitInstance() member of your CWinApp derived class.
I hope it can solve the problem.
0
 
lsimaozinhoAuthor Commented:
Sorry mb but AfxOleInit() does not solve the problem!
My InitInstance function is now
AfxEnableControlContainer();
AfxOleInit();

and everything is the same!

I still have the error!
Now I am doing:
"
if( m_Idsp.CreateDispatch("SMB050.ProgCtrl.1") )
      {
            try
            {
                  m_Idsp.AboutBox();
            }
            catch (COleException * e)
            {
                  TRACE("Erro : %d\n",e->m_sc);
                  e->Delete();
            }
      }
"

and getting:
"Warning: constructing COleException, scode = E_UNEXPECTED ($8000FFFF).
First-chance exception in Teste.exe: 0xE06D7363: Microsoft C++ Exception.
Erro : -2147418113"
!!!
0
 
_mb_Commented:
How works your AboutBox() - function?
0
 
lsimaozinhoAuthor Commented:
Here is the code generated from the wizard:

"/////////////////////////////////////////////////////////////////////////////
// CSMB050Ctrl::AboutBox - Display an "About" box to the user

void CSMB050Ctrl::AboutBox()
{
      CDialog dlgAbout(IDD_ABOUTBOX_SMB050);
      dlgAbout.DoModal();
}"
0
 
_mb_Commented:
I dont't know, there's a problem to start a dialog. Did you try other functions?
You can make a test: run a message box ( AfxMessageBox("...."); or only return a value to check, if the function generally works.
0
 
lsimaozinhoAuthor Commented:
First, sorry mb for this long delay.
The problem is that I am accessing internet from home and I have my work far.

I have solved with a different approach.
I have never understand the problem but I have just made a simple thing: Using the add to project - activex control from VStudio!
0
 
lsimaozinhoAuthor Commented:
Comment accepted as answer
0
 
_mb_Commented:
Don't worry about the delay, I'm glad that you found a solution.
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

  • 7
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now