How to synchronize the container application with the control
Some method available inside Active DJ Studio performs lengthy operations which, on a single-threaded environment, could block the user interface of the container application also for several seconds: just think about the time requested to perform the waveform analysis for a song longer than 5 minutes and you will perfectly understand that this operation couldn't be completed in less than one second.
In order to avoid this kind of blocks, the control performs lengthy operations inside secondary threads; the main side effect of this multithreaded approach is the fact that, when the method call returns, the requested operation could still be running in the background so requested data wouldn't be already available and any method call trying to access data would fail by returning an error code; for this reason it's very important that the container application synchronizes itself with events fired by the control.
Just to make a practical example, let's take the mentioned waveform's analysis calculation for having a better understanding of the issue: the container application requests the calculation of the sound's waveform through a call to the Waveform.AnalyzeFullSound method; when this method returns, the waveform is still being calculated in background and the container application will be notified about calculation advancement through the following events:
After receiving the last event, the container application could request further operations with the calculated waveform, for example it could request to obtain the bitmap representation of the waveform through a call to the Waveform.BitmapViewSaveToFile method: it's very important to remember that a call to a method of a certain ActiveX control should be never performed from within a management function of an event generated by the same ActiveX control: this is usually cause of errors and dead-lock situations and it's a practice that should be always avoided; the best approach in cases like this would be using the WaveAnalysisDone event to trigger a one shot-timer and to call the Waveform.BitmapViewSaveToFile method from within the management function of the timer's event.
As a further suggestion, keep management functions of events generated by the component as fast/short as possible and never use them in order to display messages or dialog boxes which require user interaction.