OLE2/ActiveX without using either MFC or the ATL

I have become very interested in making my own custom controls which can be added to a dialogue box at design-time.

There is a tool in the VisualStudio dialogue editor which allows you to add a place holder into your design for a custom control. One of its few properties allows you to specify the name of which Window Class this control will be created from so long as it has been registered before the dialogue box itself is created. The approach works pretty well so far as it goes, especially because the control that is made in this way will receive all the start-up messages like WM_SETFONT among others. In my opinion this is a big step up from having to create the control dynamically at run-time since you can visually position and size it alongside any other standard controls your dialogue box may be using. Following this approach I successfully wrote a superclass of the basic ComboBox. However, by its very nature the custom-control tool offers few properties other than specifying which window styles the control should use. It seems the 'proper' way to create a custom control that the dialogue box editor can use is to wrap it up in an OLE2 object. Unfortunately I know almost nothing about how to programme these things and I think it would be an ideal opportunity to learn more by changing my ComboBox in to a full OLE2 control.

I have spent a couple of hours this evening looking in to the basic ground I need to cover but every tutorial and article I found gave examples using either MFC or ATL. I do not wish to use these class libraries as I always find they actually make it harder to get a grasp on the underlying basics. I end up learning not how to do a thing in C++ but rather how to use MFC/ATL to do it for me!

I would be very grateful therefore if one of you chaps know of a good tutorial on writing an OLE2 control using 'bare' C++. Have any of you perhaps even written your own control in this manner?
OLE2 can be done in C. But those who were forced to find a better way. You'll need to go back to Windows for Workgroups for sample code, that's circa '93.

I couldn't find any examples, but there are the docs. https://msdn.microsoft.com/en-us/library/aa264874(v=vs.60).aspx

I suggest you try to find MSDN articles of that era. But I also suggest it's more tricky than you can imagine.
Many thanks kbw! That is exactly the kind of material I think I will need.

Many, many ATL tutorials I read have said exactly the same thing--that it is possible to do OLE2 'by hand' as it were, but it is difficult. I am not certain on what form that difficulty takes though. I suspect some of it may be the normal kind of difficulty I am used to in writing windows programmes in bare C++--class registration, message loop, window process and message handler-- without MFC. Obviously not the same aspects, but that kind of thing. Nonetheless I have a creeping concern I am also under-estimating the task!

Continuing my search I did come across an excellent tutorial on very similar ground. The writer showed how to create an ActiveX object using only C (not C++) and function pointers set inside a typedef struct. It was very good reading and pitched at exactly the right level--easy to follow by old codgers like me! Unfortunately I cannot find it again!!! If I do I will link it here. However it was not entirely germane to C++ as I think you could use a class instead of a typedef struct so the implicit this pointer would make some of the work the writer illustrated unnecessary.

One major thing that is holding me back at the moment is all the confusion in terminology. I am not entirely certain of the difference between an 'OLE2' control and an 'ActiveX' control... Especially when an 'OCX' control is also mentioned!

Another thought I have had is--even if I manage to properly wrap my ComboBox superclass in an ActiveX control will I be able to use it in the VS dialogue editor for C++ that is not based on MFC or ATL? I suspect I will not. Which kind of undermines the entire exercise!

Update:

This seems to be an excellent tutorial that covers the start of the process at least:

https://www.codeproject.com/Articles/665/A-very-simple-COM-server-without-ATL-or-MFC
Last edited on
Hello again Lucian! Will be home in about a week and will be able to shed some light on all this fore you. At my board on Jose Roca's website is voluminous code showing how to make ActiveX Controls from scratch without MFC or ATL and also how to utilize existing ActiveX Controls in C or C++ (or PowerBASIC) code. There is a lot of complex material here.

Let me just briefly summarize the issues. ActiveX Controls were written for languages such as Visual Basic where a Visual Designer would be involved. One would drag/drop the object onto a form, size it, and set properties. There are about 10 or 12 interfaces that must be implemented/supported to provide for this.

