#include <windows.h>
#include <ole2.h>
#include <objbase.h>
#include <exdisp.h>
#include <shlGuid.h>
#include <comdef.h>
#include <stdlib.h>


#include <atlbase.h>
#include <winerror.h>

#ifndef __CLASSES__
#define __CLASSES__

//#define NODISPATCH

void log (char* msg);
extern HWND HScol;
extern int XTobj;
extern int WM_XTEvent;

#undef log
//$BLG: Del
//#define log
#undef MMechostr
#define MMechostr

class Object;

/* Les structures de chez fred: */
// ObjVoid *********************************************************************
struct ObjVoid {

        int     Type            ; /* le type d'objet , voir plus bas           */       
        int     Father          ; /* le pointeur magma sur le pere             */
        int     Buffer          ; /* donnee de type TYPEBUF                    */
        int     Tab             ; /* donnee de type TYPETAB                    */
} ;
typedef struct ObjVoid *PtrObjVoid ;

// ObjWindow *******************************************************************
struct ObjWindow {

        int     PosX            ; /* position X a l'ecran                      */
        int     PosY            ; /* position Y a l'ecran                      */
        int     TailleW         ; /* taille horizontale de la fenetre          */
        int     TailleH         ; /* tailel verticale de la fenetre            */
        int     Flags           ; /* flags de la fenetre                       */
        HWND    WHandler        ; /* Handler Windows                           */
        
} ;        
typedef struct ObjWindow *PtrObjWindow ;
/* Fin des structures de chez fred */

//RFLstruct ********************************************************************
typedef struct RFLstruct
{
  Object *obj;
  int nelems;
  DISPID dispid;
  char **elems;
}RFLstruct;

RFLstruct *CreateRFLstruct(Object *obj, DISPID dispidmember, DISPPARAMS* pdispparams);
int FindInterface(Object *object, MEMBERID memid, char *resbuf);
int FreeInterfaces(Object *object);


