Why does Microsoft have IHTMLDocument, IHTMLDocument2, ... , IHTMLDocument8? - c++

What is the meaning of the number in the end of the interface name? I see that IHTMLDocument3-7 have no members (see example for #5), and 8 has gesture related members. Is the number derived from Windows version?

This is a general feature of public COM interfaces.
If you want backward compatibility, you never want to change a published interface, because that would mean all the code people wrote for, say, IE 6 stops working with IE 7, and all of their customers get mad at them, and they get mad at you.
So, if IE 5 adds new features that needed to be exposed, instead of changing IHTMLDocument, you create a new interface, and make IE5 support both (by inheritance, QueryInterface, or some more explicit mechanism). And when IE 7.0.2 or IE 8 or Win XP or whatever adds even more new features, you create another one. And so on.
While MS could have come up with descriptive suffixes instead of just sequential numbers, that would probably be more confusing than helpful. So, IHTMLDocument2, IHTMLDocument3, etc. are the names. They don't mean anything, except the order they were added.

What is the meaning of the number in the end of the interface name?
That is the standard convention for versioning COM interfaces. IXXX2 extends IXXX with new functions. IXXX3 extends IXXX2 with new functions, and so on. This allows clients to use older functions without breaking when new versions are released, and use newer functions when desired, even check if those functions are available before trying to call them.
I see that IHTMLDocument3-7 have no members
Where did you get that idea from? Look at their actual definitions. They expose many new members from one interface to the next.

No - it just signifies a different version of the interface. It has nothing to do with Windows version (and, for that matter, little/nothing to do with MSHTML version):
http://msdn.microsoft.com/en-us/library/aa752641%28v=vs.85%29.aspx

as of http://msdn.microsoft.com/en-us/library/aa752541(v=vs.85).aspx
where we can see :
The IHTMLDocument3 interface inherits from the IDispatch
interface but does not have additional members.
it can bee little confusing for newcomers to interface world.

Related

Progressive Disclosure in C++ API

Following my reading of the article Programmers Are People Too by Ken Arnold, I have been trying to implement the idea of progressive disclosure in a minimal C++ API, to understand how it could be done at a larger scale.
Progressive disclosure refers to the idea of "splitting" an API into categories that will be disclosed to the user of an API only upon request. For example, an API can be split into two categories: a base category what is (accessible to the user by default) for methods which are often needed and easy to use and a extended category for expert level services.
I have found only one example on the web of such an implementation: the db4o library (in Java), but I do not really understand their strategy. For example, if we take a look at ObjectServer, it is declared as an interface, just like its extended class ExtObjectServer. Then an implementing ObjectServerImpl class, inheriting from both these interfaces is defined and all methods from both interfaces are implemented there.
This supposedly allows code such as:
public void test() throws IOException {
final String user = "hohohi";
final String password = "hohoho";
ObjectServer server = clientServerFixture().server();
server.grantAccess(user, password);
ObjectContainer con = openClient(user, password);
Assert.isNotNull(con);
con.close();
server.ext().revokeAccess(user); // How does this limit the scope to
// expert level methods only since it
// inherits from ObjectServer?
// ...
});
My knowledge of Java is not that good, but it seems my misunderstanding of how this work is at an higher level.
Thanks for your help!
Java and C++ are both statically typed, so what you can do with an object depends not so much on its actual dynamic type, but on the type through which you're accessing it.
In the example you've shown, you'll notice that the variable server is of type ObjectServer. This means that when going through server, you can only access ObjectServer methods. Even if the object happens to be of a type which has other methods (which is the case in your case and its ObjectServerImpl type), you have no way of directly accessing methods other than ObjectServer ones.
To access other methods, you need to get hold of the object through different type. This could be done with a cast, or with an explicit accessor such as your ext(). a.ext() returns a, but as a different type (ExtObjectServer), giving you access to different methods of a.
Your question also asks how is server.ext() limited to expert methods when ExtObjectServer extends ObjectServer. The answer is: it is not, but that is correct. It should not be limited like this. The goal is not to provide only the expert functions. If that was the case, then client code which needs to use both normal and expert functions would need to take two references to the object, just differently typed. There's no advantage to be gained from this.
The goal of progressive disclosure is to hide the expert stuff until it's explicitly requested. Once you ask for it, you've already seen the basic stuff, so why hide it from you?

what are the things to note while adding a new interface in C++ COM (ATL)