In my case, I don't use visual designers anymore, so in the ActiveX Controls I created I eliminated this requirement. On my website I have voluminous code for creating an ActiveX Grid Control. I also have code there for utilizing the popular MSFlxGrd.ocx ActiveX Grid Control which was popular with Visual Basic users.

When I created the grid I first used PowerBASIC. It built to about 50k including all the Connection Point and self-registration code. It compacted with PX to 23k.

Later I rebuilt it with C++ using the MS C Runtime but it was about 95 k - compacting to about 50 k.

Later I wrote my own C runtime and rebuilt it with that, and came up with about 13 to 15 k depending on x86 or x64.

Gota go. Will get bacxk to you on this.

PS Custom Controls are the alternate control architecture, and are real good too.

PPS ActiveX Controls can work in any language that supports them, i.e., C, C++, PowerBASIC, Delphi, etc.
Some info here....

http://www.jose.it-berater.org/smfforum/index.php?board=431.0

Realize that ActiveX Controls generally require an 'ActiveX Control Container' in which to function. This is provided internally/transparently by languages such as Visual Basic. I believe ATL/MFC utilize Atlxx.dll (ATL71.dll, ATL80.dll, ATL90.dll, etc.). Its freely downloadable.

So, full ActiveX Control functionality usually includes capability of interacting with the design environment, e.g., it functions within the 'Toolbox'. It can run 'In Place Active'.

Further, they mostly need the 'ActiveX Control Container' I previously mentioned.

For these reasons they aren't very 'lightweight'.

However, I personally specialize in developing fully functional lightweight components.

As I said, the interactions with the design environment are in my mind optional. In my ActiveX Controls I eliminate it. That cuts the required number of interfaces that need to be implemented from about 15 down to about 4. That would be IUnknown, IConnectionPointContainer, I ConnectionPoint, and the interface unique to the control - for a grid control, for example - maybe IGrid.

In this forum I've already posted code on how to create a Web Browser App that builds to about 15 k. It would utilize the ShellExplorer OCX Control - that is, the control at the heart of Internet Explorer. However, one needs to utilize the Atlxx.dll ActiveX Control Container provided by Microsoft.

The example can be built with PowerBASIC much smaller because Jose Roca has provider source code for an ActiveX Control Container which can be built along with the target app. If you are interested in seeing the code for an ActiveX Control Container it would be part of Jose's PowerBASIC include download.

Hey Freddie! Its nice to hear from you and I hope all is going well with your cabin project! Over here around my neck of the woods in the north of England its a bit too parky to even think about camping out, but I bet its none too warm after the sun goes down in Colorado either! Mind you I've got a pal who does re-enactment and they are out in a tent at least once a month the whole year round!

OLE2/OCX/ActiveX is brand new territory for me at the moment so your info is absolute gold dust!!! Many thanks indeed. I find I can always learn a thing far easier if I can see an outline of what I need to know, even if I haven't filled in all the blanks just yet! That is why I shy away from MFC and ATL and the other class libraries--they effectively hide the interesting stuff away and at best you are only really learning how to use those libraries and not the underlying topic. Back in the 1990's when I programmed a lot more I always used to say that if I was going to use MFC I might as well just programme in VisualBasic and have done with it!

I shall definitely check out that private programming board again. There is so much excellent material to be honest I was a bit intimidated about where to start reading when I had a look the other week!
What you mentioned above and in other posts is my primary criticism of modern software development in C++. Ask any question about any technology at all and a host of well meaning repliers will point you in the direction of the three letter (some four - but mostly 3) technology you need to use to obtain that functionality. In the case of OLE/COM it happens to be ATL. In the case of visual C++ GUI development it happens to be MFC. Goes on and on, ad infinitum. Of course, there are good reasons for this, but like everything, there is no such thing as a 'free lunch', and a cost must be paid.

I'd be real happy to guide you through this stuff, but as I said before, you caught me at a particularly bad time, as I'm on a big trip, and am only occasionally at hotels/motels.

But to see what connecting to an ActiveX Control entails in C++ without using any helper libraries take a look at this for the MSFlxGrd.ocx Grid Control ...

