Fog Creek Software
g
Discussion Board




Good, thorough article on COM?

I'd like to finally understand how COM works. Between the various xID's (GUID, CLSID, IID, VersionIndepent- and -dependent ProgID), interfaces, versioning, etc., there's still too much I don't know. I do have the door-stop "OLE2", but it's just too hard to read.

Anybody knows of a good article that summed up what the average VB developer should know about COM, whether it's just to use OCX controls in their project, or build some in VB?

FredF
Monday, February 2, 2004

I used to develop a com with atl with the book <atl internals>.

atl is terrible.

redguard
Monday, February 2, 2004

COM has been superceded by .NET


Monday, February 2, 2004

There's an article on MSDN called "Dr.GUI's Gentle Guide to COM" and its an 8 part series to learning COM. I found it very interesting. Search google for "Dr.GUI's Gentle Guide to COM" or "So you wanna do COM. Hasn't it been done already?"

Then, there's Rob Thayer's Visual Basic 6 Unleashed that starts straight with COM and tells you how you can create ActiveX OCXs and DLLs.

That's all I can remember but I am sure I am missing out some really wonderful links I've been through on COM. When I recall, I'll post them.

Sathyaish Chakravarthy
Monday, February 2, 2004

Here's another article on COM that is good. Its not comprehensive but its a good start.

http://www.vbexplorer.com/VBExplorer/wrox/vbcomsamp.asp


There are Karl Moore articles on DevX.com but they're very frivolous and I don't think you want to waste your time reading his wisecracks, and rehash chip stuff from that waffle. But if you do need a very very basic tutorial on COM, then devX.com (erstwhile vbworld.com, you can just type vbworld.com and the browser will take you there) is where you must go and search "Karl Moore COM".

Sathyaish Chakravarthy
Monday, February 2, 2004

Thx everyone :-) For those interested, Dr Gui's series of articles on COM is available here:

http://www.microsoft.com/com/news/drgui.asp

Since we're on the subject, if there's some VB developer out there who could tell me why an EXE of mine in which a form contains the MS Winsock object includes the string "MSWinsockLib.Winsock" while, according to the Registry, the actual ProgID for this component is "MSWinsock.Winsock", I'm interested :-) Using CreateOject() with the former fails, while using the latter works OK. So... what's a girl to do?

I was thinking of writing a routine in Main() that would parse through the EXE/OCX itself, to search for all occurences of *.OCX and their ProgID that follows, hence the need to map an OCX filename to a ProgID.

FredF
Monday, February 2, 2004

If you are really serious you should get hold of Don Box's book, it is an excellent introduction. Following that get ATL Internals, using ATL makes the whole thing a lot easier but you should start with the basics.

COM is complex, don't expect to pick it up just by reading a short article on the web.

Tony Edgecombe
Monday, February 2, 2004

Thx Tony. I assume you mean "Essential COM"?

http://www.amazon.com/exec/obidos/tg/detail/-/0201634465/

It looks like it was written for C++ developers, while we use VB, but I'll add it to the list :-)

FredF
Monday, February 2, 2004

The actual ProgID for the Winsock control is MSWinsock.Winsock and that is also the version independant Prog ID as you see in the registry. However, the OCA file contains type library information which defines an alias for the library as MSWinsockLib. This is however, not the actual library name. A call to CreateObject or LoadLibrary on MSWinsockLib.Winsock will fail.

Sathyaish Chakravarthy
Monday, February 2, 2004

All the "bibles" are already in the thread. I read most of them but as a VB developer the one I liked most was:

COM and .NET Interoperability
by Andrew Troelsen

And you get a good .NET book too!

BD
Monday, February 2, 2004

Also watch "COM and The City"

<g>


Monday, February 2, 2004

I recommend "What OLE Is Really About" by Kraig Brockschmidt: http://msdn.microsoft.com/library/en-us/dnolegen/html/msdn_aboutole.asp

John Topley (www.johntopley.com)
Monday, February 2, 2004

I don't think Box's book is very good. He seems like a smart guy, but he's a terrible writter.

Jorel on Software
Monday, February 2, 2004