I have added a new interface IAEx which is extended from the existing interface IA (derived from IDispatch).
What are the things to change in idl?
I have changed the coclass definitions to inherit from the new one.
I changed the coclass entry in idl which was like this earlier.
(I need the deafult interface as new one)
coclass CAx
{
[default] interface IA
[default, source] dispinterface IAEvents;
};
and changed to
coclass CAx
{
[default] interface IAEx
[default, source] dispinterface IAEvents;
};
can I change the deafualt interafce?
coclass definition change.
old one
class ATL_NO_VTABLE CAx:
...
public CCIDispatchImpl<IA, &IID_IA, &LIBID_CCALib>,
new one.
class ATL_NO_VTABLE CAx:
...
public CCIDispatchImpl<IAEx, &IID_IAEx, &LIBID_CCALib>,
Is this fine?
COM MAP entries modification:
Old one:
COM_INTERFACE_ENTRY(IA)
COM_INTERFACE_ENTRY2(IDispatch,IA)
new one:
COM_INTERFACE_ENTRY(IAEx)
COM_INTERFACE_ENTRY2(IDispatch,IAEx)
Do I need to add old interface also in COM MAP?
No, this is a drastically breaking change to client programs. Golden rule #1 to keep in mind is that names are quite immaterial in COM, only uuids matter. Rule #2 is that COM components have machine scope, modifying a component affects every program on the machine that uses the component. Another way to say that is that COM has a strong DLL Hell problem.
So the first thing that will happens when you install your component on a machine is that every program that uses it will stop to work. They are still looking for the "IA" interface uuid and it is not there anymore. They fail with E_NOINTERFACE. Only way to avoid that is to get the client programs recompiled with your new type library and deploy them at the exact same time your updated COM component is deployed. This is often very hard to arrange since they don't have programmers or companies in common. Usually only the user can do this, they very rarely know how to do this correctly or know how to troubleshoot failure.
If you want your update to be backwards compatible then you must add a new interface to your coclass. It cannot be the [default] interface since existing client programs expect the legacy interface as the default. That however causes a new problem, client runtimes that use IDispatch often don't support anything but a single default interface. Usually because they don't have a notion of interfaces as a primary language construct. In other words, your client programmer has no way to call IUnknown::QueryInterface() and therefore cannot use your new interface at all. So not a general solution.
It is technically possible to violate the interfaces are immutable rule in COM. You can add new methods to the end of the IDispatch interface. Existing client code is unaware of them so will never call them and continue to operate correctly both with the old and the new version of your component. Assuming that you know how to maintain the legacy methods without causing a breaking behavior change, often harder than it looks. There is still a DLL Hell problem though, the world implodes when an updated version of the client code meets the old version of your component. This might seem unlikely at first sight but this tends to go wrong much later, when the machine is replaced or re-imaged. Very ugly scenario, the runtime failure is impossible to diagnose and anybody originally involved is not around anymore or doesn't remember the details.
Only truly safe way to do this is to create a new version. Modify all the uuids (LIBID, CLSID and IID) and change the DLL filename. Now the old and new version can co-exist and the client programmer can use your new version at his leisure. There might still be a deployment problem but the failure is easy to diagnose, the client program fails with "Class not registered".
You should include the old interface in the COM MAP as well as if a client attempts to QueryInterface for the old interface it should receive a useful result and not an error. Add COM_INTERFACE_ENTRY2(IA, IAEx).
Otherwise it looks like you have everything. We add both interfaces into the coclass entry in the IDL file but I don't thing anything really uses that. ie:
coclass Ax
{
[default] interface IAEx;
interface IA;
};
Whether it is fine or not depends on what is the goal exactly. Replacing interface is fine on its own, if you are concerned with not breaking compatibility with existing client, the most important thing is that your server still implements old interface IA. You should list the interface on the COM MAP (since you mentioned that IAEx is inherited from IA, you might need a COM_INTERFACE_ENTRY_IID macro):
COM_INTERFACE_ENTRY(IAEx)
COM_INTERFACE_ENTRY_IID(__uuidof(IA), IAEx) //COM_INTERFACE_ENTRY(IA)
COM_INTERFACE_ENTRY2(IDispatch, IAEx)
This way your server implements both IAEx and IA. Inheriting interfaces one from another is the thing I would rather suggest against, but you have what you have.
Updating coclass (as suggested in answer by patthoyts) makes update cleaner and is worth doing as well, however it is more important for rebuilding the clients rather than keeping compatibility with already existing built code: tools importing type library information will be able to see both interfaces if they at all care and are capable to handle non-default interfaces there.

