Solved

Overriding an ActiveX control's functions

Posted on 2002-05-02
7
840 Views
Last Modified: 2013-11-18
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
Comment
Question by:Morten from Eliten
7 Comments
 
LVL 22

Expert Comment

by:ambience
ID: 6987873
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
 

Author Comment

by:Morten from Eliten
ID: 6987957
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
 
LVL 22

Expert Comment

by:ambience
ID: 6987990
>> 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
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 

Author Comment

by:Morten from Eliten
ID: 6988688
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
 
LVL 11

Expert Comment

by:griessh
ID: 7178474
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
 

Author Comment

by:Morten from Eliten
ID: 7179659
Thanks Werner, you are right, there was no satisfying answer for me.
0
 
LVL 6

Accepted Solution

by:
Mindphaser earned 0 total points
ID: 7199728
Points refunded and moved to PAQ

** Mindphaser - Community Support Moderator **
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

705 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

17 Experts available now in Live!

Get 1:1 Help Now