I agree with the misspelt Jorel on Software. And to go a bit off topic, I think the same of Dan Appleman too.

Sathyaish Chakravarthy
Monday, February 2, 2004

Thx again :-) BTW, I wanted to order Dan Appleman's book on writing ActiveX controls in VB6, but it's out of print.

As far as the MSWinsockLib/MSWinsock ProgID issue is concerned... is there a way to forbid VB from inserting the alias in the binary output, and use the standard ProgID instead? This way, I can build a hash table OCX => ProgID, and write a small check in Main() to make sure all the OCX's are alive and well.

FredF
Monday, February 2, 2004

You can use late binding if you don't want that alias to be used. However, I do not understand this requirement of yours.

"This way, I can build a hash table OCX => ProgID, and write a small check in Main() to make sure all the OCX's are alive and well."

Sathyaish Chakravarthy
Monday, February 2, 2004

FredF,

I wouldn't recommend "Essential COM" by Don Box simply because it is geared toward C++ programmers and most people don't consider this book to be an easy read.

If you don't have a Half Price bookstore in your area, then your best bet is to purchase a VB COM related book via an online bookstore. I doubt you will find a VB COM related book in your local brick and mortar bookstore simply because most of these type of books were published several years ago and don't sell anymore.

I believe Wrox published a book titled "COM for the Visual Basic Programmer". I never read this particular book so I don't know if it is good or not. Check Amazon.com or do a Google search for reviews of this book and several others.

One Programmer's Opinion
Monday, February 2, 2004

For articles, I think the Dr GUI series mentioned above is very good.