http://www.jose.it-berater.org/smfforum/index.php?topic=4451.0

That code should work with MS Compilers or MinGW.

I'll be home by this weekend and will be able to provide you more info then. Am presently in Kentucky, USA heading for my wife's sisters farm.
My prejudice against MFC began when I realized you could not write standalone applications using it. At least not without including a massive statically linked library.

I liked swapping and sharing programmes with my best pal who is the IT director for a mobile telephone company. If I couldn't simply copy the *.EXE for him on to a 1.44 floppy I wasn't interested. It then struck me that what MS--and all other companies who provide a similar class library, such as the 'OWL' thing from Borland--were trying to do was make C++ look and behave as much like VB as possible. At that point as I said I really didn't see the point. After all, if you wanted that so badly then just use actual VisualBASIC, or better yet Delphi! Although from what we have discussed before it sounds like PowerBASIC would have been the best choice in that scenario!

Anyway, back from that tangent; I managed to rediscover the *really* well-written tutorial I found some time ago and then lost! This is it on CodeProject:

https://www.codeproject.com/Articles/13601/COM-in-plain-C#CPLUS

I think combined with the example code you have linked from the www.jose.it-berater.org web site these examples might let me get a toe-hold in the COM world and start on up from there!

Update:

This is a second nicely written article from the same place and another piece of reference I am using:

https://www.codeproject.com/Articles/338268/COM-in-C

These both overlap well. The first is the most authoritative in my opinion, but the second helps hugely in using C++ instead of C.
Last edited on
Back in a Motel again and headed home soon so I can reply.

Wasn't familiar with the CodeProject Tutorial but am very, very familiar with the Jeff Glatt Tutorial, which has been considered by all as ground breaking on that topic. In fact, I wrote a derivitive of it here in my COM Tutorial #2....

http://www.jose.it-berater.org/smfforum/index.php?board=362.0

In mine I provided both PowerBASIC and C versions of the same exact COM Object, with extensive discussion.

I'm surprised you are interested in this stuff. Not many are. I guess from my standpoint, the reason I was always interested in it, was the 'cross-language' thing. I always felt it was cool to be able to build an application out of various code building blocks where it doesn't matter if the various parts are written in different programming languages.

Where I feel my Tutorial #2 might be superior to Jeff Glatt's is that his is a special case of a COM interface/object with only one interface - IExample. What happens when there are numerous interfaces doesn't follow directly by extension when one has multiple interfaces, and the mechanics of switching/casting between the various interfaces is critical, and it took me some mental calories to figure it out. This issue is completely hidden by C++. One can only see what is going on in C. Therefore, for a full understanding of COM and its relation to C++ one must first understand it in C - in my opinion.

When I first started working on it my first efforts, which occupied many months of fooling around with it, were to attempt to 'dump' the memory contents of various blocks of memory to see how the various objects were constructed. The objects consist of several different memory allocations, with member variables and virtual function table pointers in one location, and the virtual function tables which contain pointers to the member functions in other places. Given a pointer to an object, one must understand where the virtual function table pointers to the various interfaces are located, and within the COM Object itself, how to switch among them. That Tutorial #2 explains all that.

That MSFlxGrd.ocx example I gave you a link to was an important milestone for me because at that point I felt like I understood the material. It took me several years of intense effort to get that far. I was greatly influenced by the work of Jose Roca on this stuff who I and many others consider to be something of a genius. In the very early 2000 time frame most PowerBASIC users did not know how to write fancy GUIs in PowerBASIC like could be easily produced in Visual Basic, and the reasaon for that was that Visual Basic made extensive use of these fancy ActiveX Controls such as grids and other things which weren't part of the standard Windows Controls. Jose personally detests C++ so had to figure all the low level details of this stuff out himself from the Microsoft documentation, and he had to build everything up from scratch using memory allocations and types/structs like Jeff Glatt did. Once he figured it out he made all his code freely available, and 3rd party PowerBASIC tools vendors incorporated his work into their IDEs which enabled a lot of PowerBASIC users to be able to build fancy GUIs with PowerBASIC, but without all the bloat of Visual Basic. It was kind of an ultimate solution, actually.

