Solved

OCX that wraps another OCX

Posted on 1997-03-04
12
427 Views
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.
0
Comment
Question by:OleUser
  • 7
  • 5
12 Comments
 

Accepted Solution

by:
manfred022897 earned 200 total points
Comment Utility
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.
0
 

Author Comment

by:OleUser
Comment Utility
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)
0
 

Author Comment

by:OleUser
Comment Utility
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
0
 

Expert Comment

by:manfred022897
Comment Utility
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.
0
 

Author Comment

by:OleUser
Comment Utility
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????
0
 

Expert Comment

by:manfred022897
Comment Utility
(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.

0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:OleUser
Comment Utility
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.
0
 

Expert Comment

by:manfred022897
Comment Utility
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->

OnCreate(...)
{
      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())

HTH!

-manfred
0
 

Expert Comment

by:manfred022897
Comment Utility
what about a response??
0
 

Author Comment

by:OleUser
Comment Utility
I'll get back with a response as soon as possible,  I am trying out the code now.
0
 

Author Comment

by:OleUser
Comment Utility
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.
0
 

Author Comment

by:OleUser
Comment Utility
I have solved the problem if I put the control on a dialog box,  please explain how your method works
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
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.
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…

743 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now