COM, DirectShow and DelphiMost of the explanations of COM have me totally confused before I reach the end of the first page so, here, I'll restrict things to what we need to know about COM as it relates to DirectShow and this tutorial.
What is COM?Put simply, the Component Object Model defines a way to write software modules - called Objects (such as applications and DLLs) - in a standard way so that they are able to communicate with one another through "gateways" known as interfaces. As in other modes of communication, one Object will act as a client and one will act as the server and it is the server that implements the interfaces. A simple server Object may have only one interface; more complicated Objects may have several. Generally, an application will be a client and a DLL will be the server. DirectShow Filters are, in reality, DLLs with the file extension - .ax
QueryInterfaceLuckily, we don't need to know how to write COM Object servers - suffice it for us to know that whoever does write them needs to provide a mechanism (or method) for our application to "open" - or expose - an interface in order to be able to communicate with it. For this purpose all server Objects must have a QueryInterface method.
Suppose we had a DirectShow Filter, called VideoTransform which could perform certain operations on a video stream depending on configuration data which we present to it via various interfaces. These interfaces might be called IBrightness, IContrast, IRotate and so on. We can query VideoTransform using its QueryInterface method in order to expose one of the interfaces.
QueryInterface will return to us a pointer to the requested interface so we need to declare a variable to hold the returned value before we call the QueryInterface method.
procedure TForm1.TrackBar1Change(Sender: TObject); var MyContrast: IContrast; begin : VideoTransform.QueryInterface(IContrast, MyContrast); MyContrast.Green:= TrackBar1.Position; :
In this hypothetical example, MyContrast is declared as type IContrast and is then passed (undefined) to the VideoTransform.QueryInterface method along with which interface we are interested in. Remember that VideoTransform has several interfaces so we need to specify which one - IContrast in this case.
If the query is successful, VideoTransform.QueryInterface will return a pointer to its IContrast interface in MyContrast. Exactly how you would subsequently use the pointer in the application depends, of course, on how the Contrast routine itself is implemented within VideoTransform. Here, I've just shown one simple possible use with a TTrackBar.
Why "If the query is successful?" There are several reasons why the query may fail to return a value in our pointer variable. It may be that VideoTransform doesn't have the particular interface we've queried. Or, more likely, we may need to configure VideoTransform in some way before the interface becomes available. So how can we test whether or not the query was successful?
In addition to returning our pointer value, QueryInterface will also return a value indicating success or failure which can be tested as follows:
procedure TForm1.TrackBar1Change(Sender: TObject); var MyContrast: IContrast; begin : if Succeeded( VideoTransform.QueryInterface(IContrast, MyContrast) ) then begin //process 'MyContrast' here.. end else ShowMessage('QueryInterface failed!');
OK, for the purposes of this turorial, that's all we need to know about COM!. In fact, users of Delphi 6 and Delphi 7 need not even concern themselves with any of the above because these versions of Delphi and DSPack can make use of the Delphi as operator to make the process 'transparent' and perform the QueryInterface behind the scenes. Delphi 5 users will, however, need to use this technique (as will be explained in the tutorial).