Well, maybe not. While the PowerBASIC code itself was small and tight, the ActiveX Controls provided by Microsoft were decidedly not. Fact is, they were pretty bloated, just like everything Microsoft touches. I recall writing a major application at work, which had previously been a major mainframe application, and I had written maybe 15,000 lines of code. It was a database type application, where a database on a server was accessed, and the data was viewed in grids throughout the application. My PowerBASIC code built to something like 500k, but the MSFlxGrd.ocx dependency was also something like 400k or 500k! That seemed out of kilter to me. At that point I wondered if I couldn't create a grid control myself that was smaller, or use something else.

The 'something else' option actually is an option. In the early 2000s when a lot of us moved from Visual Basic to PowerBASIC, we were all somewhat addicted to ActiveX Controls. But there is an alternate Windows Control architecture, and that would be 'Custom Control' architecture. At that time a PowerBASIC 3rd party vendor was selling a Grid Custom Control which was nice and it was just 50 k. I moved to that and used it for many years.

But my ultimate goal was to write my own ActiveX Grid Control using the COM/OLE architecture. This occupied my best efforts for many years. As an aside, I eventually accomplished that, and my most recent version of it I have built in x64 and it is a full featured grid control and its only something like 16k!!! But to accomplish that I had to write my own C Runtime, because, like I said, Microsoft bloats everything it touches.

But unless you have old Microsoft Visual Basic 6 Enterprise Edition installed on your system, you likely won't be able to test run that MSFlxGrd code I posted a link to. But I've posted something very similiar here couple years ago that you could run, and that would be about the same type code that utilizes the Microsoft Internet Explorer Shell.Explorer ActiveX Control. In that code I posted, if one were building with one of the old Mingw build chains, you could build a browser in about 12k or so. I'll see if I can find that link from this web site...

http://www.cplusplus.com/forum/windows/170992/

...and that's actually buildable in x86 or x64, as Microsoft provides the Shell.Explorer ActiveX Control (heart of Internet Explorer) in both x86 and x64 forms.

Last edited on
Just thought I might point out what I consider as absolute prerequisites to understanding COM/OLE at a low level, i.e., one where one understands what's going on in memory. Those prerequisites would be understanding several Registry entries, and understanding function pointers.

Understanding how to look up CLSIDs and Program IDs under HKEY_CLASSES_ROOT is the main issue. Now that we have 64 bit one needs to understand two places in the Registry where these are located.

In terms of function pointers, I've felt for some time that recent C++ coders who do not have a background in C might be weak in this area.

Lastly, in terms of my specific code examples, I tend to use a modularaization technique where I use a for loop to iterate through an array of function pointers which associate the address of an event/message handling procedure with the Windows message as received in the Window Procedure. Most folks use the switch for this. That doesn't scale well though, and many of my applications involve tens of thousands of lines of code.
Absolutely!!! I find this COM/OLE2 stuff fascinating! I think it is the very intricacy which holds my attention. I also think it is that same intricacy which leads some people to consider it 'difficult' or tricky.

I have read several times now through the first Jeff Glat example and I thought I was starting to twig what was going on. But then I hit the very pothole that you mention--the fact he only includes one 'interface'. I was also having to perform certain mental gymnastics to convert his pure C examples in to the C++ I am more familiar with. However, working through both your first COM tutorial and the valeriyabobko one I suddenly realize that what is happening from a C++ perspective is the multiple interfaces are being implemented as multiple-inheritance inside a single derived class. Therefore in order to access a specific interface in your COM object you just cast its pointer--or reference I suppose, although that is another bridge to cross on another day--via dynamic_cast<>() and the correct interface will magically appear!

However... I then read again through your example... And I realized that I was falling in to an almost identical trap analogous in a more general setting to using MFC as opposed to base C++. In the COM case it is actually bare C++ that is playing the role of the obscuring class library over the straight and more illuminative C approach.

