OCX that wraps another OCX

Posted on 1997-03-04
Last Modified: 2013-11-19
I would like to create an OCX control that does some translation and then calls an OCX control to do the work.
for example...
Program uses OCX control to add two scaled numbers
1  Program calls OCX control (Control A).
2  Control A multiplies value by 10 then calls Control B with this value
3  Control B adds 10 to the value then fires an event to Control A.
4  Control A divides this value by 10 then fires an event to the Program

I know how to write the Program and Control B.  Both of these are handled readily by the MFC Wizards.   How do I do Control A?  BTW...What I need to do is actually a lot more complicated,  but I can use the example to do what I need.
Question by:OleUser
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 5

Accepted Solution

manfred022897 earned 200 total points
ID: 1300560
From what you wrote, I assume you are using VC4,x/MFC to write your controls. Try this:
- build B with the wizard, as usual.
- build A with the wizard
- when in A, use 'insert/component' and insert B. The wizard will build a wrapper class for B which is now accessible from inside A.
- whenever an instance of A is created, create an instance of B (this is no more than having a variable of type wrapperB and initialize it, using the Create...() functions of wrapperB)
- that's it. you're A functions get called, and you can delegate to B functions as appropriate.

Author Comment

ID: 1300561
Thanks for your response, but...
1)  I assume that I have COCXControlB   ControlB in my class definition file (I made it protected)
1)  I assume that I want to call the Create function inside of Control A's constructor to initialize the control:  ControlB.Create (NULL, WS_OVERLAPPEDWINDOW,  pRect,  this,  IDC_OCX1);
2) I assume that in my method functions I should call ControlB.MtdFunctions
3) What do I do to receive events?  If I was doing a dialog template container,  I would just pick the control.  I tried copying in the code for the BEGIN_EVENTSINK_MAP / END_EVENTSINK_MAP and associated functions, but it would not compile (I changed the parameters for BEGIN_ to ControlA, COleControl instead of Container, CDialog)

Author Comment

ID: 1300562
BTW...If I do a Create in the Contstructor for Control A,  I get an assert error when I try to insert the control into the Program
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Expert Comment

ID: 1300563
you are creating your control too early. both controls should be children of one of your windows (usually your view), so passing 'this'==controlA as parent (as you did in your code) is questionable. call control.Create() when your view is alive, not in the constructor.
Perhaps this weekend I'll find time to write some demo code.

Author Comment

ID: 1300564
What I would like to do is to be able to hide ControlB completely from the program...for example,  if they want to use Control A in VB then I would like to have it so that Control B does not have to be added.  Perhaps Control A creates what amounts to an object window in which to place Control B????

Expert Comment

ID: 1300565
(back from long weekend...)
what do you mean by 'control B does not have to be added'? You will always have to sell and register bnoth control A and control B, even, if A is a complete wrapper for B and contains an instance of B.
Please tell me once again what you are trying to do (write a control that has the functionality of another, but nobody should know ?? ;) ), and I'll try to get some demo code.


Author Comment

ID: 1300566
Sorry,  I meant to say that I was hoping that Control B did not have to be added to the main program.  I was hoping that the user of my control would not have to do anything with Control B in his program.
If that is not possible,  that is ok.  I realize that I have to sell and register Control B,  but if Control B did not have to be instantiated in the main program,  that would be great.
I am basically trying to write a control that takes a string based format,  then converts it to command(s) to send out to another Control that has already been written (i.e. we are OEMing a control upon which I am trying to place another interface).
Any sample code/demo code would be very helpful.  Thank you for your patience.

Expert Comment

ID: 1300567
now, the promised info.

the following will create two controls:
- 'crunch' which can multiply 2 shorts, returning a short
and firing an event in case of overflow;
- 'interface' which will contain 'crunch', squaring a number
by delegating to crunch and handling any events crunch fires.

to use this, you only have to insert 'interface' in an app; crunch' remains invisible.

create ctrlCrunch (std ole wizard)

insert method:

short ctrlCrunch::multiply(short m0, short m1)
!      long result = m0 * m1;
!      if(result > 0xffffL) {
!            // tell client we have a numerical problem...
!            FireOverflow(result);
!            result = 0;
!      }
!      return (short) result;

insert event: overflow(long val);


create ctrlInterface (std ole wizard)

insert component 'crunch', you get a wrapper class CCrunch;
remember to include the header file ccrunch.h in some sources

insert member 'CCrunch m_crunch' into CCtrlInterface

handle WM_CREATE->

      if (COleControl::OnCreate(lpCreateStruct) == -1)
            return -1;

!      // this is very important - we are in a different module!
!      AfxEnableControlContainer();

      // create subcontrol - do not pass something else as parent (must be in permanent wnd map)
!      m_crunch.Create("", WS_CHILD, CRect(0, 0, 1, 1), this, <someID>);

      return 0;

insert method:

short CCtrlInterfaceCtrl::square(short n)
!      // delegate to contained control HERE
!      // subcontrol will fire event on overflow and return 0
!      short res = m_crunch.multiply(n, n);
!      // just show results of call
!      CString s;
!      s.Format("ctrlInterface: square of %d (as calculated by m_crunch) is %d", n, res);
!      AfxMessageBox(s);
!      return res;

event handling:
insert DECLARE_EVENTSINK_MAP() in CCtrlInterface.h

insert event map (easy way: create scratch dialog; insert crunch control; open classwizard, select crunchControl
and write handler for crunch's event; this will insert an eventsink map to the dialog; copy this, changing
the class names and inserting the id you passed in ctrlCrunch.Create())



Expert Comment

ID: 1300568
what about a response??

Author Comment

ID: 1300569
I'll get back with a response as soon as possible,  I am trying out the code now.

Author Comment

ID: 1300570
OK,  I have tried out the code.  The daughter control "crunch" never gets created because the WM_CREATE call is never made in the "Interface" control... Am I missing something?
Thank you for your patience.

Author Comment

ID: 1300571
I have solved the problem if I put the control on a dialog box,  please explain how your method works

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
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.
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.

729 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