Source Code |
1 | VB 5 Custom Controls |   |
  |
Transparent AVI Control |
|
Play any AVI file using the API directly; also demonstrates how to implement transparency |
NOTE:
this code has been superceded by the version at the new site.
|
Overview
The Animation control supplied with VB (and from various other VB websites) is derived from the
implementation within COMCTL32.DLL. However, this implementation only allows you to play
AVIs with no audio stream. Also, its idea of transparency isn't quite what you might expect:
setting an AVI to transparent only sets one of the colours in the AVI to another colour,
rather than allowing you to draw part of the background.
If you want to play any type of AVI, or you want to modify the contents of the transparent
area, you must load and draw the AVI yourself using the API. Luckily, this API is easily
accessible to VB coders.
The Transparent AVI Control The API for Playing AVIs The DrawDib API The AVI Support API
The transparent AVI control supplied with the download is a simple implementation based around
reuse of a class, cAVICtrl.cls. This class allows you to play an AVI onto any
window. The implementation includes code to tile a bitmap into the background of the control.
Use of the control is pretty self explanatory. To set up the control to show an AVI transparently
over a background bitmap the code looks like this:
With vbalAVIPlayer1
.Filename = App.Path & "\clock.avi"
.Load
.Picture = picBackground.Picture
.Transparent = True
.TransparentColor = &H0&
End With
To start and stop the AVI playing, use the .Running property.
Basically the API for playing AVIs is found in two DLLs: the AVI support DLL
Avifil32.Dll and the Video for Windows DLL msvfw32.dll (incidentally,
to find out more about working out which DLL contains which function, have a look
at the article Sleuthing the Location of an API call).
AVI loading, reading and interrogation is provided by the AVI support DLL, whilst Video
for Windows provides some functions for rendering a DIB
directly from memory onto a device context, without having to create an intermediate
GDI DIB Section or memory device context to Blit it from.
The DrawDib API is aimed at fast rendering of DIBs (Device Independent Bitmaps) to
screen without the intermediate use of any GDI objects. This was important in 16 bit
versions of windows, however, most graphic card device drivers now deal with DIBs very quickly
so the performance aspect of this API is no longer relevant. It does help simplify
drawing AVI frames, however, so it is used in this project. There are three DrawDib API
calls used:
Opens a DrawDib device and returns a handle to it.
AVIs work is performed using this DLL. To start using the DLL, call AVIFileInit()
and when finished, call AVIFileExit.
To open an AVI file for playing, the AVIStreamOpenFromFile function is used:
Private Declare Function AVIStreamOpenFromFile Lib "avifil32.dll" Alias "AVIStreamOpenFromFileA" ( _
ppavi As Any, ByVal szFile As String, _
ByVal fccType As Long, ByVal lParam As Long, _
ByVal mode As Long, pclsidHandler As Any _
) As Long
The return value from the function is a COM HRESULT.
Tip Using COM HRESULT values
Whilst a HRESULT sounds like it should be a handle to a result, it is actually just
a long value where the bits are arranged in a specific sequence:
Format of the HRESULT
The most significant bit of the HRESULT (bit 31, which can be extracted by ANDing with &H80000000)
determines whether the function call succeeded or failed. It is set for failure.
The bits betwen bit 30 and bit 16 contain what is termed the 'facility' code. Microsoft use this
to separate different errors out, for example, control errors are supposed to
set FACILITY_CONTROL (=10) in this section whilst Win32 errors set FACILITY_WINDOWS (=7).
The low order word is the return code which specifies the code for the success or failure
condition.
Since HRESULTs can be either success or failure codes, it is not enough just to check
whether the return value is zero or positive. C and C++ coders take advantage of the Macros
FAILED and SUCCEEDED which are defined in one of the COM header files; but these are simple
to rewrite in VB:
Private Function FAILED(ByVal hr As Long) As Boolean
FAILED = Not (SUCCEEDED(hr))
End Function
Private Function SUCCEEDED(ByVal hr As Long) As Boolean
SUCCEEDED = ((hr And &H80000000) = 0)
End Function
If AVIStreamOpenFromFile succeeds, then the long variable passed into the ppAVI parameter
is a pointer to the AVI stream. We can then open the AVI for playing and find out
more about the AVI.
To open the stream for playing, we call:
Private Declare Function AVIStreamGetFrameOpen Lib "avifil32.dll" ( _
pavi As Any, lpbiWanted As Any _
) As Long
If this function succeeds it returns a long pointer to the GetFrame interface (pGF),
otherwise it returns 0.
Once both the pavi and pGF pointers have been returned, the AVI can then be queried for information about its size, shape and so forth.
All AVIs are encoded as a series of "samples" (i.e. frames)
which have a particular duration. This function returns the time in milliseconds
for a given sample in the AVI:
Private Declare Function AVIStreamSampleToTime Lib "avifil32.dll" _
(pavi As Any, ByVal lSample As Long) As Long
The AVIStreamLength function returns the number of samples in the AVI, which in turn directly indicates the duration of the AVI if passed into the AVIStreamSampleToTime function:
Private Declare Function AVIStreamLength Lib "avifil32.dll" (pavi As Any) As Long
To find the position of the first sample in the AVI (which again can be converted into a time using AVIStreamSampleToTime)
we use AVIStreamStart:
Private Declare Function AVIStreamStart Lib "avifil32.dll" (pavi As Any) As Long
To get more general information about the AVI, such as size, name, samples per second to
play and so forth, the AVIStreamInfo function fills in a TAVISTREAMINFO structure
for a given AVI stream pointer. The declare of the function looks like this:
Private Declare Sub AVIStreamInfo Lib "avifil32.dll" Alias "AVIStreamInfoA" _
(pavi As Any, psi As TAVISTREAMINFO, ByVal lSize As Long)
Private Type TAVISTREAMINFO ' this is the ANSI version
fccType As Long
fccHandler As Long
dwFlags As Long '/* Contains AVITF_* flags */
dwCaps As Long
wPriority As Integer
wLanguage As Integer
dwScale As Long
dwRate As Long ' /* dwRate / dwScale == samples/second */
dwStart As Long
dwLength As Long '; /* In units above... */
dwInitialFrames As Long
dwSuggestedBufferSize As Long
dwQuality As Long
dwSampleSize As Long
rcFrame As RECT
dwEditCount As Long
dwFormatChangeCount As Long
szName(0 To 63) As Byte
End Type
Back to top
Back to ActiveX Control Source Code
Back to Source Code
NOTE:
this code has been superceded by the version at the new site.
|
About Contribute Send Feedback Privacy
|