Therefore, so far the main thread I have gathered from your example is the beginnings of an understanding--I stress so far, as I will need to read and re-read the material several times over to properly digest--of what is 'really going on'. If I am putting it together correctly then I think that COM is basically a codified system of pointers to functions and ways to allocate, share and delete the underlying data they point to.

Unfortunately, if you use even non-MFC/ATL C++ then to some extent you are losing sight of this pointer structure since the language's intrinsic multiple-inheritance and dynamic_cast<>() mechanisms take care of a lot of this behind the scenes.

Phew! That is a lot to think about and cogitate over.

I have a few specific issues with the dedicated C++ tutorial. valeriyabobko offers the following example code:

1
2
3
4
5
interface IBVAA_summer:IUnknown
{
     virtual HRESULT  __stdcall Add(const double x, const double y, double &z) = 0;   
     virtual HRESULT  __stdcall Sub(const double x, const double y, double &z) = 0;   
};


This really threw me as I had never heard of an interface reserved word. However working backwards through several layers of #define macros I think interface is actually just the struct keyword. Therefore what this really weird declaration equates to is:

1
2
3
4
5
6
class IBVAA_summer : public IUnknown
{
public:
     virtual HRESULT  __stdcall Add( const double x, const double y, double &z) = 0;   
     virtual HRESULT  __stdcall Sub( const double x, const double y, double &z) = 0;   
};


This is a clearer piece of code in my opinion than using the interface macro.

Another issue I don't understand; each of these constituent base classes is itself derived from the IUnknown class. Therefore each interface in the multiple-inherited derived class, along with the derived class itself will expect its own QueryInterface(), AddRef() and ReleaseRef() member-functions to be defined. I don't understand how this will not cause some kind of conflict.

Plus valeriyabobko constantly refes to 'C++' as 'C'. That is a pretty minor thing, but is confusing to a novice in the arena such as myself. However I don't think C has new and delete reserved words.

I am also very interested in the 'Custom Control Architecture' you mention, although I am not certain what that is! As I mentioned I have used the 'custom control' tool in the dialogue box designer tool panel. This feature allows you to specify a registered window class and position it in the editor with a plain rectangular place holder. You can then specify its styles and extended-styles as numerical Hex values. Essentially however this type of control is just a standard child window, perhaps with a superclassed window procedure that defers unhandled messages to the base control it is copied from. I would guess this is not what you are referring to?
Last edited on
It amazes me you like this stuff Lucian. Just so happens I do too.

You must be pretty smart. This is an amazing observation....


If I am putting it together correctly then I think that COM is basically a codified system of pointers to functions and ways to allocate, share and delete the underlying data they point to.


That's pretty close.

I think that 2nd tutorial of mine where I do everything in C will clear it up for you. I admit its hard. But yes, every interface (which is really a struct containing function pointers) contains as its first three members QueryInterface(), AddRef() and Release(). That's what inheritance means. Another ponderous way of putting it is that every interface is polymorphic in IUnknown. Think that one over for awhile!

Actually, in ObjBase.h (included by Windows.h) is this...

1
2
#define __STRUCT__ struct
#define interface __STRUCT__ 


So an interface is just a struct that contains function pointers. It follows from that, that it is 'stateless'. There are no member variables. A struct was used in the COM definitions because it reduces clutter.

You made another brilliant observation with regard to the analogy between Class Frameworks hiding the inner workings of the underlying APIs they are wrapping, and C++ hiding the underlying workings of COM. That is exactly the case. The actual situation is that when a C++ Class is constructed which multiply inherits from and implements pure abstract base classes each of which inherits from IUnknown, then the memory layout generated by the compiler will be COM compliant. So the compiler just glues the whole thing together for you. There's no magic to it beyond that. So its a matter of convenience. Realize though that not every C++ class is COM compliant. My 2nd tutorial will elucidate the memory layout. And clear up the confusion with multiple instances of QueryInterface(), AddRef(), and Release().

