Go Premium for a chance to win a PS4. Enter to Win

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

Overriding an ActiveX control's functions

I have a fully functional control ATL Full control, which I need to add some functionality to, without changing the source code of the control itself.

I need to override the control's OnPaint() function, so that I can draw my own output on top of the output that the control generated. This would not be such a big problem if it wasn't becourse the control is Windowed only.

My problem is that I have no way of telling when the control is done drawing, and without knowing that Im unable to paint on top of the control output.

I have allready tried to solve the problem by setting up window hooks, to catch the WM_PAINT message, but for some reason there is no end notification from a WM_PAINT (End notifications are received using the WH_CALLWNDPROCRET hook style).

I have also tried to create an aggregated ATL Full control, but my limited knowledge about ActiveX interfaces prevented me succeeding in that as well.

Any advice or code examples on how to solve this problem would be greatly appreciated.
0
Morten from Eliten
Asked:
Morten from Eliten
1 Solution
 
ambienceCommented:
Ok a thought, maybe you can aggregate (better word here is contain) the control inside a new control (that should basically be a container for the existing control).

In your new controls IVewObject::Draw() you first ask the aggregated control to draw and then do your custom drawing.

For other methods and properties you can simply delegate that call to the contained control.

So your control implements the same set of interfaces that the orginal one has, from outside it would appear like the same control.
0
 
Morten from ElitenAuthor Commented:
Yes ambience thats what I tried to do, using the ATL Full Control. Unfortunately ATL only allows aggregating entire interfaces, and some of those interfaces have to be aggregated together with some of the other interfaces. Furthermore it is furthermore complicated by the fact that the object can be drawn by other methods than the IViewObject::Draw() method.

When I aggregated the IOleObject the object would be drawn by the aggregated control and the IViewObject had no effect on the object drawing.

Furthermore the issue is complicated by the client of the COM Control. If I use the ActiveX test container, to test the aggregating object, specific interfaces will be used - If I use an MFG Dialog project to test the object, diffrent interfaces will be used.

This means that I have to have more knowledge about which interfaces do what and how they depend on eachother - Knowledge I don't have a lot of.
0
 
ambienceCommented:
>> Unfortunately ATL only allows aggregating
entire interfaces

what do you mean by aggregating interface, i've never heard of anything like that.

>> the object can be drawn by other
methods than the IViewObject::Draw() method.

like ?

>> Furthermore the issue is complicated by the client of the COM Control. If I use the ActiveX test container,
to test the aggregating object, specific interfaces will be used - If I use an MFG Dialog project to
test the object, diffrent interfaces will be used.

I do not think so, how could that be possible, only the interfaces supported by your control can be used and there is a predifned minimum set of interfaces required to be implemented by both the container and the control, though they can elect to implement more than that, but minimum is mandatory, also there is a well defined protocol of communication between the container and control, so no way its possible that two containers use different interfaces of the same control altogether.

for ex. its defined what IViewObject is for and every container must make use of that to ask the control to draw itself.

Maybe there is a problem in the way you are trying to contain the control. Here is a rough sketch of what should be there.

// kindof pseudo code
control1
{
   IViewObject::Draw() ...
   ISomeInterface::SomeFunc() ...  
};

here is what you should try to do

control2
{
   IViewObject::Draw()
   {
       pcont->Draw();
       // Now its time to draw over that
   }

   ISomeInterface::SomeFunc()  
   {
      // delegate call to control1
      return pcont->SomeFunc();
   }
 
   control1 pcont;
}

this is something like interception of calls, NOTE that this is one way to simulate inheritance in COM.

The best way is to first wrap all the control and do not do any custom stuff, once you get the control working (it should behave like the contained one), then its time to go for customizations.

If you have tried the same then perhaps you can post some info with what exactly you did, possibly with code samples of how you are creating the contained control and how are you delegating the calls.
0
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!

 
Morten from ElitenAuthor Commented:
Aggregation of interface:
// This code sample aggregates the IViewObject interface from the aggregated control (m_pAggregatedCtrl).
BEGIN_COM_MAP(CAggregationCtrl)COM_INTERFACE_ENTRY_AGGREGATE(IID_IViewObject, m_pAggregatedCtrl)
END_COM_MAP()

>> the object can be drawn by other methods than the IViewObject::Draw() method.
>>>> like ?
Aggregating the IViewObject interface from the aggregated control does not make the aggregated control render on the device context.

Aggregating the IOleObject from the aggregated control WILL make the aggregated control render on the device context.

>>I do not think so, how could that be possible, only the interfaces supported by your control can be used...
Testing the control in the ActiveX control test container will not utilize all interfaces supported by the control.

Testing the control using an MFC dialog box will also not use all the interfaces supported by the control.

I have been able to aggregate a lot more interfaces, and then successfully test the control in the ActiveX control test container, than an MFC dialog project will allow me to. The MFC dialog project will generate ASSERTION failures when certain interfaces are aggregated, but will function properly if either none or all of the interfaces are aggregated from the contained control.

I know that aggregating specific function calls is very easy to do in pseudo code, but its not the pseudo code I have problems with, its the actual implementation of the code that bugs me.

For example, this sample code will not work:

class CAggregatingControl
:public IViewObject
{
 Draw(...)
 {
  m_pAggregatedControl->Draw(...)
  // Draw stuff
 }
}

Since aggregating the IViewObject interface doesn't make the aggregated control draw stuff in the DC (However aggregating IOleObject did).
0
 
griesshCommented:
Dear Morten_From_Eliten

I think you forgot this question. I will ask Community Support to close it unless you finalize it within 7 days. You can always request to keep this question open. But remember, experts can only help you if you provide feedback to their questions.
Unless there is objection or further activity,  I will suggest to

     "refund the points and PAQ at zero points"

since nobody had a satisfying answer for you.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
======
Werner
0
 
Morten from ElitenAuthor Commented:
Thanks Werner, you are right, there was no satisfying answer for me.
0
 
MindphaserCommented:
Points refunded and moved to PAQ

** Mindphaser - Community Support Moderator **
0

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

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