A COM-based Automation Wave File Editor


Desktop-as-a-Service Designed for Any Cloud ? Nutanix Frame

  WaveEditAuto.gif (7152 bytes)


This article takes the original programming idea from the Wave File Editor Control and extends the application's functionality into a client/server application set.
The WaveEdit app can now be used as a stand-alone program or as a server, controlled by client applications written in VC++ or VB.

Making the transition from stand-alone application to client/server has become easier due to MFC's built-in automation support (faster/easier development at the expense of increasingly bloated code).
If you look at the original Wave Editor Control code, the functionality for graphing is encapsulated within a CWnd derived object - all very nice and modular and easy to move around, but within the context of MFC automation, maybe too unnecessarily complicated.
So to simplify, I took the functionality out of the WaveEditCtrl class and put it in the server's OnPaint handler.

IDispatch, Type Libraries and Stuff

To enable communication between applications (Automation), COM provides the IDispatch interface. IDispatch permits COM objects to expose functions, data and events to the outside world, allowing other applications to control these programmable objects. Although the IDispatch interface can be queried at runtime so that a client can know which data and functions are supported by the object, this requires creation of an instance of the object and may not be what we want in terms of flexibility. This is where the Type Library comes in and acts as a sort of #import library for COM objects.
Using type libraries within our automated applications provides us with information about the interfaces supported and the methods that each interface supports - regardless of whether our COM object has been created or not.

Basic Recipe

I found it easiest to create the code by following a cookbook recipe, starting from scratch - two individual AppWizard generated SDI applications with automation support added. With initial automation support you get an automation skeleton consisting of initialization code for the application's InitInstance() function, a dispatch map within the document class and a type library. Adapting the WaveEditCtrl code into the server proved not too difficult - basically, moving the initial caret positioning into the view's OnInitialUpdate().

Programming Flow

                               WaveEditAuto2.gif (4296 bytes)

Initialization - The server application exposes its functionality to the outside world through its COM enabled IWaveEdit interface in the form of various methods that are called from the client application.
When the client launches, it creates an object of the IWaveEdit interface, looks for it's CLSID in the registry and creates the IDispatch object. This gives the client access to the server's methods providing the ability to launch the server with the client.
Because the default nature of an automation server is to be invisible - we need to call three methods when launching the client, ShowApp(), ShowWindow() and SetCursor(). These methods allow the server to launch in an identical manner to it's stand-alone counterpart.
These three methods respectively allow the server's main window and view to become visible as well as placing the blinking cursor in it's initial position within the client area.

Interaction - When the client Play button is clicked, it's timer starts the stopwatch in the client's StatusBar and calls the server method - SetPlay() which in turn starts it's own timer and sends the cursor on it's merry way.
Similar server methods are called for the client's Pause and Stop buttons.

So when does the client's stopwatch know when the server has finished playing it's wave file?
The IsWaveEnd() method of course! - The client continually calls this method when it's timer is running to check the status.If the caret reaches the full width of the server's client area it sets the IWaveEdit boolean property - result. Once result returns true, the client timer simply kills itself.

void CWaveEditClientView::OnTimer(UINT nIDEvent) 

	if (m_waveEditObject.result){

	m_bPlaying = FALSE;


Definitly not the most complex COM-based app around, but should be of interest if you wish to automate some of your own code ideas.
BTW, sorry about the On/Off buttons - they might indicate to you that a COM object is being created through a class factory, or an IUnknown interface pointer is being released - I assure you that they simply show and hide the server application!
The screen redraw of the server app is annoying when clicking the client play button. But remember, in this simplified code we just draw random lines - in an audio application you would reload the same samples from the same wave file.

Download demo project - 124 KB


  • There are no comments yet. Be the first to comment!

  • You must have javascript enabled in order to post comments.

Leave a Comment
  • Your email address will not be published. All fields are required.

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date