// MDispatch *******************************************************************
class MDispatch : 
				public IDispatch, 
				public IPropertyNotifySink
{
protected:
  Object *mainobj;
  int ref;
public:
	//$BLG - v5.01: Add
	MDispatch()
	{
		ref = 0;
	}
	~MDispatch()
	{
	}

  STDMETHODIMP QueryInterface(/* [in] */ REFIID riid,/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
  {
    USES_CONVERSION;

    LPOLESTR str;
    log(">");
    StringFromCLSID(riid, &str);
    log(".h  : /////////////////////////////// IDispatch::QueryInterface");
    //MMechostr(1,"///// IDispatch::QueryInterface");
    log(OLE2T(str));

		//$BLG - v5.01: Add
		//AddRef();

    if (riid == IID_IUnknown)
    {
      log(".h  : IID_IUnknown OK");
      *ppvObject = this;
      //$BLG: Add
      ((IUnknown *)*ppvObject)->AddRef();
      return S_OK;  
    }
    else if (riid == IID_IDispatch)
    {
      log(".h  : IDispatch interface OK");
      *ppvObject = (IDispatch *)this;
      //$BLG: Add
      ((IDispatch *)*ppvObject)->AddRef();
      return S_OK;  
    }
    else
    {
      log(".h  : Another interface OK ");
      //MMechostr(1," Another interface OK \n");
      *ppvObject = (IDispatch *)this;
      //$BLG: Add
      ((IDispatch *)*ppvObject)->AddRef();
      return S_OK;  
    }

    //$BLG - v5.01: Del
    //How could we get up to there ??? Everything "else" is handled as IDispatch ...
    //log(".h  : no such interface..");
    //return E_NOINTERFACE;
  }
  
  //$BLG - v5.01: Modif
  /*
  unsigned long __stdcall AddRef(void) { 
  	log(".h  : MDispatch  AddRef"); 
  	ref++; 
  	return 0;
  }
  */
  unsigned long __stdcall AddRef(void) { 
  	char buf[256];
  	
  	ref++;
  	sprintf(buf, ".h  : MDispatch  AddRef - %d", ref);
  	log(buf); 
 
  	return ref;
  }
  
  //$BLG - v5.01: Modif
  /*
  unsigned long __stdcall Release(void) { 
  	log(".h  : MDispatch Release"); 
  	ref--; 
  	return 0;
  }
  */
  unsigned long __stdcall Release(void) { 
  	char buf[256];
  	
  	ref--;
  	sprintf(buf, ".h  : MDispatch Release - %d", ref);
  	log(buf); 
 
  	return ref;
  }

// IDispatch 
  STDMETHODIMP GetTypeInfoCount(unsigned int * truc) 
  { 
    log(".h  : IDispatch::GetTypeInfoCount Dispatch");
    return E_NOTIMPL;
  }
  
  STDMETHODIMP GetTypeInfo(unsigned int,unsigned long,struct ITypeInfo ** ) 
  { 
    log(".h  : IDispatch::GetTypeInfo Dispatch");
    return E_NOTIMPL;
  }
  
  virtual STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
  { 
    log(".h  : IDispatch::GetIDsOfNames");
    return E_NOTIMPL;
  }
  
  STDMETHODIMP Invoke(DISPID dispidMember,REFIID refiid,LCID,unsigned short,DISPPARAMS  *pdispparams,VARIANT  * pvarResult,EXCEPINFO*,unsigned int*) 
  { 
    USES_CONVERSION;
    //char buf[1024];
    RFLstruct *preflex;

		//$BLG - v5.01: Modif
		//This is to ensure that MDispatch.Invoke() will not be run after object destruction (this sometimes causes crashes with AX Controls by closure)
		/*
    log(".h  : Real Invoke Dispatch");
    if(dispidMember != -705  &&   dispidMember != -709 && dispidMember != -706
      &&  dispidMember != -501 &&  dispidMember != -701 &&  dispidMember != -710)
    {       
//      FindInterface(mainobj,dispidMember,buf);
//      MMechostr(1,"RealInvoke! [DispID: %d] [%s]\n",(int)dispidMember,buf);
      preflex=CreateRFLstruct(mainobj,dispidMember,pdispparams);

      sprintf(buf, "%d", (int)HScol);
      log(buf);
      if (mainobj == NULL) log(".h  : NULL"); else log(".h  : OK");
      PostMessage(HScol,WM_XTEvent,0,(DWORD)preflex);
    }
    log(".h  : REAL Invoke OK");
    */

    log(".h  : Real Invoke Dispatch");
    
    if (mainobj != NULL)
    {
	    if((dispidMember != -705) && (dispidMember != -709) && (dispidMember != -706) && (dispidMember != -501) && (dispidMember != -701) && (dispidMember != -710))
	    {       
				//FindInterface(mainobj,dispidMember,buf);
				//MMechostr(1,"RealInvoke! [DispID: %d] [%s]\n",(int)dispidMember,buf);
	      preflex = CreateRFLstruct(mainobj, dispidMember, pdispparams);
	
	      PostMessage(HScol, WM_XTEvent, 0, (DWORD)preflex);
	    }
	    log(".h  : REAL Invoke OK");
	  }
	  else
	  {
	  	log(".h  : REAL Invoke Failed - Object already destroyed");
	  }
    
    return E_NOTIMPL;
  }

// IPropertyNotifySink
  STDMETHODIMP OnChanged(DISPID dispID)
  {
    log(".h  : OnChanged");
    return S_OK;
  }
  
  STDMETHODIMP OnRequestEdit(DISPID dispID)
  {
    log(".h  : OnRequestEdit");
    return S_OK;
  }

  void setobj(Object *obj)
  {
    log(".h  : setobj");
    mainobj = obj;
  }

  void DeleteReflex(RFLstruct *p)
  {
    log(".h  : DeleteReflex");
    if (p->elems)
    {
      for (int i=0; i<p->nelems; i++)
        if (p->elems[i])
          delete p->elems[i];
      delete p->elems;
    }
    delete p;
  }

};


// MOleClientSite **************************************************************
class MOleClientSite : 
        public IOleClientSite, 
        public IOleControlSite,
        public IOleContainer,
        //$BLG 
        /*
        public IOleInPlaceSite,
        //$BLG: v4.6a5 - Add
        public IOleInPlaceSiteWindowless,
        */
        public IOleInPlaceSite,
#ifndef NODISPATCH
        public IOleInPlaceFrame,
        public IDispatch,
        public IServiceProvider,
#endif
        public ISupportErrorInfo
{
protected:
  ULONG ref;
  HWND hwnd;
  Object *mainobj;

public:

	//$BLG - v5.01: Add
	MOleClientSite()
	{
		ref = 0;
	};

	~MOleClientSite()
	{
	};

	// IUnknown

  STDMETHODIMP QueryInterface(/* [in] */ REFIID riid,/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
  {
    USES_CONVERSION;

    LPOLESTR str;
    StringFromCLSID(riid,&str);
    log(".h  : MOleClientSite::QueryInterface");
    log(OLE2T(str));

    if (riid==IID_IOleClientSite)
    {
      log(".h  : IID_IOleClientSite OK");
      *ppvObject = (IOleClientSite*)this;
			
			//$BLG - v5.01: Add
			((IOleClientSite *)*ppvObject)->AddRef();
			
      return S_OK;  
    }
    else if (riid==IID_IOleControlSite)
    {
      log(".h  : IID_IOleControlSite OK");
      *ppvObject = (IOleControlSite*)this;
			
			//$BLG - v5.01: Add
			((IOleControlSite *)*ppvObject)->AddRef();
			
      return S_OK;   
    }
    else if (riid==IID_IUnknown)
    {
      log(".h  : IID_IUnknown OK");
      *ppvObject = this;
			
			//$BLG - v5.01: Add
			((IUnknown *)*ppvObject)->AddRef();
			
      return S_OK; 
    }
    else if (riid==IID_IOleInPlaceSite)
    {
      log(".h  : IOleInPlaceSite interface OK");
      *ppvObject = (IOleInPlaceSite*)this;
			
			//$BLG - v5.01: Add
			((IOleInPlaceSite *)*ppvObject)->AddRef();
			
      return S_OK; 
    }
#ifndef NODISPATCH
    else if (riid==IID_IServiceProvider)
    {
      log(".h  : IServiceProvider interface OK");
      *ppvObject = (IServiceProvider*)this;
			
			//$BLG - v5.01: Add
			((IServiceProvider *)*ppvObject)->AddRef();
			
      return S_OK; 
    }
    else if (riid==IID_IDispatch)
    {
      log(".h  : IDispatch interface OK");
      *ppvObject = (IDispatch*)this;
			
			//$BLG - v5.01: Add
			((IDispatch *)*ppvObject)->AddRef();
			
      return S_OK;  
    }
    else if (riid==IID_IOleInPlaceFrame)
    {
      log(".h  : IOleInPlaceFrame interface OK");
      *ppvObject = (IOleInPlaceFrame*)this;
			
			//$BLG - v5.01: Add
			((IOleInPlaceFrame *)*ppvObject)->AddRef();
			
      return S_OK; 
    }
#endif
/*    else if (riid==IID_IOleContainer )
    {
      log(".h  : IOleContainer interface OK");
      *ppvObject = (IOleContainer*)this;
      return S_OK;  
    }*/
    else if (riid==IID_IParseDisplayName )
    {
      log(".h  : interface OK");
      *ppvObject = (IParseDisplayName*)this;
			
			//$BLG - v5.01: Add
			((IParseDisplayName *)*ppvObject)->AddRef();
			
      return S_OK; 
    }
//$BLG: v4.6a5 - Del: Code already present above
/*
    else if (riid==IID_IOleInPlaceSite)
    {
      log(".h  : MOleInPlaceSite interface OK");
      *ppvObject = (IOleInPlaceSite*)this;
      return S_OK;  
    }
*/    
    //$BLG: v4.6a5 - Add: IOleInPlaceSiteWindowless
    else if (riid==IID_IOleInPlaceSiteWindowless)
    {
      log(".h  : IOleInPlaceSiteWindowless interface OK");
      *ppvObject = (IOleInPlaceSiteWindowless*)this;
			
			//$BLG - v5.01: Add
			((IOleInPlaceSiteWindowless *)*ppvObject)->AddRef();
			
      return S_OK; 
    }    
    else if (riid==IID_ISupportErrorInfo)
    {
      log(".h  : ISupportErrorInfo interface OK");
      *ppvObject = (ISupportErrorInfo*)this;
			
			//$BLG - v5.01: Add
			((ISupportErrorInfo *)*ppvObject)->AddRef();
			
      return S_OK; 
    }

    log(".h  : no such interface..");
    return E_NOINTERFACE;
  };
  
  //$BLG - v5.01: Modif
  /*
    unsigned long __stdcall AddRef(void) { 
  	ref++;
  	return 0;
  }
  */
  unsigned long __stdcall AddRef(void) { 
  	char buf[256];
  	
  	ref++; 
  	sprintf(buf, ".h  : MOleClientSite AddRef - %d", ref);
  	log(buf);
  	
  	return ref;
  };
  
  //$BLG - v5.01: Modif
  /*
  unsigned long __stdcall Release(void) {
  	ref--;
  	return 0;
 }
 */
  unsigned long __stdcall Release(void) { 
		char buf[256];

  	ref--;
  	sprintf(buf, ".h  : MOleClientSite Release - %d", ref);
  	log(buf); 
 
  	return ref;
  };

	// IOleClientSite

  STDMETHODIMP SaveObject()
  {
    log(".h  : IOleClientSite::SaveObject");
    
    //$BLG - v5.01: Add
    AddRef();
    
    return S_OK;
  };
  
  STDMETHODIMP GetMoniker(/* [in] */ DWORD dwAssign, /* [in] */ DWORD dwWhichMoniker, /* [out] */ IMoniker __RPC_FAR *__RPC_FAR *ppmk)
  {
    log(".h  : IOleClientSite::GetMoniker");
    return E_NOTIMPL;
  };
  
  STDMETHODIMP GetContainer(/* [out] */ IOleContainer __RPC_FAR *__RPC_FAR *ppContainer)
  {
    log(".h  : IOleClientSite::GetContainer");
    *ppContainer = (IOleContainer*)this;
    
    //$BLG - v5.01: Add
    //http://msdn2.microsoft.com/en-us/library/ms688620.aspx
    //http://www.microsoft.com/msj/1299/Containment/Containment.aspx
    (*ppContainer)->AddRef();
    
    return S_OK;
  };
  
  STDMETHODIMP ShowObject()
  {
    log(".h  : IOleClientSite::ShowObject");
    return S_OK;
  };
  
  STDMETHODIMP OnShowWindow(/* [in] */ BOOL fShow)
  {
    log(".h  : IOleClientSite::OnShowWindow");
    return S_OK;
  };
  
  STDMETHODIMP RequestNewObjectLayout(void)
  {
    log(".h  : IOleClientSite::RequestNewObjectLayout");
    return E_NOTIMPL;
  };

	// IOleControlSite
	
  STDMETHODIMP OnControlInfoChanged( void)
  {
    log(".h  : IOleControlSite::OnControlInfoChanged");
    return E_NOTIMPL;
  };
  
  STDMETHODIMP LockInPlaceActive(/* [in] */ BOOL fLock)
  {
    log(".h  : IOleControlSite::LockInPlaceActive");
    return E_NOTIMPL;
  };
  
  STDMETHODIMP GetExtendedControl(/* [out] */ IDispatch __RPC_FAR *__RPC_FAR *ppDisp)
  {
    log(".h  : IOleControlSite::GetExtendedControl");
    return E_NOTIMPL;
  };
  
  STDMETHODIMP TransformCoords(/* [out][in] */ POINTL __RPC_FAR *pPtlHimetric,/* [out][in] */ POINTF __RPC_FAR *pPtfContainer,/* [in] */ DWORD dwFlags)
  {
    log(".h  : IOleControlSite::TransformCoords");
    return E_NOTIMPL;
  };
  
  STDMETHODIMP TranslateAccelerator (/* [in] */ MSG __RPC_FAR *pMsg,/* [in] */ DWORD grfModifiers)
  {
    log(".h  : IOleControlSite::TranslateAccelerator");
    return E_NOTIMPL;
  };
  
  STDMETHODIMP OnFocus(/* [in] */ BOOL fGotFocus)
  {
    log(".h  : IOleControlSite::OnFocus");
    return S_OK;
  };
  
  STDMETHODIMP ShowPropertyFrame(void)
  {
    log(".h  : IOleControlSite::ShowPropertyFrame");
    return E_NOTIMPL;
  };


#ifndef NODISPATCH
	// IDispatch 
	
  STDMETHODIMP GetTypeInfoCount(unsigned int * truc) 
  { 
    log(".h  : IDispatch::GetTypeInfoCount OleClientSite");
    return E_NOTIMPL;
  };
  
  STDMETHODIMP GetTypeInfo(unsigned int,unsigned long,struct ITypeInfo ** ) 
  { 
    log(".h  : IDispatch::GetTypeInfo OleClientSite");
    return E_NOTIMPL;
  };
  
  virtual STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
  { 
    log(".h  : IDispatch::GetIDsOfNames");
    return E_NOTIMPL;
  };
  
  STDMETHODIMP Invoke(DISPID dispidMember,REFIID refiid,LCID,unsigned short,DISPPARAMS *pdispparams,VARIANT *pvarResult,EXCEPINFO*,unsigned int*) 
  { 
    USES_CONVERSION;
    char buf[1024];
//    unsigned int k;

//    return DispInvoke(this, m_ptinfo,dispidMember, wFlags, pDispParams,pVarResult, pExcepInfo, puArgErr); 

    log(".h  : Invoke Dispatch");
    if((dispidMember != -705) && (dispidMember != -709) && (dispidMember != -706) && (dispidMember != -501) && (dispidMember != -701) && (dispidMember != -710))
    {       
//        PostMessage(Hscol,WM,0,(DWORD)preflex);
    }
    FindInterface(mainobj, dispidMember, buf);
//    MMechostr(1,"Invoke! [DispID: %d] [refiid: %d] [%s]\n",dispidMember,refiid,buf);
    log(".h  : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Invoke OK");                               
    return E_NOTIMPL;
  };

	// IServiceProvider
	
  STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void** ppv)
  {
    USES_CONVERSION;
    LPOLESTR str;
    log(".h  : MServiceProvider::QueryService");

    StringFromCLSID(guidService, &str);
    log(".h  : GUID:");
    log(OLE2T(str));
    StringFromCLSID(riid, &str);
    log(".h  : IID:");
    log(OLE2T(str));

    if (ppv) *ppv = NULL;
    return E_NOINTERFACE;
  };

  // IOleInPlaceFrame
  
  STDMETHODIMP InsertMenus(/* [in] */ HMENU hmenuShared,/* [out][in] */ LPOLEMENUGROUPWIDTHS lpMenuWidths)
  {
    log(".h  : >>>>>>>>>>>IOleInPlaceFrame InsertMenus");
    return E_NOTIMPL;
  };
  
  STDMETHODIMP SetMenu(/* [in] */ HMENU hmenuShared,/* [in] */ HOLEMENU holemenu,/* [in] */ HWND hwndActiveObject)
  {
    log(".h  : >>>>>>>>>>>IOleInPlaceFrame SetMenu");
    return E_NOTIMPL;
  };
  
  STDMETHODIMP RemoveMenus(/* [in] */ HMENU hmenuShared)
  {
    log(".h  : >>>>>>>>>>>IOleInPlaceFrame RemoveMenus");
    return E_NOTIMPL;
  };
  
  STDMETHODIMP SetStatusText(/* [unique][in] */ LPCOLESTR pszStatusText)
  {
    USES_CONVERSION;
    log(".h  : >>>>>>>>>>>IOleInPlaceFrame SetStatusText");
    log(OLE2T(pszStatusText));
    return S_OK;
  };
  
  STDMETHODIMP EnableModeless(/* [in] */ BOOL fEnable)
  {
    log(".h  : >>>>>>>>>>>IOleInPlaceFrame EnableModeless");
    /*
    if (fEnable) log(".h  : TRUE..."); 
    else log(".h  : FALSE...");
    */
    return S_OK;
  };
  
  STDMETHODIMP TranslateAccelerator(/* [in] */ LPMSG lpmsg,/* [in] */ WORD wID)
  {
    log(".h  : >>>>>>>>>>>IOleInPlaceFrame TranslateAccelerator");
    return E_NOTIMPL;
  };

#endif

	// IParseDisplayName
  virtual STDMETHODIMP ParseDisplayName(IBindCtx*, LPOLESTR, ULONG*,IMoniker ** )
  {
    log(".h  : IParseDisplayName::ParseDisplayName");
    return E_NOTIMPL;
  };

	// IOleContainer
	
  STDMETHODIMP EnumObjects(unsigned long,struct IEnumUnknown ** )
  {
    log(".h  : IOleContainer::EnumObjects");
    return E_NOTIMPL;
  };
  
  STDMETHODIMP LockContainer(int)
  {
    log(".h  : IOleContainer::LockContainer");
    return E_NOTIMPL;
  };
  
	// IOleWindow
	
  STDMETHODIMP GetWindow(HWND * phwnd)
  {
    char buf[80];
    log(".h  : MOleInPlaceSite GetWindow");
    sprintf(buf,"---------------- GetWindow HWND = %X",hwnd);
    log(buf);
    
    *phwnd = hwnd;
    
    return S_OK;
  };

  STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode)
  {
    log(".h  : MOleInPlaceSite ContextSensitiveHelp");
    return E_NOTIMPL;
  };
        
	// IOleInPlaceSite

  STDMETHODIMP CanInPlaceActivate(void)
  {
    log(".h  : MOleInPlaceSite CanInPlaceActivate");
    return S_OK;
  };
        
  STDMETHODIMP OnInPlaceActivate(void)
  {
    log(".h  : MOleInPlaceSite OnInPlaceActivate");
    return S_OK;
  };
  
  STDMETHODIMP OnUIActivate(void)
  {
    log(".h  : MOleInPlaceSite OnUIActivate");
    //$BLG - v5.01: Modif
    return E_NOTIMPL;
    //return S_OK;
  };
  
  STDMETHODIMP GetWindowContext(/* [out] */ IOleInPlaceFrame __RPC_FAR *__RPC_FAR *ppFrame,
                                /* [out] */ IOleInPlaceUIWindow __RPC_FAR *__RPC_FAR *ppDoc,
                                /* [out] */ LPRECT lprcPosRect,
                                /* [out] */ LPRECT lprcClipRect,
                                /* [out][in] */ LPOLEINPLACEFRAMEINFO lpFrameInfo)
  {
    log(".h  : MOleInPlaceSite GetWindowContext");

#ifndef NODISPATCH
    *ppFrame = (IOleInPlaceFrame *)this;
    *ppDoc = (IOleInPlaceUIWindow *)this;
#else
    *ppFrame = (IOleInPlaceFrame *)NULL;
    *ppDoc = NULL;
#endif

    GetClientRect(hwnd, lprcPosRect);
    GetClientRect(hwnd, lprcClipRect);

//$BLG - v5.01: Note
//Next lines were already commented, except the ->cb that I added for testing
/*
		lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO);
    lpFrameInfo->fMDIApp=FALSE;
//    lpFrameInfo->hwndFrame=hwnd;
    lpFrameInfo->hwndFrame=HScol;
    lpFrameInfo->haccel=NULL;
    lpFrameInfo->cAccelEntries=0;
*/

    return S_OK;
  };

  STDMETHODIMP Scroll(/* [in] */ SIZE scrollExtant)
  {
    log(".h  : MOleInPlaceSite Scroll");
    return S_OK;
  };
  
  STDMETHODIMP OnUIDeactivate(/* [in] */ BOOL fUndoable)
  {
    log(".h  : MOleInPlaceSite OnUIDeactivate");
    return S_OK;
  };
  
  STDMETHODIMP OnInPlaceDeactivate(void)
  {
    log(".h  : MOleInPlaceSite OnInPlaceDeactivate");
    return S_OK;
  };
  
  STDMETHODIMP DiscardUndoState(void)
  {
    log(".h  : MOleInPlaceSite DiscardUndoState");
    return S_OK;
  };
  
  STDMETHODIMP DeactivateAndUndo(void)
  {

    log(".h  : MOleInPlaceSite DeactivateAndUndo");
    // Potential Danger Here!!!
    return S_OK;
  };
  
  STDMETHODIMP OnPosRectChange(/* [in] */ LPCRECT lprcPosRect)
  {
    log(".h  : MOleInPlaceSite OnPosRectChange");
    return E_NOTIMPL;
  };

  // IOleInPlaceUIWindow
  
  STDMETHODIMP GetBorder(/* [out] */ LPRECT lprectBorder)
  {
    log(".h  : ------------IOleInPlaceUIWindow GetBorder");
    return INPLACE_E_NOTOOLSPACE;
  };

  STDMETHODIMP RequestBorderSpace(/* [unique][in] */ LPCBORDERWIDTHS pborderwidths)
  {
    log(".h  : ------------IOleInPlaceUIWindow RequestBorderSpace");
    return INPLACE_E_NOTOOLSPACE;
  };

  STDMETHODIMP SetBorderSpace(/* [unique][in] */ LPCBORDERWIDTHS pborderwidths)
  {
    log(".h  : ------------IOleInPlaceUIWindow SetBorderSpace");
    return E_UNEXPECTED;
  };

  STDMETHODIMP SetActiveObject(/* [unique][in] */ IOleInPlaceActiveObject __RPC_FAR *pActiveObject,/* [unique][string][in] */ LPCOLESTR pszObjName)
  {
    char buf[256];
    
    log(".h  : ------------IOleInPlaceUIWindow SetActiveObject");
    sprintf(buf, "> %d", pActiveObject);
    log(buf);
    
    return E_UNEXPECTED;
  };

  STDMETHODIMP InterfaceSupportsErrorInfo(REFIID riid)
  {
      log(".h  : ------------IOleInPlaceUIWindow InterfaceSupportsErrorInfo");
      return S_FALSE;
  };

  // MOLEINPLACESITE
  
  void setHWND(HWND h) 
  { 
    char buf[80];
    //$BLG
    log(".h  : setHWND");
    
    hwnd = h;
    
    sprintf(buf,"IOleContainer::OleContainer HWND = %X",hwnd);
    log(buf);
  };
  
  void setobj(Object *obj) 
  { 
    log(".h  : setobj");
    mainobj = obj;
  };
};