Putting all code of a module behind 1 interface. Good idea or not?

I have several modules (mainly C) that need to be redesigned (using C++). Currently, the main problems are:
many parts of the application rely on the functions of the module
some parts of the application might want to overrule the behavior of the module
I was thinking about the following approach:
redesign the module so that it has a clear modern class structure (using interfaces, inheritence, STL containers, ...)
writing a global module interface class that can be used to access any functionality of the module
writing an implementation of this interface that simply maps the interface methods to the correct methods of the correct class in the interface
Other modules in the application that currently directly use the C functions of the module, should be passed [an implementation of] this interface. That way, if the application wants to alter the behavior of one of the functions of the module, it simply inherits from this default implementation and overrules any function that it wants.
An example:
Suppose I completely redesign my module so that I have classes like: Book, Page, Cover, Author, ... All these classes have lots of different methods.
I make a global interface, called ILibraryAccessor, with lots of pure virtual methods
I make a default implementation, called DefaultLibraryAccessor, than simply forwards all methods to the correct method of the correct class, e.g.
DefaultLibraryAccessor::printBook(book) calls book->print()
DefaultLibraryAccessor::getPage(book,10) calls book->getPage(10)
DefaultLibraryAccessor::printPage(page) calls page->print()
Suppose my application has 3 kinds of windows
The first one allows all functionality and as an application I want to allow that
The second one also allows all functionality (internally), but from the application I want to prevent printing separate pages
The third one also allows all functionality (internally), but from the application I want to prevent printing certain kinds of books
When constructing the window, the application passes an implementation of ILibraryAccessor to the window
The first window will get the DefaultLibraryAccessor, allowing everything
I will pass a special MyLibraryAccessor to the second window, and in MyLibraryAccessor, I will overrule the printPage method and let it fail
I will pass a special AnotherLibraryAccessor to the third window, and in AnotherLibraryAccessor, I will overrule the printBook method and check the type of book before I will call book->print().
The advantage of this approach is that, as shown in the example, an application can overrule any method it wants to overrule. The disadvantage is that I get a rather big interface, and the class-structure is completely lost for all modules that wants to access this other module.
Good idea or not?
You could represent the class structure with nested interfaces. E.g. instead of DefaultLibraryAccessor::printBook(book), have DefaultLibraryAccessor::Book::print(book). Otherwise it looks like a good design to me.
Maybe look at the design pattern called "Facade". Use one facade per module. Your approach seems good.
ILibraryAccessor sounds like a known anti-pattern, the "god class".
Your individual windows are probably better off inheriting and overriding at Book/Page/Cover/Author level.
The only thing I'd worry about is a loss of granularity, partly addressed by suszterpatt previously. Your implementations might end up being rather heavyweight and inflexible. If you're sure that you can predict the future use of the module at this point then the design is probably ok.
It occurs to me that you might want to keep the interface fine-grained, but find some way of injecting this kind of display-specific behaviour rather than trying to incorporate it at top level.
If you have n number of methods in your interface class, And there are m number of behaviors per each method, you get m*(nC1 + nC2 + nC3 + ... + nCn) Implementations of your interface (I hope I got my math right :) ). Compare this with the m*n implementations you need if you were to have a single interface per function. And this method has added flexibility which is more important. So, no - I don't think a single interface would do. But you don't have to be extreme about it.
EDIT: I am sure the math is wrong. :(

what if i keep my class members are public?

In c++ instance variables are private by default,in Python variables are public by default
i have two questions regarding the same:-
1: why Python have all the members are public by default?
2: People say you should your member data should be private
what if i make my data to be public?
what are the disadvantages of this approch?
why it is a bad design?
You can use a leading underscore in the name to tell readers of the code that the name in question is an internal detail and they must not rely on it remaining in future versions. Such a convention is really all you need -- why weigh the language down with an enforcement mechanism?
Data, just like methods, should be public (named without a leading underscore) if they're part of your class's designed API which you intend to support going forward. In C++, or Java, that's unlikely to happen because if you want to change the data member into an accessor method, you're out of luck -- you'll have to break your API and every single client of the class will have to change.
In Python, and other languages supporting a property-like construct, that's not the case -- you can always replace a data member with a property which calls accessor methods transparently, the API does not change, nor does client code. So, in Python and other languages with property-like constructs (I believe .NET languages are like that, at source-code level though not necessarily at bytecode level), you may as well leave your data public when it's part of the API and no accessors are currently needed (you can always add accessor methods to later implementation releases if need be, and not break the API).
So it's not really a general OO issue, it's language specific: does a given language support a property-like construct. Python does.
I can't comment on Python, but in C++, structs provide public access by default.
The primary reason you want a private part of your class is that, without one, it is impossible to guarantee your invariants are satisfied. If you have a string class, for instance, that is supposed to keep track of the length of the string, you need to be able to track insertions. But if the underlying char* member is public, you can't do that. Anybody can just come along and tack something onto the end, or overwrite your null terminator, or call delete[] on it, or whatever. When you call your length() member, you just have to hope for the best.
It's really a question of language design philosophies. I favour the Python camp so might come down a little heavy handedly on the C++ style but the bottom line is that in C++ it's possible to forcibly prevent users of your class from accessing certain internal parts.
In Python, it's a matter of convention and stating that it's internal. Some applications might want to access the internal member for non-malignant purposes (eg. documentation generators). Some users who know what they're doing might want to do the same. People who want to shoot themselves in the foot twiddling with the internal details are not protected from suicide.
Like Dennis said "Anybody can just come along and tack something onto the end, or overwrite your null terminator". Python treats the user like an adult and expects her to take care of herself. C++ protects the user as one would a child.
This is why.

How to create a VB6 collection object with ATL

or a VB6 - compatible - collection object.
We provide hooks into our .net products through a set of API's.
We need to continue to support customers that call our API's from VB6, so we need to continue supporting VB6 collection objects (simple with VBA.Collection in .net).
The problem is supporting some sites that use VBScript to call our API's. VBScript has no concept of a collection object, so to create a collection object to pass to our API we built a VB6 ActiveX DLL that provides a "CreateCollection" method. This method simply creates and passes back a new collection object. Problem solved.
After many years of pruning, porting and re-building, this DLL is the only VB6 code we have. Because of it we still need to install Visual Studio 6 on our Dev & build Machines.
I'm not happy with our reliance on this DLL for several reasons (my personal dislike of VB6 is not one of them). Top of the list is that Microsoft no longer support Visual Studio 6.
My question is, how do I get ATL to create a collection object that implements the same interface as the VB6 collection object.
I've a good handle on C++, but only a loose grasp of ATL - I can create simple objects and implement simple methods, but this is beyond me.
Collections are more or less based on convention. They implement IDispatch and expose some standard methods and properties:
Add() - optional
Remove() - optional
Item()
Count - read-only
_NewEnum - hidden, read-only, returns pointer to enumerator object that implements IEnumVariant
The _NewEnum property is what allows Visual Basic For Each.
In the IDL you use a dual interface and:
DISPID_VALUE for Item()
[propget, id(DISPID_NEWENUM), restricted] HRESULT _NewEnum([out, retval] IUnknown** pVal)
Here are some MSDN entries: Design Considerations for ActiveX Objects
And here is some ATL specific convenience: ATL Collections and Enumerators
Lets target this VBScript snippet
Dim vElem
For Each vElem In MyObject
...
Next
particularly the implementation of MyObject. As a minimum you have to implement a method/propget with DISPID_NEWENUM on the default dispinterface (its dual/dispinterface to talk about DISPIDs). You can name it whatever you want, it doesn't matter. Most collections use NewEnum, and flag it in IDL as hidden. VB6 uses underscore prefix to mark hidden methods so you might see _NewEnum as recommendation but it's kind of a cargo cult ATL does.
You don't need any Count, Item, Add, Remove, Clear or any other method at all (on the default interface). You can supply these as a convenience (particulatly Item accessor and probably Count) but you don't have to, to make the sample code above work.
Next, the retval has to be a separate object (so called enumerator) which implements IEnumVARIANT interface by using a (private) pointer to MyObject. In IDL you can declare retval as IUnknown nothing wrong here. What is most interesting is that you have to implement only the Next method on IEnumVARIANT, you can return E_NOTIMPLEMENTED on the rest if you like or optionally implement them though these are never called by For Each. What makes the implementation even easier is that celt parameter of Next (the number of items requested) is always 1, so For Each requests items always one by one.
What you can use in ATL is CComEnumOnSTL and the like to create a "proxy" enumerator on an STL container, or the array based enumerator ATL provides (and exclude STL).
For a good example of how to implement COM collections that would be used naturally in script programming languages, check out my website
It offers a comprehensive example of how to do that...