AVI Player – ATL DLL

The AVI Player may be called by applications during lengthy operations (database operations, etc.). The DLL provides the caller with a couple of standard AVI files, that is these AVI files are residing in the DLL resource. Additional you may also play an AVI out of the callers resource.


The DLL displays a modeless dialog box consisting of the animation window, and optional a static control (for displaying additional text) and a progressbar. The progressbar is controled by a logarithmic function.
L = 100-100*exp(-c*t), where c=log(0.5)/(-H), with L…Progress, t…Timedifference to starting time and H…Halflife (time to pass until 50% of progress a reached).


To play an AVI is actual not a serious problem (you may use the Animate_Create(), Animate_Open() respectively Animate_Play() macros), the challenge was the progressbar. My first attempt was to establish a timer and process the progressbar within the timer callback. This did not work in cases of intensive background operations (like database operations), because the SendMessage() was not processed. I tried to increase the process-priority in vain. The trick is, that I had to create the progressbar in the same thread where the window message are processed.
I don’t want to bore anybody by details, therefore I only present some snippets. If you are interested in more details, please download the sources, I tryed to comment them extensively. And please, be tolerant, I am not a real guru.


// Somewhere in the PlayEx(...) Routine I create the thread with a pointer of my class as user datas.
m_pDlg = new CXAviPlay((HINSTANCE)hInstance, ResID, Repeat, Width,
Height, nTextRows, Progress, HalfLife, (HWND)hWnd);
m_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadCallback, (LPVOID)this, 0, &ThreadID);

// thread callback. processes all the dialog stuff.
DWORD WINAPI ThreadCallback(CXAviPlayer* pthis)
{ while (1)
{
//...
WaitWithMessageLoop(NULL); // better than sleeping, at least in this routine.
}
return 1L;
}

First I had a Sleep() statement in my thread callback, but then no further messages are processed, therefore I used MsgWaitForMulitpleObjects() instead. (The following code is borrowed from Microsoft OLE technology.)

// message loop for our thread.
BOOL WaitWithMessageLoop(HANDLE hEvent)
{
DWORD dwRet;
MSG msg;
while (1)
{
dwRet = MsgWaitForMultipleObjects(1, &hEvent, FALSE, 2000, QS_ALLINPUT);
if (dwRet == WAIT_OBJECT_0)
{
return TRUE;
}
else if (dwRet == WAIT_OBJECT_0 + 1)
{
// window message
while (PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
return FALSE;
}
}
}

If you like to try out the AVI Player you have to register the DLL. I will work under NT4.0 only.


Methods of the AVI Player


PlayEx
(
long hInstance ... Instance of the caller if you want to play an AVI out of your resource or 0
long hWnd ... Handle to the window within the Dialogbox should be centered or 0
long ResID ... < 0 that is you want to play a resource which resides in the DLL or the resource ID of your AVI.
-1 ... File copying
-2 ... File search
-3 ... transmitting data
-4 ... printing
BSTR Title ... Title of Dialog Box
long Repeat ... Number of Repetitions, -1 means infinite (until you call stop)
long Width ... Width of Dialogbox (if you specify both, width and height than the size of the Dialogbox will be calculated and the AVI will be centered in, otherwise (0) the calculation of the Dialogbox is based on the size of the AVI frames.)
long Height ... Height of Dialogbox.
long nTextRows ... Number of Textrows you want to display.
BOOL Progress ... TRUE: Progressbar is displayed.
long HalfLife ... Halflife-Time of the Progressbar in sec.
)


Stop() ... Stops the playing


SetText
(
BSTR Text ... additional text (will be displayed in static control)
)


ResetProgressBar() ... Resets the Value of the Progressbar to zero.


' Playing AVIs - Visual Basic sample.
' After you have registred the DLL, open a new Visual Basic Project and add the reference (ADV AVIPlayer 1.0) to your project.
' Add two command buttons (named 'cmdPlay', 'cmdStop') and the following code to your form:
Option Explicit
Dim Player As XAviPlayer
Private Sub cmdPlay_Click()
If Not (Player Is Nothing) Then
Player.Stop
Set Player = Nothing
End If
Set Player = New XAviPlayer
Call Player.PlayEx(0, Me.hWnd, -1, "Caption", -1, 0, 0, 2, 1, 2)
Call Player.SetText("additional text")
End Sub
Private Sub cmdResetProgress_Click()
If Not (Player Is Nothing) Then Call Player.ResetProgressBar
End Sub
Private Sub cmdStop_Click()
If Not (Player Is Nothing) Then
Player.Stop
Set Player = Nothing
End If
End Sub
Private Sub Form_Unload(Cancel As Integer)
If Not (Player Is Nothing) Then Set Player = Nothing
End Sub

// Visual C++ Sample. You have to add a new class (based on a typelibrary - AVI.dll) and to include the .h File
#inlcude "avi.h"

// intializing the com interface:
static struct InitOle
{
InitOle() { ::CoInitialize(NULL); }
~InitOle() { ::CoUninitialize(); }
} _init_InitOle_;



// somewhere

COleException e;
IXAviPlayer Player;

if (!Player.CreateDispatch(_T("XAviPlayer.XAviPlayer.1")))
{
// Error-Logging.
char buf[256];
sprintf(buf, "Error on CreateDispatch(): %ld (%08lx)", e.m_sc, e.m_sc);
AfxMessageBox(buf, MB_SETFOREGROUND);
return FALSE;
}

// Playing the AVI
Player.PlayEx(0L, 0L, -3, _T("Caption"), -1, 0L, 0L, 1, 1, 3);

// Later
Player.Stop();
Player.ReleaseDispatch();

Download AVI.dll – 63 KB

Download demo project – 68 KB

Download source – 76 KB

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read