// OBJECT **********************************************************************
class Object
{
public:
  IClassFactory *pClassFactory;
  IOleObject *pOleObject;
	IOleControl *pOleControl;

  MOleClientSite OleClientSite;
  MDispatch Dispatch;

  Object()
  {
    log(".h  : Object Constructor...");
    //MMechostr(1,"Object Constructor...\n");
    pClassFactory = (IClassFactory *)NULL;
    pOleObject = (IOleObject *)NULL;
    pOleControl = (IOleControl *)NULL;
    OleClientSite.setobj(this);
    Dispatch.setobj(this);
  }

  ~Object()
  {
    log(".h  : Object Destructor...");
    //MMechostr(1,"Object Destructor...\n");

    FreeInterfaces(this);

    if (pOleObject)
    {
      log(".h  : Close pOleObject");
      //$BLG - v5.01: Modif
      pOleObject->Close(OLECLOSE_PROMPTSAVE);
      //pOleObject->Close(OLECLOSE_NOSAVE);
      log("<");
    }

    log(".h  : Release pOleControl");
    if (pOleControl) pOleControl->Release();
    pOleControl = (IOleControl *)NULL;
    log("<");

    log(".h  : Release pOleObject");
    if (pOleObject) pOleObject->Release();
    pOleObject = (IOleObject *)NULL;
    log("<");

    log(".h  : Release pClassFactory");
    if (pClassFactory) pClassFactory->Release();
    pClassFactory = (IClassFactory *)NULL;
    log("<");
    
    //$BLG - v5.01: Add
    //This is to ensure that MDispatch.Invoke() will not be run after object destruction (this sometimes causes crashes with AX Controls by closure)
    OleClientSite.setobj(NULL);
    OleClientSite.Release();		//This is to decrement the reference count that was first incremented by SetClientSite() in _AXSetSite()
    Dispatch.setobj(NULL);
    //delete &Dispatch;
    //delete &OleClientSite;
    
    log(".h  : ...Object destroyed");
  }
};


#endif


/*
IOleCommandTarget
*/