README.TXT
IEMime Sample 
============= 
 
IEMime demonstrates MIME type registration and MIME type recognition of downloads. 
 
The control starts an asynchronous download, usually by asking its 
bind-host to MonikerBindToStorage on its behalf. During the download proces, IEMime 
is notified of the MIME type on its bind-status-callback. IEMime displays this MIME type. 
 
Main points of interest: 
 
* For purposes of demonstration, IEMime uses a somewhat atypical scheme for 
  downloading during initialization. Typically, a control which downloads asynchronous 
  data based on a data-path property (URL) would proceed with the download as soon 
  as it possibly can. The ReadyState property would then be used to signal to MSHTML as 
  the control container that the control was done downloading whatever data it needed 
  asynchronously. MSHTML would continue to show progress and UI such as the spinning 
  icon until the control signalled READYSTATE_COMPLETE. In most cases, any events 
  signalling the download would happen before the page was ready to receive them. In 
  the case of IEMime, this would cause the Complete() event to not fire on page-startup. 
 
  Instead, IEMime waits until the container is totally ready to receive events before 
  starting its download. That way, script can catch Complete() even for downloads kicked off 
  by <PARAM URL=> persistent properties. However, this gets us into a deadlocked 
  situation of sorts -- the container is waiting for our control to signal complete 
  while we're waiting for the container to go complete. We avoid this problem by 
  signalling "COMPLETE" as soon as our properties are loaded and then transitioning back to 
  "INTERACTIVE" once we start our asynchronous download. This solution is acceptable -- 
  it is okay for a control to change ReadyState back to LOADED or INTERACTIVE while it 
  is re-downloading a data file or re-evaluating a query, for example. We always go back 
  to INTERACTIVE when doing an asynchronous download. 
 
  The traditional means for a control to know when its container is up and running and 
  can receive events is to watch IOleControl::FreezeEvents until the freeze count 
  transitions from 1 to 0. This is where IEMime kicks off the download by calling Reload(). 
 
* IEMime adds to the basic ATL class CBindStatusCallback by adding some extra overrides. 
  IEMime's CBindStatusCallback2 passes the FORMATETC and STGMEDIUM on to the using class 
  (CIEMimeCtl) during OnData, because these structures are what we are really interested in. 
  The original CBindStatusCallback did not provide these to the using class. 
 
  IEMime also calls up to two funcs in the using class, PreBindMoniker & OnBindingFailure. 
  The class design here could be improved, as this requires the using class to implement 
  these funcs instead of pass in func-pointers such as with OnData. In our case, 
  we want to handle both so it isn't a big deal. 
 
* PreBindMoniker is intended to allow the using class to talk to the IBindCtx and IMoniker 
  interfaces before the upcoming bind process. In our case, we use it to demonstrate 
  the use of the RegisterMediaType, CreateFormatEnumerator, and RegisterFormatEnumerator APIs. 
  If the "Media" property has been set on the control, then IEMime uses this custom 
  string to Register a new Media Type. This nets a Clipboard format for that media type. Then, 
  IEMime creates a format enumerator that enumerates ONLY this custom clipformat and registers 
  that format enumerator on the bindctx. The net effect of this is that IE will use this 
  custom type in the HTTP "Accept" header supplied to remote servers to indicate the 
  accepted types that we're looking for. Feel free to experiment with different servers 
  and different requested types. 
 
* IEMime marks itself as safe-for-persistence on the IPersistPropertyBag interface. This 
  is necessary to allow controls to receive Property persistence through <PARAM> tags.  
  The standard ATL IObjectSafetyImpl doesn't support this automatically, so we override 
  Set/GetInterfaceSafetyOptions and do the right magic. 
 
* Miscellaneous Note #1: When asking a BindHost to do a binding via MonikerBindToStorage, 
  the IBindStatusCallback registered on the IBindCtx will not be used in most cases and 
  will get dumped. It's pretty important to supply the IBindStatusCallback interface as the 
  third parameter to MonikerBindToStorage.  
 
* Miscellaneous Note #2: IProvideClassInfo(2) must be implemented by a control if it wants 
  IE/MSHTML to connect the control's event sink for scripting.