About a month ago I had an exchange at www.cprogramming.com with a member about this stuff. Perhaps check out my code in replies #12 and #13 here...

https://cboard.cprogramming.com/cplusplus-programming/174377-how-does-cplusplus-itself-work.html

When you reach the point of realizing that casts between different interfaces change the value or address of the thing being cast - you are close to 'getting it'!

I'm finally home now (back in Pennsylvania). Seems like I'vebeen gone forever!
You are very kind Freddie! I don't think I am especially smart, but I have always liked to 'know what they know' as it were and I have a genuinely evangelical passion that anyone can learn anything. Its a bit off-topic, but in my opinion nothing is actually 'hard', it is just a case of understanding the framework around the material you are trying to learn, where it fits in and more importantly why. The concept of 'emergent behaviour' applies here and also fascinates me--I have been a die-hard Trekker since the late sixties and I think emergent behaviour is a real-world example of what the Vulcans call 'IDIC'. Anyway that is a long way away from the matter at hand!

I have now gone over several times the valeriyabobko tutorial and then cross-referenced this to both your first tutorial and the Jeff Glatt material. I think I have a pretty good grasp of 'interfaces' and how to inherit from IUnkown. I am now trying to get a similar grip on the 'Class Factory' concept.

To help I have just managed to find hard-copies of 'Essential COM' by Don Box and 'Inside COM' by 'Dale Rogerson'. I am hoping these texts along with your tutorials, those from Glatt and valeriyabobko will cover this thing from all the angles I need!
Last edited on
Symetry exists between the concepts of 'emergence' and 'reduction'. Emergent phenenomen can't be 'reduced' to its constituents. For example, there is nothing one can learn about hydrogen atoms or oxygen atoms that would be useful in predicting the qualities of water. The qualities of water are emergent. The behavior can't be reduced to its constituent parts.

Likewise with human culture. At some point in the development of the physical universe life arose. Its basic constituent was the cell - not the atom. The qualities of cells are 'emergent'. The behavior of cells can't be reduced to the characteristics of atoms.

At some point here on Earth intelligent life here on Earth developed. Its basic structure is the symbol. Some might use the term 'super-organic', or perhaps 'extrasomatic'. Again, not reducible to the behavior of cells. This brought culture into being. But I digress.

I was going to recommend Dale Rogerson's book. That will help a lot. Don Box is good too. And actually, a lot of ATL books are real good too. They always devote a lot of effort to COM in the raw before getting into all the template stuff which is quite inpenetratable.
Class Factories are essentially the COM version of the 'new' operator in C++. Windows has a subsystem called SCM (Service Control Manager - pronounced SCUM), one of whose jobs is to load and create COM objects. Basically, SCM takes the CLSID from either CoCreateInstance() or CoGetClassObject(), looks up the path to the Dll that houses the COM object, loads the Dll into memory with LoadLibrary(), and creates the COM object with IClassFactory()::CreateInstance() (or something like that). Of course, this is where the Windows Registry comes into play. Are you familiar with RegEdit.exe? That's a useful app to wander around the Registry with.

My above description may allude to the fact that SCM is simply a wrapper around a host of API calls that one may be able to do oneself. Such is indeed the case. One may ignore the Registry altogether and call LoadLibrary() to load the Dll containing the COM Object, then call the exported function DllGetClassObject() to obtain a pointer to the object's Class Factory. This is known as 'Registry Free COM'. Just thought you might want to know. I discuss all this in detail in my COM Tutorial #2.

Emergence and Reduction are concepts I came across in my studies of Cultural Anthropology, with particular reference to the seminal work of one Leslie A. White - a famous American Anthropologist from the mid 1900s. His basic thesis was that human culture was an emergent phenenomen of biological evolution brought about by man's ability to crerate and attach meanings to symbols, i.e., articulate speech. Once brought into being, human culture became a seperate and distinct category of reality not reducible to physical or biological explanation. The most bizarre part about all this is that this new category of reality was no longer under the control of man. Just as one turns on the weather channel to find out what the weather is going to do (an aspect of physical reality over which we have no control), one turns on CNN to find out what 'culture' is doing. Don't get me started! :)
I have not been doing much programming for the last few days; one thing or another has been claiming my time. My apologies for not getting back here sooner!