For VB-specific books on COM, Daniel Appleman's "Developing COM/ActiveX Components with Visual Basic 6.0" is good, and is still available directly from the author at: http://www.desaware.com/ActiveXGuidetothePerplexedL2.htm
Some people don't like Appleman's writing style or explanations, but I learned a lot from a couple of his books including this one (although it's been several years since I read it).

For an introductory book on COM (not specific to any programming language), try "Understanding Activex and Ole" by David Chappell:
http://www.amazon.com/exec/obidos/ASIN/1572312165
This book is older (1996), but does a much better job of explaining the concepts of COM than Don Box's book.

And, of course, there is always "Mr. Bunny's Guide to Activex":
http://www.amazon.com/exec/obidos/ASIN/0201485362

Philip Dickerson
Monday, February 2, 2004

One Programmer's Opinion >> I guess you mean "VB COM: Visual Basic 6 Programmer's Introduction to COM" by Thomas Lewis
http://www.amazon.com/exec/obidos/tg/detail/-/B00008K3NV/

Sathyaish Chakravarthy >> You can use late binding if you don't want that alias to be used. However, I do not understand this requirement of yours

I want to add some checking in Main() to check that all the ActiveX controls my application uses are available, and download them and install them if not. Since it appears that both the OCX and ProgID are listed in the EXE (compile a VB program, open the EXE in a binary editor, and search for ".OCX"), I wanted to avoid hard-coding the list of controls, and just fill a collection by either calling an API that would return those infos, or use eg. a regex to parse through the EXE and extract this stuff.

FredF
Monday, February 2, 2004

Although you might be tempted to dismiss it as cheesey certification book, James Foxall's MCSD in a Nutshell ( http://www.amazon.com/exec/obidos/tg/detail/-/1565927524/qid=1075745060/sr=1-1/ref=sr_1_1/103-4226150-8611037?v=glance&s=books ) is a very good book.

It has ~150 pages on ActiveX Components and ActiveX Controls.  It also has 40 pages on the other VB COM topic - ActiveX Documents - which might come in handy if you run out of toilet paper.

The book is very thorough and is priced at about $20.

anon
Monday, February 2, 2004

If I understand correctly, you are trying to have an EXE read its own dependencies. I *think* there are Portable Executable (PE) File format API in the imghlp32.dll, if I recall correctly. Check the MSDN for this library.

Also, I remember Steve Roman, in his book Win32 API with Visual Basic (O'rielly publication) devotes a chapter to parsing the PE format. He also doles out a PE scanner (like Depends) that gives you not only the export and import table but also component info like the OCXs used.

Sathyaish Chakravarthy
Monday, February 2, 2004

"I want to add some checking in Main() to check that all the ActiveX controls my application uses are available, and download them and install them if not. Since it appears that both the OCX and ProgID are listed in the EXE [...]"

I believe the OCX will only be listed inside the EXE if you have used early binding, and in that case the EXE will fail to start (before the Main sub is reached) if the OCX is not available (or not registered) on the system. You can use late binding to avoid this particular problem, but then you will need a hard-coded list of controls to search for in your Main() procedure (plus you lose the advantages of early binding).

To ensure that all the controls that your EXE uses are available on a system (at least initially) you should use an install program to install the EXE plus all the required controls, DLLs, runtimes, etc. Even the Package and Deployment Wizard that's included with VB will suffice for an EXE with simple usage of other controls - but for most cases it's better to use either a commercial install package or one of the free installers.

To protect against the case where everything was initially installed correctly, but an OCX has been removed (or replaced with an imcompatible version) at some later time, there are a few techniques you could use - such as having 2 EXE's, one which checks for the existence of all the required controls (without using early binding) and then either displays an error message (or starts a download/install of the missing controls) if there's a problem, or launches the real EXE if everything is correct.

I saw a web site several weeks ago that had an article on a technique in VB to check whether all the required controls were installed while the EXE was starting, but I can't remember now where I saw it.

Philip Dickerson
Monday, February 2, 2004

"COM has been superceded by .NET "

Hardly.

Much of .NET is largely a thin veener layered on top of COM. And it will remain such for several more years until we have 100% managed code. Obviously, that will take some time.

Understanding COM will stay pay dividends, even if you are working with .NET.

I thought the book by Don Box was a pretty good read.

Mark Hoffman
Monday, February 2, 2004

Thx Sathyaish for the tips on PE resources.

Philip Dickerson >> I believe the OCX will only be listed inside the EXE if you have used early binding, and in that case the EXE will fail to start (before the Main sub is reached) if the OCX is not available (or not registered) on the system

Thx Philip for the idea. Actually, we do use early-biding in our forms, but an error will occur only when you try to load a form, ie. checking for dependencies in Main() is the way to go.

Try this: Build a basic VB app with just one form, add a dummy ActiveX control in the form, add a module, add Public Sub Main(), set the project to start with Main(), move or delete the dummy OCX, and start the app: You'll see that it starts fine with Main(), and fails with Err 429 when you hit Form1.Show . So, checking for dependencies in Main() is fine... provided the user has at least the VB runtime up and running, obviously :-)

I'm only using late-biding (ie. calls to CreateObject) in Main() to check for dependencies using :

'--------------------
Sub Main()
    On Error GoTo ErrHandler

    Dim myCol As New Collection
    Dim MyObject As Variant
    Dim myObj As Object
   
    myCol.Add "MSComctlLib.TabStrip"
   
    For Each MyObject In myCol
        Set myObj = CreateObject(MyObject)
        Set myObj = Nothing
    Next
   
    Form1.Show
    Exit Sub

ErrHandler:
    MsgBox Err.Description & " " & MyObject, vbCritical, "Erreur " & Err.Number
    Select Case Err.Number
        Case 429: 'Component not registered, or wrong ProgID/CLSID?
    End Select
End Sub
'--------------------

>> You can use late binding to avoid this particular problem, but then you will need a hard-coded list of controls to search for in your Main() procedure (plus you lose the advantages of early binding)

... which is precisely why I asked if someone knew of a good way to extract the list of OCX and ProgID that I see in the EXE, so as to avoid hard-coding this list in Main() :-)

>> To ensure that all the controls that your EXE uses are available on a system (at least initially) you should use an install program

I do, using an installer written in NSIS, but I can't stop users from installing other applications which occasionnaly replaces one of the OCX's that I need with an older version. That's the issue I'm trying to solve.

FredF
Monday, February 2, 2004

I liked Wrox Press's book Beginning ATL COM book by Richard Grimes and others.  Lots of work-through examples, including DCOM.

David Hurst
Monday, February 2, 2004

If you're coming from VB, probably Ted Pattison's articles are the best, do a search on msdn - "Understanding interface based programming" is one for example. He also has a MS Press book, the 2nd edition of which is on COM+, but covers the basics as well.

Although there's lots of good C++ COM books like Box's, you may them confusing, although "Inside COM" is a fairly simple introductory book. VB takes care of a lot of the details for you, but there are several things you have to watch out for.

Pietro
Monday, February 2, 2004

Thx Pietro :-) For those interested, here's a list of articles by Ted on MSDN:

