Introducting MCIWnd Window Class
MCIWnd is a window class for controlling multimedia devices. A library of functions, messages, and macros associated with
MCIWnd provides a simple method to add multimedia playback or recording capabilities to your applications.
MCIWnd Window class is very easy to use. By identifying a simple
HWND member variable and assigning it to MCI window using a single function, you can create a control that plays any device that uses the media control interface (MCI) and gain support of any installed codec on your machine. These devices include Audio CDs, WAV Audios, MIDIs, and video devices with any supported codec.
Automating playback is also quick and easy. Using only one function and two macros, an application can create an MCIWnd window with the appropriate media device, play the device, and close both the device and the window when the content has finished playing.
Note that term device refers to any playable media from file stored to any playable medium.
Note: to use
MCIWnd Class in your application you must add vfw32.lib library to Link sections of Project Settings (accessible by Ctrl+F7) or simply add following line your header:
#pragma comment(lib, "vfw32.lib")
which does the same.
Considering we want to write a dialog based player, after adding library, add a
HWND member variable to your dialog class (as mentioned above), for example:
Then, add following code to any section you want to open your media for playing:
m_Player = MCIWndCreate(GetSafeHwnd(),AfxGetInstanceHandle(),
WS_CHILD | WS_VISIBLE, m_sFileName);
m_sFileName is a member variable which holds media name. After that you can use single line macros to control media playback. e.g.
MCIWndPlay(m_Player) to start media playback or
You are done, you have a media player now!
A wrapper class for MCIWnd: CEasyPlayer
I have written a very simple wrapper class for this API. This wrapper class is part of my work. That certain program needed simple playback of wav and mp3 media and sometimes continuous playing (loop). So, I just wrapped very few macros and messages in implementing the class. The class interface is as below:
class CEasyPlayer : public CWnd
void SetVolume(long lVol);
void SetPosition(long lPos);
void SetPath(CString sPath);
void SetParent(HWND hParent);
afx_msg void OnDestroy();
c_Player is that so called
HWND member variable. I use
c_ prefix to determine control variables from other member variables(Values).
MCIWnd control and assigns it to
c_Player. Other functions are identify themselves by their names which show exact duty of function. It is necessary to mention that
GetMode() is used to determine playback status and returns one of following values:
|Operating mode||MCI constant|
|not ready |
Class code is clear, it just wraps some macros, passes values to them and gets results from them. The only part of code that may need description is
Loop() function. Using
Loop() will cause launching a thread call to
LoopThread() which implementation is as follows:
UINT LoopThread(LPVOID pParam)
::PostMessage(c_Player, MCI_PLAY, 0, 0);
A conditional loop which checks if
m_Event member variable of class is set, if not then checks if media playback stoped. If so then replys the media by sending a
MCI_PLAY message to
HWND control. Very simple!
After concluding that project, I decided to try writing a Media Player, and that'is it. Using potentials of
CStatic control as a
CWnd derived class, I made a GUI for my wrapper class. I used a
CStatic control to hold onto video media playback (if exist). This
CStatic control rules as
CEasyPlayer instance parent.
Changing approach this application did not used
Loop() member function for continuous media playback. Instead a timer used to periodically check if media stopped or not.
I must mention that I used Nishant S approach to handles key board messages and menu accelerators in this application. Thank you very much Nishant S.
I took the introduction section of the article from MSDN (^). This article is first written in 2003.