It is interesting that you mention the concept of 'registry-less COM', because the very first thing that sparked my interest in the topic was that I had a desire to write 'shell extensions' for windows. I don't know if they even exist any more in the brave new world of the 'Metro' pseudo-mobile telephone interface, but that process seemed to based primarily around registering your class with Windows in the registry so it would be loaded and its routines (actually Interfaces, as I am now starting to recognise!) be called when the GUI needed to draw an Explorer window. Windows would then defer to the behaviour you had programmed to show a property sheet or a special icon or a context menu or whatever. However I quickly realized that shell extensions were like coming in to the movie halfway through and before I could even think about trying my hand in that area I would really need to understand OLE2/COM. Sadly I let myself be put off by the amount of stuff to learn and never took it any further until a couple of weeks ago when I decided I would get all this material hammered out once and for all! I am comfortable with editing the registry--although never really understood the various CLSID sections. It is now starting to make more sense! I instinctively always prefer to use the 'bare metal' approach, so part of me would rather employ 'Registry Free COM' in just the same way I do not like using the interfaces macro or indeed ATL itself. However I suppose at the end of the day you do need to be practical so I shall try to get used to how to SCM subsystem if only to understand where it fits in to the larger scheme of things.

My second-hand books by Don Box and Dale Rogerson came in the post today. I instantly really like the tone and the level that Rogerson's 'Inside COM' is pitched at. It reads exactly like an extension to your tutorial or the one by Jeff Glatt and I think it will help me a great deal indeed. Conversely I do not like the Don Box book at all. I find it almost totally impenetrable; dry beyond belief and neither explanatory nor engaging--rather like trying to read something on the 'CPPReference' web site!

Anyway, once I get under way again I am sure I will have a host of new questions to ask!
I really loved Don Box's 1st chapter. It put the issue regarding COM and C++ in excellent perspective. I never got into the remainder of the book much.

Rogerson's book is an excellent book IMO. If you look at any of my tutorials you'll see they are a 'take off' from it, and extend it with my somewhat personal input and observations.

Actually, the book that got me started was by Guy and Henry Eddon's "Inside DCOM'. As they state themselves, its actually a COM book. Eddon's book gets into Connection Points, which are critically important if one ventures into visual ActiveX Controls. When you get that far, let me know and I'll provide you some excellent code I've worked on which illustrates the concepts well. It was something I put a lot of effort into, as I knew the direction I wanted to go with my work required it.

Funny about 'Registry Free COM'. Next day after I mentioned that to you 'in passing' I found a critical need for that in my work. At my place of work they've just changed to 'Restricted Access' from everyone having 'administrator privilidges' on their computers, and I'm going to use that technique now to load my ActiveX Controls. Its extremely easy in PowerBASIC but not really hard in C or C++.

I'm not really very knowledgible with shell extensions. I know Jose is. All I know is that it heavily involves COM.

It is odd how things like that happen viz the 'Registry Free COM'! My more mystically inclined wife would consider it to be 'synchronicity', but she is a second-wave flower\crystal child of the nineties and I was a bit too old at the time to get back in to all that 'Woodstock' stuff when it came around again!

I shall have a look on Amazon at once for the 'Inside DCOM' title you mention. 'DCOM' is another topic I have always wanted to get to know more about, beyond its obvious links to normal COM but allowed myself to be put off by the amount of material I would have to digest beforehand. However it is exactly the arena of visual ActiveX components that has fired my determination to learn COM so it sounds like this is another must-have text. One positive thing that ATL has done is make these books which just cover bare C/C++ very reasonably priced when second-hand!

Rogerson's book is pitched at exactly the right level in my opinion and while he does deal primarily with C++ this does not entirely undermine the bare C backbones. The section I have just reached is starting to delve in to the underlying memory structure which makes a COM object possible--or rather that defines an otherwise plain C++ object as a qualified COM component at all. This reminds me very much of your first and second tutorial and I hope working from both sources will give me a clearer view.