http://msdn.microsoft.com/msdnmag/find/default.aspx?type=Au&phrase=Ted%20Pattison

FredF
Monday, February 2, 2004

I really enjoyed Dale Rogerson's "Inside COM", having been defeated by Don Box's book (although the first chapter was good). It uses C++, but nothing too esoteric, and I would have thought is worth reading by the VB programmer.

as
Monday, February 2, 2004

FredF,

Now I understand more of what you are trying to do, after your detailed explanation a few entries before this one.

With the new information, I still believe that you will need a hard-coded list (plus different handling for each control) inside your Main() procedure, rather than scanning the EXE file for the controls. For example, sometimes a TypeLib is referenced as the registered component instead of an OCX; sometimes the first part of the ProgID name doesn't match the control name or the OCX file name; etc. For example, the control ComCtl3.CoolBar is in comct332.ocx; the TreeView control in mscomctl.ocx can not be created as "MSComctlLib.TreeView", but must be created as "MSComctlLib.TreeCtrl". Also, note that being able to do a CreateObject for the control successfully does not guarantee that the correct version of the control is installed - your code may be using a feature in the control that only exists in a later version of the component than the one installed on the target system, but the ProgID is the same for both versions. (Although, it is possible to obtain the OCX file version number using the Windows API and check that it's the version that you need or later.)

In addition, if you really want to download a control if it's missing, you are likely to need special case handling for different components - downloading/installing COMCTL32 is different than MSCOMCTL, for example, and downloading components such as ADO is different from both of those. If your Main() code determines that a control is missing, you may want to only display a message informing the user of the missing control and suggesting that they re-install your application to correct the problem.

For a slightly different approach for checking that the controls are installed, you could try simply registering each control that you need in your Main() subroutine each time the application starts, using the DllRegisterServer method that each COM component must have, and catching any errors raised by the DllRegisterServer method. For example:

Private Declare Function RegisterMSCOMCTL Lib "MSCOMCTL.OCX" Alias "DllRegisterServer" () As Long
Private Const ERROR_SUCCESS = 0&
Dim lngRetCode As Long
On Error Resume Next
lngRetCode = RegisterMSCOMCTL()
If Err.Number <> 0 Then
' most likely cause is OCX file not found - display error message
ElseIf lngRetCode <> ERROR_SUCCESS Then
' found the file, but the register call failed - display error
End If

Philip Dickerson
Monday, February 2, 2004

Thx Philip for the ideas :-) I need to read more on COM, because I'm still a bit unclear about things like what a Type Library is, why the references in a VB EXE differs (eg. MSWINSCKLIB. vs. MSWINSCK.), etc.

As for the version issue, I was aware of this, but there doesn't seem to be a way to extract this info from the EXE either.

Also, as you pointed out, some updates can be tricky. Incidently, that's why we replaced COMCTL32 and COMCTL232 with their more modern, and less painful MSCOMCTL and MSCOMCTL2.

I guess I'll just download a light, over-the-web installer in our application directory, and if I detect any component-related problem using your excellent idea of DllRegisterServer(), I can just launch this installer, which will check that an Internet connection is up, and rerun the install from there.

Considering that VB launched a huge industry of components, it's funny that it didn't provide a way to ensure and deploy those dependencies past the original install.

BTW, someone pointed me to some code that could be useful:

http://reliableanswers.com/vb/samples.asp
(mra_startup)

Thx again :-)

FredF
Monday, February 2, 2004

*  Recent Topics

*  Fog Creek Home