One positive thing that ATL has done is make these books which just cover bare C/C++ very reasonably priced when second-hand!


I found that Eddon book in a used bookstore and bought it for about an
American Dollar sometime in the early 2000s.

One of the biggest issues I had to face when I was learning this material was the transition to visual COM Controls (ActiveX Controls) using low level COM without ATL. Perhaps there are others with more and better WEB searching skills than I (I'm sure there are), but try as I might I simply was unable to find anything in terms of source code, tutorials, or books that didn't use ATL or MFC. In the end, I simply had to fabricate everything myself. At that point though I had put a tremendous effort into learning COM, and I was relatively expert at using the Windows Api. So I just had to use that knowledge to somehow bridge the gap between the type of basic COM plumbing issues you are seeing discussed in Rogerson, and the way Windows GUIs work.

At the most fundamental architectural level, all GUIs use a function pointer callback mechanism to operate. When one uses RegisterClass() or RegisterClassEx() in a Windows Api program, one passes the virtual address of a Window Procedure to Windows the Operating System. The Window Procedure has a definite function signature of which Windows is aware - its specified in the Windows headers. In that manner Windows calls the Window Procedure in my or your program through that function pointer address - not through an alphanumeric label which is the more typical way to call a function.

With ActiveX Controls its somewhat different in the details, but basically the same - at least in terms of the involvement with function pointers. That's where the IConnectionPointContainer and IConnectionPoint interfaces enter the picture.

But I'm getting ahead of where you are presently at. I do have most if not all these issues discussed in detail on Jose Roca's website. When I built my ActiveX Grid Control I started in PowerBASIC with the Custom Control architecture. All that code is on Jose's website. Once I got that working I ripped out the custom control plumbing and inserted the COM plumbing to convert it to a COM based control. A big part of that was replacing or modifying what went on within the Window Procedure of the Grid Control to utilize the IConnectionPoint interface in notifying the client of user interactions within the grid.

But that's not all of it. The IClassFactory interface was necessary to create the grid. So there's a lot of details.

But it all pretty much worked out well. Unfortunately, that code I described above is all in PowerBASIC. I didn't convert things over to C++ until several years later when I decided it was time to learn 64 bit. Since PowerBASIC was only available in 32 bit, I used Microsoft's build system, which, since about Visual Studio 2005 or so, contained both 32 bit and 64 bit build chains.

I undertook all that with a great deal of trepidation. I was just learning 64 bit, and didn't know how things would go. At first, I agonized whether I wanted to use C or C++. In other words, build the VTables and other structures by hand, or let C++ do it. I finally decided to use C++ because my internal grid code required a great deal of string parsing which is pure murder in C. But over the course of many years I had developed my own String Class which I exclusively use in lieu of the C++ Standard Library's std::string or std::wstring class, and it had very good parsing functionality.

Eventually I got that all working, and all the code, comments, and thought processes involved are posted in detail in Jose's Forum.

The only downside to the C++ conversion was that the resulting binary wasn't as small as the PowerBASIC generated one. PowerBASIC generated code is pretty small. Actually, there's more to be said about that. Its really not that much different than C or C++ compiler generated code, its just that there is a great deal more C or C++ adds to the binary than PowerBASIC does. So in other words, it starts out bigger. That is the justification for some of us hard core coders to write our own C Runtime, which I've done. All that is in Jose's Forum.

Only last year I redeveloped my grid code (very little needed to be changed) to build against my own C Runtime, and using that I was able to produce both x86 and x64 versions of of my ActiveX Grid Control that are actually smaller than the PowerBASIC created grid.

These are the kinds of intellectual endeavors I've spent a significant part of my life fooling around with. It all started though after spending a significant amount of my life in philosophy, anthropology, sociology and so forth without having produced anything worthwhile besides an understanding of how the world works (that's why I understand emergence/reduction). At least now I have working code that helps folks out.


Topic archived. No new replies allowed.