// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.

#ifndef __AFXOLE_H__
#define __AFXOLE_H__

#ifdef _AFX_NO_OLE_SUPPORT
	#error OLE classes not supported in this library variant.
#endif

#ifndef __AFXEXT_H__
	#include <afxext.h>
#endif

#ifndef __AFXDISP_H__
	#include <afxdisp.h>
#endif

// include OLE Compound Document headers
#ifndef _OLE2_H_
	#include <ole2.h>
#endif

// ActiveX Document support
#ifndef __docobj_h__
	#include <docobj.h>
#endif

// URL Monikers support
#ifndef __urlmon_h__
	#include <urlmon.h>
#endif

#ifndef __AFXCOM_H__
#include <afxcom_.h>
#endif

#ifdef _AFX_MINREBUILD
#pragma component(minrebuild, off)
#endif
#ifndef _AFX_FULLTYPEINFO
#pragma component(mintypeinfo, on)
#endif

#ifdef _AFX_PACKING
#pragma pack(push, _AFX_PACKING)
#endif


#ifndef _AFX_NOFORCE_LIBS

#pragma comment(lib, "urlmon.lib")

#endif // !_AFX_NOFORCE_LIBS

/////////////////////////////////////////////////////////////////////////////
// AFXOLE.H - MFC OLE support

// Classes declared in this file

//CDocument
	class COleDocument;             // OLE container document
		class COleLinkingDoc;       // supports links to embeddings
			class COleServerDoc;    // OLE server document
	class CDocObjectServer;         // might be owned by a COleServerDoc

//CCmdTarget
	class CDocItem;                 // part of a document
		class COleClientItem;       // embedded ole object from outside
#if _MFC_VER >= 0x0600
            class COleDocObjectItem;// ActiveX Document item
#endif
		class COleServerItem;       // ole object to export
	class COleDataSource;           // clipboard data source mechanism
	class COleDropSource;           // drag/drop source
	class COleDropTarget;           // drag/drop target
	class COleMessageFilter;        // concurrency management

//CFrameWnd
	class COleIPFrameWnd;           // frame window for in-place servers

//CControlBar
	class COleResizeBar;            // implements in-place resizing

//CFile
	class COleStreamFile;           // CFile wrapper for IStream interface
		class CMonikerFile;         // bound to via IMoniker
			class CAsyncMonikerFile;// asynchronous IMoniker

class COleDataObject;               // wrapper for IDataObject interface

/////////////////////////////////////////////////////////////////////////////

// AFXDLL support
#undef AFX_DATA
#define AFX_DATA AFX_OLE_DATA

/////////////////////////////////////////////////////////////////////////////
// backward compatibility

// COleClientDoc is now obsolete -- use COleDocument instead
#define COleClientDoc COleDocument

// COleServer has been replaced by the more general COleObjectFactory
#define COleServer  COleObjectFactory

/////////////////////////////////////////////////////////////////////////////
// Useful OLE specific types (some from OLE 1.0 headers)

// Codes for CallBack events
enum OLE_NOTIFICATION
{
	OLE_CHANGED,        // representation of a draw aspect has changed
	OLE_SAVED,          // the item has committed its storage
	OLE_CLOSED,         // the item has closed
	OLE_RENAMED,        // the item has changed its moniker
	OLE_CHANGED_STATE,  // the item state (open, active, etc.) has changed
	OLE_CHANGED_ASPECT, // the item draw aspect has changed
};

// Object types
enum OLE_OBJTYPE
{
	OT_UNKNOWN = 0,

	// These are OLE 1.0 types and OLE 2.0 types as returned from GetType().
	OT_LINK = 1,
	OT_EMBEDDED = 2,
	OT_STATIC = 3,

	// All OLE2 objects are written with this tag when serialized.  This
	//  differentiates them from OLE 1.0 objects written with MFC 2.0.
	//  This value will never be returned from GetType().
	OT_OLE2 = 256,
};

/////////////////////////////////////////////////////////////////////////////
// COleDataObject -- simple wrapper for IDataObject

class COleDataObject
{
// Constructors
public:
	COleDataObject();

// Operations
	void Attach(LPDATAOBJECT lpDataObject, BOOL bAutoRelease = TRUE);
	LPDATAOBJECT Detach();  // detach and get ownership of m_lpDataObject
	void Release(); // detach and Release ownership of m_lpDataObject
	BOOL AttachClipboard(); // attach to current clipboard object

// Attributes
	void BeginEnumFormats();
	BOOL GetNextFormat(LPFORMATETC lpFormatEtc);
	CFile* GetFileData(CLIPFORMAT cfFormat, LPFORMATETC lpFormatEtc = NULL);
	HGLOBAL GetGlobalData(CLIPFORMAT cfFormat, LPFORMATETC lpFormatEtc = NULL);
	BOOL GetData(CLIPFORMAT cfFormat, LPSTGMEDIUM lpStgMedium,
		LPFORMATETC lpFormatEtc = NULL);
	BOOL IsDataAvailable(CLIPFORMAT cfFormat, LPFORMATETC lpFormatEtc = NULL);

// Implementation
public:
	LPDATAOBJECT m_lpDataObject;
	LPENUMFORMATETC m_lpEnumerator;
	~COleDataObject();

	// advanced use and implementation
	LPDATAOBJECT GetIDataObject(BOOL bAddRef);
	void EnsureClipboardObject();
	BOOL m_bClipboard;      // TRUE if represents the Win32 clipboard

protected:
	BOOL m_bAutoRelease;    // TRUE if destructor should call Release

private:
	// Disable the copy constructor and assignment by default so you will get
	//   compiler errors instead of unexpected behaviour if you pass objects
	//   by value or assign objects.
	COleDataObject(const COleDataObject&);  // no implementation
	void operator=(const COleDataObject&);  // no implementation
};

/////////////////////////////////////////////////////////////////////////////
// COleDataSource -- wrapper for implementing IDataObject
//  (works similar to how data is provided on the clipboard)

struct AFX_DATACACHE_ENTRY;
class COleDropSource;

class COleDataSource : public CCmdTarget
{
// Constructors
public:
	COleDataSource();

// Operations
	void Empty();   // empty cache (similar to ::EmptyClipboard)

	// CacheData & DelayRenderData operations similar to ::SetClipboardData
	void CacheGlobalData(CLIPFORMAT cfFormat, HGLOBAL hGlobal,
		LPFORMATETC lpFormatEtc = NULL);    // for HGLOBAL based data
	void DelayRenderFileData(CLIPFORMAT cfFormat,
		LPFORMATETC lpFormatEtc = NULL);    // for CFile* based delayed render

	// Clipboard and Drag/Drop access
	DROPEFFECT DoDragDrop(
		DWORD dwEffects = DROPEFFECT_COPY|DROPEFFECT_MOVE|DROPEFFECT_LINK,
		LPCRECT lpRectStartDrag = NULL,
		COleDropSource* pDropSource = NULL);
	void SetClipboard();
	static void PASCAL FlushClipboard();
	static COleDataSource* PASCAL GetClipboardOwner();

	// Advanced: STGMEDIUM based cached data
	void CacheData(CLIPFORMAT cfFormat, LPSTGMEDIUM lpStgMedium,
		LPFORMATETC lpFormatEtc = NULL);    // for LPSTGMEDIUM based data
	// Advanced: STGMEDIUM or HGLOBAL based delayed render
	void DelayRenderData(CLIPFORMAT cfFormat, LPFORMATETC lpFormatEtc = NULL);

	// Advanced: support for SetData in COleServerItem
	//  (not generally useful for clipboard or drag/drop operations)
	void DelaySetData(CLIPFORMAT cfFormat, LPFORMATETC lpFormatEtc = NULL);

// Overidables
	virtual BOOL OnRenderGlobalData(LPFORMATETC lpFormatEtc, HGLOBAL* phGlobal);
	virtual BOOL OnRenderFileData(LPFORMATETC lpFormatEtc, CFile* pFile);
	virtual BOOL OnRenderData(LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium);
		// OnRenderFileData and OnRenderGlobalData are called by
		//  the default implementation of OnRenderData.

	virtual BOOL OnSetData(LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium,
		BOOL bRelease);
		// used only in COleServerItem implementation

// Implementation
public:
	virtual ~COleDataSource();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:
	AFX_DATACACHE_ENTRY* m_pDataCache;  // data cache itself
	UINT m_nMaxSize;    // current allocated size
	UINT m_nSize;       // current size of the cache
	UINT m_nGrowBy;     // number of cache elements to grow by for new allocs

	AFX_DATACACHE_ENTRY* Lookup(
		LPFORMATETC lpFormatEtc, DATADIR nDataDir) const;
	AFX_DATACACHE_ENTRY* GetCacheEntry(
		LPFORMATETC lpFormatEtc, DATADIR nDataDir);

// Interface Maps
public:
	BEGIN_INTERFACE_PART(DataObject, IDataObject)
		INIT_INTERFACE_PART(COleDataSource, DataObject)
		STDMETHOD(GetData)(LPFORMATETC, LPSTGMEDIUM);
		STDMETHOD(GetDataHere)(LPFORMATETC, LPSTGMEDIUM);
		STDMETHOD(QueryGetData)(LPFORMATETC);
		STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC, LPFORMATETC);
		STDMETHOD(SetData)(LPFORMATETC, LPSTGMEDIUM, BOOL);
		STDMETHOD(EnumFormatEtc)(DWORD, LPENUMFORMATETC*);
		STDMETHOD(DAdvise)(LPFORMATETC, DWORD, LPADVISESINK, LPDWORD);
		STDMETHOD(DUnadvise)(DWORD);
		STDMETHOD(EnumDAdvise)(LPENUMSTATDATA*);
	END_INTERFACE_PART(DataObject)

	DECLARE_INTERFACE_MAP()

	friend class COleServerItem;
};

//////////////////////////////////////////////////////////////////////////////
// DocItem support

#ifdef _AFXDLL
class CDocItem : public CCmdTarget
#else
class AFX_NOVTABLE CDocItem : public CCmdTarget
#endif
{
	DECLARE_SERIAL(CDocItem)

// Constructors
protected:      // abstract class
	CDocItem();

// Attributes
public:
	CDocument* GetDocument() const; // return container document

// Overridables
public:
	// Raw data access (native format)
	virtual BOOL IsBlank() const;

// Implementation
protected:
	COleDocument* m_pDocument;

public:
	virtual void Serialize(CArchive& ar);   // for Native data
	virtual ~CDocItem();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

	friend class COleDocument;              // for access to back pointer
};

//////////////////////////////////////////////////////////////////////////////
// COleDocument - common OLE container behavior (enables server functionality)

class COleDocument : public CDocument
{
	DECLARE_DYNAMIC(COleDocument)

// Constructors
public:
	COleDocument();

// Attributes
	BOOL HasBlankItems() const; // check for BLANK items
	virtual COleClientItem* GetInPlaceActiveItem(CWnd* pWnd);
		// return in-place active item for this view or NULL if none

// Operations
	// iterating over existing items
	virtual POSITION GetStartPosition() const;
	virtual CDocItem* GetNextItem(POSITION& pos) const;

	// iterator helpers (helpers use virtual GetNextItem above)
	COleClientItem* GetNextClientItem(POSITION& pos) const;
	COleServerItem* GetNextServerItem(POSITION& pos) const;

	// adding new items - called from item constructors
	virtual void AddItem(CDocItem* pItem);
	virtual void RemoveItem(CDocItem* pItem);

	void EnableCompoundFile(BOOL bEnable = TRUE);
		// enable compound file support (only call during constructor)
	virtual void UpdateModifiedFlag();
		// scan for modified items -- mark document modified

	// printer-device caching/control
	BOOL ApplyPrintDevice(const DVTARGETDEVICE* ptd);
	BOOL ApplyPrintDevice(const PRINTDLG* ppd);
		// these apply the target device to all COleClientItem objects

// Overridables
	virtual COleClientItem* GetPrimarySelectedItem(CView* pView);
		// return primary selected item or NULL if none
	virtual void OnShowViews(BOOL bVisible);
		// called during app-idle when visibility of a document has changed

// Implementation
public:
	CObList m_docItemList;  // not owned items

#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif
	CFrameWnd* GetFirstFrame();

	// document handling overrides
	virtual void SetPathName(LPCTSTR lpszPathName, BOOL bAddToMRU = TRUE);
	virtual ~COleDocument();
	virtual void DeleteContents(); // delete client items in list
	virtual void Serialize(CArchive& ar);   // serialize items to file
	virtual void PreCloseFrame(CFrameWnd* pFrame);
	virtual BOOL SaveModified();
	virtual void OnIdle();

	// compound file implementation
	virtual BOOL OnNewDocument();
	virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
	virtual BOOL OnSaveDocument(LPCTSTR lpszPathName);
	virtual void OnCloseDocument();
	void CommitItems(BOOL bSuccess);    // called during File.Save & File.Save As

	// minimal linking protocol
	virtual LPMONIKER GetMoniker(OLEGETMONIKER nAssign);
	virtual LPOLEITEMCONTAINER GetContainer();

protected:
	// document state implementation
	UINT m_dwNextItemNumber;// serial number for next item in this document
	BOOL m_bLastVisible;    // TRUE if one or more views was last visible

	// 'docfile' support
	BOOL m_bCompoundFile;   // TRUE if use compound files
	LPSTORAGE m_lpRootStg;  // root storage for the document
	BOOL m_bSameAsLoad;     // TRUE = file-save, FALSE = Save [Copy] As
	BOOL m_bRemember;       // if FALSE, indicates Save Copy As

	DVTARGETDEVICE* m_ptd;  // current document target device

	// implementation helpers
	virtual void LoadFromStorage();
	virtual void SaveToStorage(CObject* pObject = NULL);
	CDocItem* GetNextItemOfKind(POSITION& pos, CRuntimeClass* pClass) const;

	// command handling

#if _MFC_VER >= 0x600
public:
#endif

	virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra,
		AFX_CMDHANDLERINFO* pHandlerInfo);

#if _MFC_VER >= 0x600
protected:
#endif
	afx_msg void OnUpdatePasteMenu(CCmdUI* pCmdUI);
	afx_msg void OnUpdatePasteLinkMenu(CCmdUI* pCmdUI);
	afx_msg void OnUpdateEditLinksMenu(CCmdUI* pCmdUI);
	afx_msg void OnEditLinks();
	afx_msg void OnEditConvert();
	afx_msg void OnUpdateEditChangeIcon(CCmdUI* pCmdUI);
	afx_msg void OnEditChangeIcon();
	afx_msg void OnUpdateObjectVerbMenu(CCmdUI* pCmdUI);
	afx_msg void OnFileSendMail();

	friend class COleClientItem;
	friend class COleServerItem;
};

/////////////////////////////////////////////////////////////////////////////
// COleClientItem - Supports OLE2 non-inplace editing.
//      implements IOleClientSite, IAdviseSink, and IOleInPlaceSite

class COleFrameHook;    // forward reference (see ..\src\oleimpl2.h)

class COleClientItem : public CDocItem
{
	DECLARE_DYNAMIC(COleClientItem)

// Constructors
public:
	COleClientItem(COleDocument* pContainerDoc = NULL);

	// create from the clipboard
	BOOL CreateFromClipboard(OLERENDER render = OLERENDER_DRAW,
		CLIPFORMAT cfFormat = 0, LPFORMATETC lpFormatEtc = NULL);
	BOOL CreateLinkFromClipboard(OLERENDER render = OLERENDER_DRAW,
		CLIPFORMAT cfFormat = 0, LPFORMATETC lpFormatEtc = NULL);
	BOOL CreateStaticFromClipboard(OLERENDER render = OLERENDER_DRAW,
		CLIPFORMAT cfFormat = 0, LPFORMATETC lpFormatEtc = NULL);

	// create from a class ID (Insert New Object dialog)
	BOOL CreateNewItem(REFCLSID clsid, OLERENDER render = OLERENDER_DRAW,
		CLIPFORMAT cfFormat = 0, LPFORMATETC lpFormatEtc = NULL);

	// create from COleDataObject
	BOOL CreateFromData(COleDataObject* pDataObject,
		OLERENDER render = OLERENDER_DRAW,
		CLIPFORMAT cfFormat = 0, LPFORMATETC lpFormatEtc = NULL);
	BOOL CreateLinkFromData(COleDataObject* pDataObject,
		OLERENDER render = OLERENDER_DRAW,
		CLIPFORMAT cfFormat = 0, LPFORMATETC lpFormatEtc = NULL);
	BOOL CreateStaticFromData(COleDataObject* pDataObject,
		OLERENDER render = OLERENDER_DRAW,
		CLIPFORMAT cfFormat = 0, LPFORMATETC lpFormatEtc = NULL);

	// create from file (package support)
	BOOL CreateFromFile(LPCTSTR lpszFileName, REFCLSID clsid = CLSID_NULL,
		OLERENDER render = OLERENDER_DRAW,
		CLIPFORMAT cfFormat = 0, LPFORMATETC lpFormatEtc = NULL);
	BOOL CreateLinkFromFile(LPCTSTR lpszFileName,
		OLERENDER render = OLERENDER_DRAW,
		CLIPFORMAT cfFormat = 0, LPFORMATETC lpFormatEtc = NULL);

	// create a copy
	BOOL CreateCloneFrom(const COleClientItem* pSrcItem);

// General Attributes
public:
#if _MFC_VER >= 0x0600
	HICON GetIconFromRegistry() const;
	static HICON GetIconFromRegistry(CLSID& clsid);
#endif
	SCODE GetLastStatus() const;
	OLE_OBJTYPE GetType() const; // OT_LINK, OT_EMBEDDED, OT_STATIC
	void GetClassID(CLSID* pClassID) const;
	void GetUserType(USERCLASSTYPE nUserClassType, CString& rString);
	BOOL GetExtent(LPSIZE lpSize, DVASPECT nDrawAspect = (DVASPECT)-1);
		// will return FALSE if item is BLANK
	BOOL GetCachedExtent(LPSIZE lpSize, DVASPECT nDrawAspect = (DVASPECT)-1);

	// getting/setting iconic cache
	HGLOBAL GetIconicMetafile();
	BOOL SetIconicMetafile(HGLOBAL hMetaPict);

	// setting/getting default display aspect
	DVASPECT GetDrawAspect() const;
	virtual void SetDrawAspect(DVASPECT nDrawAspect);

	// for printer presentation cache
	BOOL SetPrintDevice(const DVTARGETDEVICE* ptd);
	BOOL SetPrintDevice(const PRINTDLG* ppd);

	// Item state
	enum ItemState
		{ emptyState, loadedState, openState, activeState, activeUIState };
	UINT GetItemState() const;

	BOOL IsModified() const;
	BOOL IsRunning() const;
	BOOL IsInPlaceActive() const;
	BOOL IsOpen() const;
	CView* GetActiveView() const;

	// Data access
	void AttachDataObject(COleDataObject& rDataObject) const;

	// other rare access information
	COleDocument* GetDocument() const; // return container

	// helpers for checking clipboard data availability
	static BOOL PASCAL CanPaste();
	static BOOL PASCAL CanPasteLink();

	// helpers for checking COleDataObject, useful in drag drop
	static BOOL PASCAL CanCreateFromData(const COleDataObject* pDataObject);
	static BOOL PASCAL CanCreateLinkFromData(const COleDataObject* pDataObject);

// General Operations
	virtual void Release(OLECLOSE dwCloseOption = OLECLOSE_NOSAVE);
		// cleanup, detach (close if needed)
	void Close(OLECLOSE dwCloseOption = OLECLOSE_SAVEIFDIRTY);
		// close without releasing the item
	void Delete(BOOL bAutoDelete = TRUE);
		// logically delete from file -- not part of the document anymore
	void Run(); // insure item is in running state

	// Drawing
	BOOL Draw(CDC* pDC, LPCRECT lpBounds,
		DVASPECT nDrawAspect = (DVASPECT)-1);   // defaults to m_nDrawAspect

	// Activation
	virtual BOOL DoVerb(LONG nVerb, CView* pView, LPMSG lpMsg = NULL);
	void Activate(LONG nVerb, CView* pView, LPMSG lpMsg = NULL);

	// In-place Activation
	void Deactivate();          // completely deactivate
	void DeactivateUI();        // deactivate the user interface
	BOOL ReactivateAndUndo();   // reactivate then perform undo command
	BOOL SetItemRects(LPCRECT lpPosRect = NULL, LPCRECT lpClipRect = NULL);
	CWnd* GetInPlaceWindow();

	// Clipboard operations
	void CopyToClipboard(BOOL bIncludeLink = FALSE);
	DROPEFFECT DoDragDrop(LPCRECT lpItemRect, CPoint ptOffset,
		BOOL bIncludeLink = FALSE,
		DWORD dwEffects = DROPEFFECT_COPY|DROPEFFECT_MOVE,
		LPCRECT lpRectStartDrag = NULL);
	void GetClipboardData(COleDataSource* pDataSource,
		BOOL bIncludeLink = FALSE, LPPOINT lpOffset = NULL,
		LPSIZE lpSize = NULL);

	// called for creating a COleDataSource by CopyToClipboard and DoDragDrop
	virtual COleDataSource* OnGetClipboardData(BOOL bIncludeLink,
		LPPOINT lpOffset, LPSIZE lpSize);

	// Operations that apply to embedded items only
	void SetHostNames(LPCTSTR lpszHost, LPCTSTR lpszHostObj);
	void SetExtent(const CSize& size, DVASPECT nDrawAspect = DVASPECT_CONTENT);

	// Operations that apply to linked items only
	//  (link options are rarely changed, except through Links dialog)
	OLEUPDATE GetLinkUpdateOptions();
	void SetLinkUpdateOptions(OLEUPDATE dwUpdateOpt);

	// Link-source update status (also useful for embeddings that contain links)
	BOOL UpdateLink();  // make up-to-date
	BOOL IsLinkUpToDate() const;    // is link up-to-date

	// object conversion
	virtual BOOL ConvertTo(REFCLSID clsidNew);
	virtual BOOL ActivateAs(LPCTSTR lpszUserType, REFCLSID clsidOld, REFCLSID clsidNew);
	BOOL Reload();  // for lazy reload after ActivateAs

// Overridables (notifications of IAdviseSink, IOleClientSite and IOleInPlaceSite)
	// Callbacks/notifications from the server you must/should implement
	virtual void OnChange(OLE_NOTIFICATION nCode, DWORD dwParam);
		// implement OnChange to invalidate when item changes

protected:
	virtual void OnGetItemPosition(CRect& rPosition);
		// implement OnGetItemPosition if you support in-place activation

	// Common overrides for in-place activation
	virtual BOOL OnScrollBy(CSize sizeExtent);

	// Common overrides for applications supporting undo
	virtual void OnDiscardUndoState();
	virtual void OnDeactivateAndUndo();

public:
	virtual void OnDeactivateUI(BOOL bUndoable);

protected:
	// Common overrides for applications supporting links to embeddings
	virtual void OnShowItem();

	// Advanced overrides for in-place activation
	virtual void OnGetClipRect(CRect& rClipRect);
	virtual BOOL CanActivate();

public:
	virtual void OnActivate();
	virtual void OnActivateUI();
	virtual void OnDeactivate();

protected:
	virtual BOOL OnGetWindowContext(CFrameWnd** ppMainFrame,
		CFrameWnd** ppDocFrame, LPOLEINPLACEFRAMEINFO lpFrameInfo);
	virtual BOOL OnChangeItemPosition(const CRect& rectPos);
		// default calls SetItemRects and caches the pos rect

public:
	// Advanced overrides for menu/title handling (rarely overridden)
	virtual void OnInsertMenus(CMenu* pMenuShared,
		LPOLEMENUGROUPWIDTHS lpMenuWidths);
	virtual void OnSetMenu(CMenu* pMenuShared, HOLEMENU holemenu,
		HWND hwndActiveObject);
	virtual void OnRemoveMenus(CMenu* pMenuShared);
	virtual BOOL OnUpdateFrameTitle();

	// Advanced override for control bar handling
	virtual BOOL OnShowControlBars(CFrameWnd* pFrameWnd, BOOL bShow);

// Implementation
public:
	// data to support non-inplace activated items
	LPOLEOBJECT m_lpObject; // in case you want direct access to the OLE object
	LPVIEWOBJECT2 m_lpViewObject;// IViewObject for IOleObject above
	DWORD m_dwItemNumber;   // serial number for this item in this document
	DVASPECT m_nDrawAspect; // current default display aspect
	SCODE m_scLast;         // last error code encountered
	LPSTORAGE m_lpStorage;  // provides storage for m_lpObject
	LPLOCKBYTES m_lpLockBytes;  // part of implementation of m_lpStorage
	DWORD m_dwConnection;   // advise connection to the m_lpObject
	BYTE m_bLinkUnavail;    // TRUE if link is currently unavailable
	BYTE m_bMoniker;        // TRUE if moniker is assigned
	BYTE m_bLocked;         // TRUE if object has external lock
	BYTE m_bNeedCommit;     // TRUE if need CommitItem
	BYTE m_bClosing;        // TRUE if currently doing COleClientItem::Close
	BYTE m_bReserved[3];    // (reserved for future use)

	// for compound file support
	LPSTORAGE m_lpNewStorage;   // used during Save As situations

	// item state & item type
	ItemState m_nItemState; // item state (see ItemState enumeration)
	OLE_OBJTYPE m_nItemType;    // item type (depends on how created)

	// data valid when in-place activated
	CView* m_pView; // view when object is in-place activated
	DWORD m_dwContainerStyle;   // style of the container wnd before activation
	COleFrameHook* m_pInPlaceFrame;// frame window when in-place active
	COleFrameHook* m_pInPlaceDoc;   // doc window when in-place (may be NULL)
	HWND m_hWndServer;  // HWND of in-place server window

public:
	virtual ~COleClientItem();
	virtual void Serialize(CArchive& ar);
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

// Implementation
public:
	virtual BOOL ReportError(SCODE sc) const;
	virtual BOOL FreezeLink();  // converts to static: for edit links dialog

	DWORD GetNewItemNumber();   // generates new item number
	void GetItemName(LPTSTR lpszItemName) const; // gets readable item name

	void UpdateItemType();  // update m_nItemType

protected:
	// clipboard helpers
	void GetEmbeddedItemData(LPSTGMEDIUM lpStgMedium);
	void AddCachedData(COleDataSource* pDataSource);
	BOOL GetLinkSourceData(LPSTGMEDIUM lpStgMedium);
	void GetObjectDescriptorData(LPPOINT lpOffset, LPSIZE lpSize,
		LPSTGMEDIUM lpStgMedium);

	// interface helpers
	virtual LPOLECLIENTSITE GetClientSite();

	// helpers for printer-cached representation
	BOOL GetPrintDeviceInfo(LPOLECACHE* plpOleCache,
		DVTARGETDEVICE** pptd, DWORD* pdwConnection);

// Advanced Overridables for implementation
protected:
	virtual BOOL FinishCreate(SCODE sc);
	virtual void CheckGeneral(SCODE sc);

	virtual void OnDataChange(LPFORMATETC lpFormatEtc,
		LPSTGMEDIUM lpStgMedium);

public:
	// for storage hookability (override to use 'docfiles')
	virtual void GetItemStorage();  // allocate storage for new item
	virtual void ReadItem(CArchive& ar);    // read item from archive
	virtual void WriteItem(CArchive& ar);   // write item to archive
	virtual void CommitItem(BOOL bSuccess); // commit item's storage

	// compound & flat file implementations of above
	void GetItemStorageFlat();
	void ReadItemFlat(CArchive& ar);
	void WriteItemFlat(CArchive& ar);
	void GetItemStorageCompound();
	void ReadItemCompound(CArchive& ar);
	void WriteItemCompound(CArchive& ar);

// Interface Maps
public:
	BEGIN_INTERFACE_PART(OleClientSite, IOleClientSite)
		INIT_INTERFACE_PART(COleClientItem, OleClientSite)
		STDMETHOD(SaveObject)();
		STDMETHOD(GetMoniker)(DWORD, DWORD, LPMONIKER*);
		STDMETHOD(GetContainer)(LPOLECONTAINER*);
		STDMETHOD(ShowObject)();
		STDMETHOD(OnShowWindow)(BOOL);
		STDMETHOD(RequestNewObjectLayout)();
	END_INTERFACE_PART(OleClientSite)

	BEGIN_INTERFACE_PART(AdviseSink, IAdviseSink)
		INIT_INTERFACE_PART(COleClientItem, AdviseSink)
		STDMETHOD_(void,OnDataChange)(LPFORMATETC, LPSTGMEDIUM);
		STDMETHOD_(void,OnViewChange)(DWORD, LONG);
		STDMETHOD_(void,OnRename)(LPMONIKER);
		STDMETHOD_(void,OnSave)();
		STDMETHOD_(void,OnClose)();
	END_INTERFACE_PART(AdviseSink)

	BEGIN_INTERFACE_PART(OleIPSite, IOleInPlaceSite)
		INIT_INTERFACE_PART(COleClientItem, OleIPSite)
		STDMETHOD(GetWindow)(HWND*);
		STDMETHOD(ContextSensitiveHelp)(BOOL);
		STDMETHOD(CanInPlaceActivate)();
		STDMETHOD(OnInPlaceActivate)();
		STDMETHOD(OnUIActivate)();
		STDMETHOD(GetWindowContext)(LPOLEINPLACEFRAME*,
			LPOLEINPLACEUIWINDOW*, LPRECT, LPRECT, LPOLEINPLACEFRAMEINFO);
		STDMETHOD(Scroll)(SIZE);
		STDMETHOD(OnUIDeactivate)(BOOL);
		STDMETHOD(OnInPlaceDeactivate)();
		STDMETHOD(DiscardUndoState)();
		STDMETHOD(DeactivateAndUndo)();
		STDMETHOD(OnPosRectChange)(LPCRECT);
	END_INTERFACE_PART(OleIPSite)

	DECLARE_INTERFACE_MAP()

// Friendship declarations (to avoid many public members)
	friend class COleUIWindow;
	friend class COleFrameWindow;
	friend class COleLinkingDoc;
};

#if _MFC_VER >= 0x0600
class COleDocObjectItem : public COleClientItem
{
	friend class COleFrameHook;
	DECLARE_DYNAMIC(COleDocObjectItem)

// Constructors
public:
	COleDocObjectItem(COleDocument* pContainerDoc = NULL);

//Overridables
public:
	LPOLEDOCUMENTVIEW GetActiveView() const;
	virtual void Release(OLECLOSE dwCloseOption = OLECLOSE_NOSAVE);
	virtual void OnInsertMenus(CMenu* pMenuShared,
		LPOLEMENUGROUPWIDTHS lpMenuWidths);
	virtual void OnRemoveMenus(CMenu *pMenuShared);

// Operations
public:
	static BOOL OnPreparePrinting(CView* pCaller, CPrintInfo* pInfo,
		BOOL bPrintAll = TRUE);
	static void OnPrint(CView* pCaller, CPrintInfo* pInfo,
		BOOL bPrintAll = TRUE);
	BOOL GetPageCount(LPLONG pnFirstPage, LPLONG pcPages);
	HRESULT ExecCommand(DWORD nCmdID,
		DWORD nCmdExecOpt = OLECMDEXECOPT_DONTPROMPTUSER,
		const GUID* pguidCmdGroup = NULL);

// Implementation
public:
	virtual ~COleDocObjectItem();
	CMenu* m_pHelpPopupMenu;

protected:
	virtual void OnGetItemPosition(CRect& rPosition);
	virtual CMenu* GetHelpMenu(UINT& nPosition);
	void ActivateAndShow();
	LPOLEDOCUMENTVIEW m_pActiveView;
	LPPRINT m_pIPrint;
	BOOL SupportsIPrint();
	BOOL m_bInHelpMenu;

	BEGIN_INTERFACE_PART(OleDocumentSite, IOleDocumentSite)
		INIT_INTERFACE_PART(COleDocObjectItem, OleDocumentSite)
		STDMETHOD(ActivateMe)(LPOLEDOCUMENTVIEW pViewToActivate);
	END_INTERFACE_PART(OleDocumentSite)

	DECLARE_INTERFACE_MAP()
};
#endif

/////////////////////////////////////////////////////////////////////////////
// COleServerItem - IOleObject & IDataObject OLE component

#ifdef _AFXDLL
class COleServerItem : public CDocItem
#else
class AFX_NOVTABLE COleServerItem : public CDocItem
#endif
{
	DECLARE_DYNAMIC(COleServerItem)
protected:
	// NOTE: many members in this class are protected - since everything
	//   in this class is designed for implementing an OLE server.
	// Requests will come from OLE containers through non-C++ mechanisms,
	//   which will result in virtual functions in this class being called.

// Constructors
	COleServerItem(COleServerDoc* pServerDoc, BOOL bAutoDelete);
		// If your COleServerItem is an integral part of your data,
		//  bAutoDelete should be FALSE.  If your COleServerItem can be
		//  deleted when a link is released, it can be TRUE.

	COleDataSource* GetDataSource();
		// Use this data source to add conversion formats that your
		//  server should support.  Usually such formats are
		//  added in the item's constructor.

// Public Attributes
public:
	COleServerDoc* GetDocument() const; // return server document

	// naming (for links only)
	const CString& GetItemName() const; // get name of linked item
	void SetItemName(LPCTSTR lpszItemName);  // set name of linked item

	// link state
	BOOL IsConnected() const;   // returns TRUE if item has a client
	BOOL IsLinkedItem() const;  // returns TRUE if item is not embedded item

	// extents
	CSize m_sizeExtent;
		// HIMETRIC size -- the default implementation of OnSetExtent
		//  updates this member variable.  This member tells the server how
		//  much of the object is visible in the container document.

// Operations
public:
	void NotifyChanged(DVASPECT nDrawAspect = DVASPECT_CONTENT);
		// call this after you change item
	void CopyToClipboard(BOOL bIncludeLink = FALSE);
		// helper for implementing server 'copy to clipboard'
	DROPEFFECT DoDragDrop(LPCRECT lpRectItem, CPoint ptOffset,
		BOOL bIncludeLink = FALSE,
		DWORD dwEffects = DROPEFFECT_COPY|DROPEFFECT_MOVE,
		LPCRECT lpRectStartDrag = NULL);
	void GetClipboardData(COleDataSource* pDataSource,
		BOOL bIncludeLink = FALSE, LPPOINT lpOffset = NULL,
		LPSIZE lpSize = NULL);

// Overridables
	// overridables you must implement for yourself
	virtual BOOL OnDraw(CDC* pDC, CSize& rSize) = 0;
		// drawing for metafile format (return FALSE if not supported or error)
		//  (called for DVASPECT_CONTENT only)

	// overridables you may want to implement yourself
	virtual void OnUpdate(COleServerItem* pSender,
		LPARAM lHint, CObject* pHint, DVASPECT nDrawAspect);
		// the default implementation always calls NotifyChanged

	virtual BOOL OnDrawEx(CDC* pDC, DVASPECT nDrawAspect, CSize& rSize);
		// advanced drawing -- called for DVASPECT other than DVASPECT_CONTENT
	virtual BOOL OnSetExtent(DVASPECT nDrawAspect, const CSize& size);
	virtual BOOL OnGetExtent(DVASPECT nDrawAspect, CSize& rSize);
		// default implementation uses m_sizeExtent

	// overridables you do not have to implement
	virtual void OnDoVerb(LONG iVerb);
		// default routes to OnShow &/or OnOpen
	virtual BOOL OnSetColorScheme(const LOGPALETTE* lpLogPalette);
		// default does nothing
	virtual COleDataSource* OnGetClipboardData(BOOL bIncludeLink,
		LPPOINT lpOffset, LPSIZE lpSize);
		// called for access to clipboard data
	virtual BOOL OnQueryUpdateItems();
		// called to determine if there are any contained out-of-date links
	virtual void OnUpdateItems();
		// called to update any out-of-date links

protected:
	virtual void OnShow();
		// show item in the user interface (may edit in-place)
	virtual void OnOpen();
		// show item in the user interface (must open fully)
	virtual void OnHide();
		// hide document (and sometimes application)

	// very advanced overridables
public:
	virtual BOOL OnInitFromData(COleDataObject* pDataObject, BOOL bCreation);
		// initialize object from IDataObject

	// see COleDataSource for a description of these overridables
	virtual BOOL OnRenderGlobalData(LPFORMATETC lpFormatEtc, HGLOBAL* phGlobal);
	virtual BOOL OnRenderFileData(LPFORMATETC lpFormatEtc, CFile* pFile);
	virtual BOOL OnRenderData(LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium);
		// HGLOBAL version will be called first, then CFile* version

	virtual BOOL OnSetData(LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium,
		BOOL bRelease);
		// Rare -- only if you support SetData (programmatic paste)

	// advanced helpers for CopyToClipboard
	void GetEmbedSourceData(LPSTGMEDIUM lpStgMedium);
	void AddOtherClipboardData(COleDataSource* pDataSource);
	BOOL GetLinkSourceData(LPSTGMEDIUM lpStgMedium);
	void GetObjectDescriptorData(LPPOINT lpOffset, LPSIZE lpSize,
		LPSTGMEDIUM lpStgMedium);

// Implementation
public:
	BOOL m_bNeedUnlock;             // if TRUE need to pDoc->LockExternal(FALSE)
	BOOL m_bAutoDelete;             // if TRUE will OnRelease will 'delete this'

	// special version of OnFinalRelease to implement document locking
	virtual void OnFinalRelease();

protected:
	CString m_strItemName;          // simple item name

public:
	LPOLEADVISEHOLDER m_lpOleAdviseHolder;  // may be NULL
	LPDATAADVISEHOLDER m_lpDataAdviseHolder;    // may be NULL

	virtual ~COleServerItem();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

	// implementation helpers
	void NotifyClient(OLE_NOTIFICATION wNotification, DWORD_PTR dwParam);
	LPDATAOBJECT GetDataObject();
	LPOLEOBJECT GetOleObject();
	LPMONIKER GetMoniker(OLEGETMONIKER nAssign);

protected:
	virtual BOOL GetMetafileData(LPFORMATETC lpFormatEtc, LPSTGMEDIUM pmedium);
		// calls OnDraw or OnDrawEx
	virtual void OnSaveEmbedding(LPSTORAGE lpStorage);
	virtual BOOL IsBlank() const;

	// CItemDataSource implements OnRender reflections to COleServerItem
	class CItemDataSource : public COleDataSource
	{
	protected:
		// the GetData and SetData interfaces forward to m_pItem
		virtual BOOL OnRenderGlobalData(LPFORMATETC lpFormatEtc, HGLOBAL* phGlobal);
		virtual BOOL OnRenderFileData(LPFORMATETC lpFormatEtc, CFile* pFile);
		virtual BOOL OnRenderData(LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium);
			// HGLOBAL version will be called first, then CFile* version

		virtual BOOL OnSetData(LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium,
			BOOL bRelease);
	};
	CItemDataSource m_dataSource;
		// data source used to implement IDataObject

// Interface Maps
//  (Note: these interface maps are used just for link implementation)
public:
	BEGIN_INTERFACE_PART(OleObject, IOleObject)
		INIT_INTERFACE_PART(COleServerItem, OleObject)
		STDMETHOD(SetClientSite)(LPOLECLIENTSITE);
		STDMETHOD(GetClientSite)(LPOLECLIENTSITE*);
		STDMETHOD(SetHostNames)(LPCOLESTR, LPCOLESTR);
		STDMETHOD(Close)(DWORD);
		STDMETHOD(SetMoniker)(DWORD, LPMONIKER);
		STDMETHOD(GetMoniker)(DWORD, DWORD, LPMONIKER*);
		STDMETHOD(InitFromData)(LPDATAOBJECT, BOOL, DWORD);
		STDMETHOD(GetClipboardData)(DWORD, LPDATAOBJECT*);
		STDMETHOD(DoVerb)(LONG, LPMSG, LPOLECLIENTSITE, LONG, HWND, LPCRECT);
		STDMETHOD(EnumVerbs)(LPENUMOLEVERB*);
		STDMETHOD(Update)();
		STDMETHOD(IsUpToDate)();
		STDMETHOD(GetUserClassID)(LPCLSID);
		STDMETHOD(GetUserType)(DWORD, LPOLESTR*);
		STDMETHOD(SetExtent)(DWORD, LPSIZEL);
		STDMETHOD(GetExtent)(DWORD, LPSIZEL);
		STDMETHOD(Advise)(LPADVISESINK, LPDWORD);
		STDMETHOD(Unadvise)(DWORD);
		STDMETHOD(EnumAdvise)(LPENUMSTATDATA*);
		STDMETHOD(GetMiscStatus)(DWORD, LPDWORD);
		STDMETHOD(SetColorScheme)(LPLOGPALETTE);
	END_INTERFACE_PART(OleObject)

	BEGIN_INTERFACE_PART(DataObject, IDataObject)
		INIT_INTERFACE_PART(COleServerItem, DataObject)
		STDMETHOD(GetData)(LPFORMATETC, LPSTGMEDIUM);
		STDMETHOD(GetDataHere)(LPFORMATETC, LPSTGMEDIUM);
		STDMETHOD(QueryGetData)(LPFORMATETC);
		STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC, LPFORMATETC);
		STDMETHOD(SetData)(LPFORMATETC, LPSTGMEDIUM, BOOL);
		STDMETHOD(EnumFormatEtc)(DWORD, LPENUMFORMATETC*);
		STDMETHOD(DAdvise)(LPFORMATETC, DWORD, LPADVISESINK, LPDWORD);
		STDMETHOD(DUnadvise)(DWORD);
		STDMETHOD(EnumDAdvise)(LPENUMSTATDATA*);
	END_INTERFACE_PART(DataObject)

	DECLARE_INTERFACE_MAP()

	friend class CItemDataSource;
	friend class COleServerDoc;
	friend class COleLinkingDoc;
};

/////////////////////////////////////////////////////////////////////////////
// COleLinkingDoc -
//  (enables linking to embeddings - beginnings of server fuctionality)

class COleLinkingDoc : public COleDocument
{
	DECLARE_DYNAMIC(COleLinkingDoc)

// Constructors
public:
	COleLinkingDoc();

// Operations
	BOOL Register(COleObjectFactory* pFactory, LPCTSTR lpszPathName);
		// notify the running object table and connect to pServer
	void Revoke();
		// revoke from running object table

// Overridables
protected:
	virtual COleServerItem* OnGetLinkedItem(LPCTSTR lpszItemName);
		// return item for the named linked item (for supporting links)
	virtual COleClientItem* OnFindEmbeddedItem(LPCTSTR lpszItemName);
		// return item for the named embedded item (for links to embeddings)

// Implementation
public:
	COleObjectFactory* m_pFactory;  // back-pointer to server

#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif
	virtual ~COleLinkingDoc();

	// overrides for updating of monikers & running object table registration
	virtual BOOL OnNewDocument();
	virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
	virtual BOOL OnSaveDocument(LPCTSTR lpszPathName);
	virtual void OnCloseDocument();
	virtual LPOLEITEMCONTAINER GetContainer();
	virtual LPMONIKER GetMoniker(OLEGETMONIKER nAssign);

	// special handling of error messages during save/load
	virtual void ReportSaveLoadException(LPCTSTR lpszPathName,
		CException* e, BOOL bSaving, UINT nIDPDefault);
	void BeginDeferErrors();
	SCODE EndDeferErrors(SCODE sc);

protected:
	BOOL m_bDeferErrors;    // TRUE if in non-interactive OLE mode
	CException* m_pLastException;

	DWORD m_dwRegister;     // file moniker's registration in the ROT
	LPMONIKER m_lpMonikerROT; // file moniker that is registered
	CString m_strMoniker;   // filename used to create moniker
	BOOL m_bVisibleLock;    // TRUE if user is holding lock on document

	// implementation helpers
	virtual BOOL RegisterIfServerAttached(LPCTSTR lpszPathName, BOOL bMessage);
	void LockExternal(BOOL bLock, BOOL bRemoveRefs);
	void UpdateVisibleLock(BOOL bVisible, BOOL bRemoveRefs);
	virtual void OnShowViews(BOOL bVisible);

	virtual void SaveToStorage(CObject* pObject = NULL);

// Interface Maps
public:
	BEGIN_INTERFACE_PART(PersistFile, IPersistFile)
		INIT_INTERFACE_PART(COleLinkingDoc, PersistFile)
		STDMETHOD(GetClassID)(LPCLSID);
		STDMETHOD(IsDirty)();
		STDMETHOD(Load)(LPCOLESTR, DWORD);
		STDMETHOD(Save)(LPCOLESTR, BOOL);
		STDMETHOD(SaveCompleted)(LPCOLESTR);
		STDMETHOD(GetCurFile)(LPOLESTR*);
	END_INTERFACE_PART(PersistFile)

	BEGIN_INTERFACE_PART(OleItemContainer, IOleItemContainer)
		INIT_INTERFACE_PART(COleLinkingDoc, OleItemContainer)
		STDMETHOD(ParseDisplayName)(LPBC, LPOLESTR, ULONG*, LPMONIKER*);
		STDMETHOD(EnumObjects)(DWORD, LPENUMUNKNOWN*);
		STDMETHOD(LockContainer)(BOOL);
		STDMETHOD(GetObject)(LPOLESTR, DWORD, LPBINDCTX, REFIID, LPVOID*);
		STDMETHOD(GetObjectStorage)(LPOLESTR, LPBINDCTX, REFIID, LPVOID*);
		STDMETHOD(IsRunning)(LPOLESTR);
	END_INTERFACE_PART(OleItemContainer)

	DECLARE_INTERFACE_MAP()

	friend class COleClientItem;
	friend class COleClientItem::XOleClientSite;
	friend class COleServerItem::XOleObject;
};

//////////////////////////////////////////////////////////////////////////////
// COleServerDoc - registered server document containing COleServerItems

#ifdef _AFXDLL
class COleServerDoc : public COleLinkingDoc
#else
class AFX_NOVTABLE COleServerDoc : public COleLinkingDoc
#endif
{
	DECLARE_DYNAMIC(COleServerDoc)

// Constructors and Destructors
public:
	COleServerDoc();

// Attributes
	BOOL IsEmbedded() const;    // TRUE if document is an embedding
	BOOL IsDocObject() const;   // TRUE if document is a DocObject
	COleServerItem* GetEmbeddedItem();
		// return embedded item for document (will allocate if necessary)

	// attributes specific to in-place activation
	BOOL IsInPlaceActive() const;
	void GetItemPosition(LPRECT lpPosRect) const;
		// get current position rectangle of in-place edit
	void GetItemClipRect(LPRECT lpClipRect) const;
		// get current clipping rectangle of in-place edit
	BOOL GetZoomFactor(LPSIZE lpSizeNum = NULL, LPSIZE lpSizeDenom = NULL,
		LPCRECT lpPosRect = NULL) const;
		// returns the zoom factor in pixels

// Operations
	void NotifyChanged();
		// call this after you change some global attribute like
		//  document dimensions
	void UpdateAllItems(COleServerItem* pSender,
		LPARAM lHint = 0L, CObject* pHint = NULL,
		DVASPECT nDrawAspect = DVASPECT_CONTENT);

	// changes to the entire document (automatically notifies clients)
	void NotifyRename(LPCTSTR lpszNewName);
	void NotifySaved();
	void NotifyClosed();        // call this after you close document

	// specific operations for embedded documents
	void SaveEmbedding();       // call this to save embedded (before closing)

	// specific to in-place activation
	BOOL ActivateInPlace();
	void ActivateDocObject();
	void RequestPositionChange(LPCRECT lpPosRect);
	BOOL ScrollContainerBy(CSize sizeScroll);
	BOOL DeactivateAndUndo();
	BOOL DiscardUndoState();

public:
// Overridables for standard user interface (full server)
	virtual BOOL OnUpdateDocument(); // implementation of embedded update

protected:
// Overridables you must implement for yourself
	virtual COleServerItem* OnGetEmbeddedItem() = 0;
		// return item representing entire (embedded) document

// Overridables you do not have to implement
	virtual void OnClose(OLECLOSE dwCloseOption);
	virtual void OnSetHostNames(LPCTSTR lpszHost, LPCTSTR lpszHostObj);
	virtual HRESULT OnExecOleCmd(const GUID* pguidCmdGroup, DWORD nCmdID,
		DWORD nCmdExecOpt, VARIANTARG* pvarargIn, VARIANTARG* pvarargOut);
	virtual CDocObjectServer* GetDocObjectServer(LPOLEDOCUMENTSITE pDocSite);

// Advanced overridables
	LPUNKNOWN GetInterfaceHook(const void* piid);
	virtual void OnShowDocument(BOOL bShow);
		// show first frame for document or hide all frames for document

// Advanced overridables for in-place activation
public:
	virtual void OnDeactivate();
	virtual void OnDeactivateUI(BOOL bUndoable);

protected:
	virtual void OnSetItemRects(LPCRECT lpPosRect, LPCRECT lpClipRect);
	virtual BOOL OnReactivateAndUndo();

	virtual void OnFrameWindowActivate(BOOL bActivate);
	virtual void OnDocWindowActivate(BOOL bActivate);
	virtual void OnShowControlBars(CFrameWnd* pFrameWnd, BOOL bShow);
	virtual COleIPFrameWnd* CreateInPlaceFrame(CWnd* pParentWnd);
	virtual void DestroyInPlaceFrame(COleIPFrameWnd* pFrameWnd);
public:
	virtual void OnResizeBorder(LPCRECT lpRectBorder,
		LPOLEINPLACEUIWINDOW lpUIWindow, BOOL bFrame);

// Implementation
protected:
	LPOLECLIENTSITE m_lpClientSite;     // for embedded item
	CString m_strHostObj;               // name of document in container
	BOOL m_bCntrVisible;                // TRUE if OnShowWindow(TRUE) called
	BOOL m_bClosing;                    // TRUE if shutting down
	COleServerItem* m_pEmbeddedItem;    // pointer to embedded item for document

	COleIPFrameWnd* m_pInPlaceFrame;    // not NULL if in-place activated
	CWnd* m_pOrigParent;                // not NULL if existing view used
	DWORD m_dwOrigStyle;                // original style of in-place view
	DWORD m_dwOrigStyleEx;              // original extended style

	CDocObjectServer* m_pDocObjectServer;  // if DocObject, ptr to doc site

public:
	virtual ~COleServerDoc();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

	// overridables for implementation
	virtual BOOL OnSaveDocument(LPCTSTR lpszPathName);
	virtual void OnCloseDocument();
	virtual void DeleteContents(); // delete auto-delete server items
	virtual LPMONIKER GetMoniker(OLEGETMONIKER nAssign);
	virtual COleServerItem* OnGetLinkedItem(LPCTSTR lpszItemName);
		// return item for the named linked item (only if supporting links)
	virtual BOOL CanCloseFrame(CFrameWnd* pFrame);

protected:
	// overrides to handle server user-interface
	virtual BOOL SaveModified();        // return TRUE if ok to continue
	virtual HMENU GetDefaultMenu();     // return menu based on doc type
	virtual HACCEL GetDefaultAccelerator(); // return accel table based on doc type
	virtual BOOL GetFileTypeString(CString& rString);

	// IPersistStorage implementation
	virtual void OnNewEmbedding(LPSTORAGE lpStorage);
	virtual void OnOpenEmbedding(LPSTORAGE lpStorage);
	virtual void OnSaveEmbedding(LPSTORAGE lpStorage);

	// Implementation helpers
	void NotifyAllItems(OLE_NOTIFICATION wNotification, DWORD_PTR dwParam);
	BOOL SaveModifiedPrompt();
	void ConnectView(CWnd* pParentWnd, CView* pView);
	void UpdateUsingHostObj(UINT nIDS, CCmdUI* pCmdUI);

// Message Maps
	//{{AFX_MSG(COleServerDoc)
	afx_msg void OnFileUpdate();
	afx_msg void OnFileSaveCopyAs();
	afx_msg void OnUpdateFileUpdate(CCmdUI* pCmdUI);
	afx_msg void OnUpdateFileExit(CCmdUI* pCmdUI);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()

// Interface Maps
public:
	BEGIN_INTERFACE_PART(PersistStorage, IPersistStorage)
		INIT_INTERFACE_PART(COleServerDoc, PersistStorage)
		STDMETHOD(GetClassID)(LPCLSID);
		STDMETHOD(IsDirty)();
		STDMETHOD(InitNew)(LPSTORAGE);
		STDMETHOD(Load)(LPSTORAGE);
		STDMETHOD(Save)(LPSTORAGE, BOOL);
		STDMETHOD(SaveCompleted)(LPSTORAGE);
		STDMETHOD(HandsOffStorage)();
	END_INTERFACE_PART(PersistStorage)

	BEGIN_INTERFACE_PART(OleObject, IOleObject)
		INIT_INTERFACE_PART(COleServerDoc, OleObject)
		STDMETHOD(SetClientSite)(LPOLECLIENTSITE);
		STDMETHOD(GetClientSite)(LPOLECLIENTSITE*);
		STDMETHOD(SetHostNames)(LPCOLESTR, LPCOLESTR);
		STDMETHOD(Close)(DWORD);
		STDMETHOD(SetMoniker)(DWORD, LPMONIKER);
		STDMETHOD(GetMoniker)(DWORD, DWORD, LPMONIKER*);
		STDMETHOD(InitFromData)(LPDATAOBJECT, BOOL, DWORD);
		STDMETHOD(GetClipboardData)(DWORD, LPDATAOBJECT*);
		STDMETHOD(DoVerb)(LONG, LPMSG, LPOLECLIENTSITE, LONG, HWND, LPCRECT);
		STDMETHOD(EnumVerbs)(IEnumOLEVERB**);
		STDMETHOD(Update)();
		STDMETHOD(IsUpToDate)();
		STDMETHOD(GetUserClassID)(CLSID*);
		STDMETHOD(GetUserType)(DWORD, LPOLESTR*);
		STDMETHOD(SetExtent)(DWORD, LPSIZEL);
		STDMETHOD(GetExtent)(DWORD, LPSIZEL);
		STDMETHOD(Advise)(LPADVISESINK, LPDWORD);
		STDMETHOD(Unadvise)(DWORD);
		STDMETHOD(EnumAdvise)(LPENUMSTATDATA*);
		STDMETHOD(GetMiscStatus)(DWORD, LPDWORD);
		STDMETHOD(SetColorScheme)(LPLOGPALETTE);
	END_INTERFACE_PART(OleObject)

	BEGIN_INTERFACE_PART(DataObject, IDataObject)
		INIT_INTERFACE_PART(COleServerDoc, DataObject)
		STDMETHOD(GetData)(LPFORMATETC, LPSTGMEDIUM);
		STDMETHOD(GetDataHere)(LPFORMATETC, LPSTGMEDIUM);
		STDMETHOD(QueryGetData)(LPFORMATETC);
		STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC, LPFORMATETC);
		STDMETHOD(SetData)(LPFORMATETC, LPSTGMEDIUM, BOOL);
		STDMETHOD(EnumFormatEtc)(DWORD, LPENUMFORMATETC*);
		STDMETHOD(DAdvise)(LPFORMATETC, DWORD, LPADVISESINK, LPDWORD);
		STDMETHOD(DUnadvise)(DWORD);
		STDMETHOD(EnumDAdvise)(LPENUMSTATDATA*);
	END_INTERFACE_PART(DataObject)

	BEGIN_INTERFACE_PART(OleInPlaceObject, IOleInPlaceObject)
		INIT_INTERFACE_PART(COleServerDoc, OleInPlaceObject)
		STDMETHOD(GetWindow)(HWND*);
		STDMETHOD(ContextSensitiveHelp)(BOOL);
		STDMETHOD(InPlaceDeactivate)();
		STDMETHOD(UIDeactivate)();
		STDMETHOD(SetObjectRects)(LPCRECT, LPCRECT);
		STDMETHOD(ReactivateAndUndo)();
	END_INTERFACE_PART(OleInPlaceObject)

	BEGIN_INTERFACE_PART(OleInPlaceActiveObject, IOleInPlaceActiveObject)
		INIT_INTERFACE_PART(COleServerDoc, OleInPlaceActiveObject)
		STDMETHOD(GetWindow)(HWND*);
		STDMETHOD(ContextSensitiveHelp)(BOOL);
		STDMETHOD(TranslateAccelerator)(LPMSG);
		STDMETHOD(OnFrameWindowActivate)(BOOL);
		STDMETHOD(OnDocWindowActivate)(BOOL);
		STDMETHOD(ResizeBorder)(LPCRECT, LPOLEINPLACEUIWINDOW, BOOL);
		STDMETHOD(EnableModeless)(BOOL);
	END_INTERFACE_PART(OleInPlaceActiveObject)

	DECLARE_INTERFACE_MAP()

	friend class COleServer;
	friend class COleServerItem;
	friend class CDocObjectServer;
};

//////////////////////////////////////////////////////////////////////////////
// COleIPFrameWnd

class COleCntrFrameWnd;

class COleIPFrameWnd : public CFrameWnd
{
	DECLARE_DYNCREATE(COleIPFrameWnd)

// Constructors
public:
	COleIPFrameWnd();

// Overridables
public:
	virtual BOOL OnCreateControlBars(CWnd* pWndFrame, CWnd* pWndDoc);
		// create control bars on container windows (pWndDoc can be NULL)
	virtual BOOL OnCreateControlBars(CFrameWnd* pWndFrame, CFrameWnd* pWndDoc);
		// create control bars on container windows (pWndDoc can be NULL)

	virtual void RepositionFrame(LPCRECT lpPosRect, LPCRECT lpClipRect);
		// Advanced: reposition frame to wrap around new lpPosRect

// Implementation
public:
	BOOL m_bUIActive;   // TRUE if currently in uiacitve state

	virtual BOOL LoadFrame(UINT nIDResource,
		DWORD dwDefaultStyle = WS_CHILD|WS_BORDER|WS_CLIPSIBLINGS,
		CWnd* pParentWnd = NULL,
		CCreateContext* pContext = NULL);
	virtual void RecalcLayout(BOOL bNotify = TRUE);
	virtual BOOL PreTranslateMessage(MSG* pMsg);
	virtual LRESULT OnSetMessageString(WPARAM wParam, LPARAM lParam);
	virtual ~COleIPFrameWnd();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:
	// in-place state
	OLEINPLACEFRAMEINFO m_frameInfo;
	LPOLEINPLACEFRAME m_lpFrame;
	LPOLEINPLACEUIWINDOW m_lpDocFrame;
	COleCntrFrameWnd* m_pMainFrame;
	COleCntrFrameWnd* m_pDocFrame;

	HMENU m_hSharedMenu;
	OLEMENUGROUPWIDTHS m_menuWidths;
	HOLEMENU m_hOleMenu;
	CRect m_rectPos;            // client area rect of the item
	CRect m_rectClip;           // area to which frame should be clipped
	BOOL m_bInsideRecalc;

#if _MFC_VER >= 0x0600
	HMENU _m_Reserved;
#else
	HMENU m_hMenuHelpPopup;     // shared Help menu for DocObjects
#endif

	// Advanced: in-place activation virtual implementation
	virtual BOOL BuildSharedMenu();
	virtual void DestroySharedMenu();
	virtual HMENU GetInPlaceMenu();

	// Advanced: possible override to change in-place sizing behavior
	virtual void OnRequestPositionChange(LPCRECT lpRect);

protected:
	//{{AFX_MSG(COleIPFrameWnd)
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg LRESULT OnRecalcParent(WPARAM wParam, LPARAM lParam);
	afx_msg void OnIdleUpdateCmdUI();
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnDestroy();
	afx_msg LRESULT OnResizeChild(WPARAM wParam, LPARAM lParam);
	afx_msg void OnContextHelp();
	afx_msg void OnUpdateControlBarMenu(CCmdUI* pCmdUI);
	afx_msg BOOL OnBarCheck(UINT nID);
	afx_msg void OnWindowPosChanging(LPWINDOWPOS lpWndPos);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()

	friend class COleServerDoc;
	friend class COleCntrFrameWnd;
	friend class CDocObjectServer;
};

/////////////////////////////////////////////////////////////////////////////
// COleResizeBar - supports in-place resizing in server applications

class COleResizeBar : public CControlBar
{
	DECLARE_DYNAMIC(COleResizeBar)

// Constructors
public:
	COleResizeBar();
	BOOL Create(CWnd* pParentWnd, DWORD dwStyle = WS_CHILD | WS_VISIBLE,
		UINT nID = AFX_IDW_RESIZE_BAR);

// Implementation
public:
	virtual ~COleResizeBar();
	virtual void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);

protected:
	CRectTracker m_tracker;     // implemented with a tracker

protected:
	//{{AFX_MSG(COleResizeBar)
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
	afx_msg void OnPaint();
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
	afx_msg void OnLButtonDown(UINT, CPoint point);
	afx_msg LRESULT OnSizeParent(WPARAM wParam, LPARAM lParam);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////
// COleStreamFile - implementation of CFile which uses an IStream

class COleStreamFile : public CFile
{
	DECLARE_DYNAMIC(COleStreamFile)

// Constructors and Destructors
public:
	COleStreamFile(LPSTREAM lpStream = NULL);

// Operations
	// Note: OpenStream and CreateStream can accept eith STGM_ flags or
	//  CFile::OpenFlags bits since common values are guaranteed to have
	//  the same semantics.
	BOOL OpenStream(LPSTORAGE lpStorage, LPCTSTR lpszStreamName,
		DWORD nOpenFlags = modeReadWrite|shareExclusive,
		CFileException* pError = NULL);
	BOOL CreateStream(LPSTORAGE lpStorage, LPCTSTR lpszStreamName,
		DWORD nOpenFlags = modeReadWrite|shareExclusive|modeCreate,
		CFileException* pError = NULL);

	BOOL CreateMemoryStream(CFileException* pError = NULL);

	// attach & detach can be used when Open/Create functions aren't adequate
	void Attach(LPSTREAM lpStream);
	LPSTREAM Detach();

	IStream* GetStream() const;
	// Returns the current stream

// Implementation
public:
	LPSTREAM m_lpStream;
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif
	virtual ~COleStreamFile();

	// attributes for implementation
	BOOL GetStatus(CFileStatus& rStatus) const;
	virtual DWORD GetPosition() const;

	virtual const CString GetStorageName() const;

	// overrides for implementation
	virtual CFile* Duplicate() const;
	virtual LONG Seek(LONG lOff, UINT nFrom);
	virtual void SetLength(DWORD dwNewLen);
	virtual DWORD GetLength() const;
	virtual UINT Read(void* lpBuf, UINT nCount);
	virtual void Write(const void* lpBuf, UINT nCount);
	virtual void LockRange(DWORD dwPos, DWORD dwCount);
	virtual void UnlockRange(DWORD dwPos, DWORD dwCount);
	virtual void Abort();
	virtual void Flush();
	virtual void Close();

protected:
	CString m_strStorageName;
};

/////////////////////////////////////////////////////////////////////////////
// CMonikerFile - implementation of COleStreamFile that uses an IMoniker to
//                get the IStream

class CMonikerFile: public COleStreamFile
{
	DECLARE_DYNAMIC(CMonikerFile)

public:
	CMonikerFile();

	virtual BOOL Open(LPCTSTR lpszURL, CFileException* pError=NULL);
	// Uses synchronous URLMonikers to create a moniker.
	// Opens the URL specified.
	// If provided, pError will be set in case of error.
	// Return value: TRUE if successful, FALSE otherwise.

	virtual BOOL Open(IMoniker* pMoniker, CFileException* pError=NULL);
	// Binds to the provided moniker to obtain a stream.
	// If provided, pError will be set in case of error.
	// Return value: TRUE if successful, FALSE otherwise.

	virtual void Close();
	// Detaches the stream, Release()s it, and the moniker.  Close may be
	// called on unopened, or already closed streams.

	BOOL Detach(CFileException* pError = NULL);
	// Closes the stream.  If there is an error when closing, then the
	// error code will be placed in pError and the function will return FALSE.

	IMoniker* GetMoniker() const;
	// Returns the current moniker.  The moniker returned is not AddRef()'ed.

protected:
// Overidables
	IBindCtx* CreateBindContext(CFileException* pError);
	// A hook so users can provide a particular IBindCtx, potentially one
	// on which the user has registered one or more objects.

// Implementation
protected:
	virtual BOOL Open(LPCTSTR lpszUrl, IBindHost* pBindHost,
		IBindStatusCallback* pBSC, IBindCtx* pBindCtx, CFileException* pError);
	BOOL Attach(LPCTSTR lpszUrl, IBindHost* pBindHost,
		IBindStatusCallback* pBSC, IBindCtx* pBindCtx, CFileException* pError);
	virtual BOOL Open(IMoniker* pMoniker, IBindHost* pBindHost,
		IBindStatusCallback* pBSC, IBindCtx* pBindCtx, CFileException* pError);

	BOOL Attach(IMoniker* pMoniker, IBindHost* pBindHost,
		IBindStatusCallback* pBSC, IBindCtx* pBindCtx, CFileException* pError);

	virtual BOOL PostBindToStream(CFileException* pError);

	static IBindHost* CreateBindHost();
public:
	virtual ~CMonikerFile();
	// Closes the stream, and releases the moniker if needed.

	virtual void Flush();

#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
	// Calls COleStreamFile::Dump(), and prints out moniker value.
#endif

protected:
	IPTR(IMoniker) m_Moniker;
	// The moniker provided or created to which this class is bound.

	CMonikerFile(const CMonikerFile&);
	// Prevents copying.
};

/////////////////////////////////////////////////////////////////////////////
// CAsyncMonikerFile - implementation of COleStreamFile that uses an
//                     asynchronous IMoniker to get the IStream

class _AfxBindStatusCallback; // Forward declaration

class CAsyncMonikerFile: public CMonikerFile
{
	DECLARE_DYNAMIC(CAsyncMonikerFile)

public:
	CAsyncMonikerFile();
	// Creates the IBindStatusCallback used internally to provide asynchronous
	// operation.

	//All Open overloads call one of these two.
	virtual BOOL Open(LPCTSTR lpszURL, IBindHost* pBindHost,
		CFileException* pError=NULL);
	virtual BOOL Open(IMoniker* pMoniker, IBindHost* pBindHost,
		CFileException* pError=NULL);

	//Open overloads that take monikers
	virtual BOOL Open(IMoniker* pMoniker, CFileException* pError=NULL);
	virtual BOOL Open(IMoniker* pMoniker, IServiceProvider* pServiceProvider,
		CFileException* pError=NULL);
	virtual BOOL Open(IMoniker* pMoniker, IUnknown* pUnknown,
		CFileException* pError=NULL);

	//Open overloads that take strings
	virtual BOOL Open(LPCTSTR lpszURL, CFileException* pError=NULL);
	virtual BOOL Open(LPCTSTR lpszURL, IServiceProvider* pServiceProvider,
		CFileException* pError=NULL);
	virtual BOOL Open(LPCTSTR lpszURL, IUnknown* pUnknown,
		CFileException* pError=NULL);

	virtual void Close();

	IBinding* GetBinding() const;
	// Returns the binding provided when the asychronous transfer begins.
	// With the IBinding*, the user may abort, or pause the transfer.
	// NULL may be returned if for any reason the transfer could not be
	// made asynchronous, or if the IBinding* has not yet been provided by
	// the system.

	FORMATETC* GetFormatEtc() const;
	// Returns the FORMATETC for the currently opened stream.  NULL will be
	// returned if this is called from outside the context of OnDataAvailable.
	// If you want to keep the FORMATETC beyond this call, make a copy of it.
	// The FORMATETC indicates the format of the data in the stream.

protected:
// Overidables
	virtual IUnknown* CreateBindStatusCallback(IUnknown* pUnkControlling);

	virtual DWORD GetBindInfo() const;
	// Returns the settings returned by IBindStatusCallback::GetBindInfo.
	// The default values returned should work for most cases and should not
	// be changed lightly.

	virtual LONG GetPriority() const;
	// Returns the priority at which the asynchronous transfer will take
	// place.  The value is one of the standard thread priority flags.
	// By default THREAD_PRIORITY_NORMAL is returned.

	virtual void OnDataAvailable(DWORD dwSize, DWORD bscfFlag);
	// Called when there is data available to be read.  dwSize indicates
	// the cumulative number of bytes which can be read.  The bscfFlag may be used
	// to identify first, last, and intermediate blocks of data.

	virtual void OnLowResource();
	// This is called when resources are low.

	virtual void OnStartBinding();
	// Called when the binding is starting up.

	virtual void OnProgress(ULONG ulProgress, ULONG ulProgressMax,
		ULONG ulStatusCode, LPCTSTR szStatusText);

	virtual void OnStopBinding(HRESULT hresult, LPCTSTR szError);
	// Called when the transfer is stopped.  This function releases the
	// IBinding and should nearly always be call when overidden.

// Implementation
public:
	virtual ~CAsyncMonikerFile();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
	// Calls CMonikerFile::Dump(), and prints out IBinding,
	// IBindStatusCallback, and m_pFormatEtc values.
#endif
	virtual UINT Read(void* lpBuf, UINT nCount);

protected:
	friend class _AfxBindStatusCallback;
	_AfxBindStatusCallback* m_pAfxBSCCurrent;
	BOOL m_bStopBindingReceived;
	void EndCallbacks();

	IPTR(IBinding) m_Binding;
	FORMATETC* m_pFormatEtc;

	void SetBinding(IBinding* pBinding);
	// Sets and AddRefs m_Binding

	void SetFormatEtc(FORMATETC* pFormatEtc);
	// Sets the FORMATETC for the current stream.

	virtual BOOL PostBindToStream(CFileException* pError);
};

/////////////////////////////////////////////////////////////////////////////
// COleDropSource (advanced drop source support)

class COleDropSource : public CCmdTarget
{
// Constructors
public:
	COleDropSource();

// Overridables
	virtual SCODE QueryContinueDrag(BOOL bEscapePressed, DWORD dwKeyState);
	virtual SCODE GiveFeedback(DROPEFFECT dropEffect);
	virtual BOOL OnBeginDrag(CWnd* pWnd);

// Implementation
public:
#ifdef _DEBUG
	virtual void Dump(CDumpContext& dc) const;
#endif

public:
	BEGIN_INTERFACE_PART(DropSource, IDropSource)
		INIT_INTERFACE_PART(COleDropSource, DropSource)
		STDMETHOD(QueryContinueDrag)(BOOL, DWORD);
		STDMETHOD(GiveFeedback)(DWORD);
	END_INTERFACE_PART(DropSource)

	DECLARE_INTERFACE_MAP()

	CRect m_rectStartDrag;  // when mouse leaves this rect, drag drop starts
	BOOL m_bDragStarted;    // has drag really started yet?
	DWORD m_dwButtonCancel; // which button will cancel (going down)
	DWORD m_dwButtonDrop;   // which button will confirm (going up)

	// metrics for drag start determination
	static AFX_DATA UINT nDragMinDist;  // min. amount mouse must move for drag
	static AFX_DATA UINT nDragDelay;    // delay before drag starts

	friend class COleDataSource;
};

/////////////////////////////////////////////////////////////////////////////
// COleDropTarget (advanced drop target support)

class COleDropTarget : public CCmdTarget
{
// Constructors
public:
	COleDropTarget();

// Operations
	BOOL Register(CWnd* pWnd);
	virtual void Revoke();  // virtual for implementation

// Overridables
	virtual DROPEFFECT OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject,
		DWORD dwKeyState, CPoint point);
	virtual DROPEFFECT OnDragOver(CWnd* pWnd, COleDataObject* pDataObject,
		DWORD dwKeyState, CPoint point);
	virtual BOOL OnDrop(CWnd* pWnd, COleDataObject* pDataObject,
		DROPEFFECT dropEffect, CPoint point);
	virtual DROPEFFECT OnDropEx(CWnd* pWnd, COleDataObject* pDataObject,
		DROPEFFECT dropDefault, DROPEFFECT dropList, CPoint point);
	virtual void OnDragLeave(CWnd* pWnd);
	virtual DROPEFFECT OnDragScroll(CWnd* pWnd, DWORD dwKeyState,
		CPoint point);

// Implementation
public:
	virtual ~COleDropTarget();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:
	HWND m_hWnd;            // HWND this IDropTarget is attached to
	LPDATAOBJECT m_lpDataObject;    // != NULL between OnDragEnter, OnDragLeave
	UINT m_nTimerID;        // != MAKEWORD(-1, -1) when in scroll area
	DWORD m_dwLastTick;     // only valid when m_nTimerID valid
	UINT m_nScrollDelay;    // time to next scroll

	// metrics for drag-scrolling
	static AFX_DATA int nScrollInset;
	static AFX_DATA UINT nScrollDelay;
	static AFX_DATA UINT nScrollInterval;

	// implementation helpers
	void SetupTimer(CView* pView, UINT nTimerID);
	void CancelTimer(CWnd* pWnd);

// Interface Maps
public:
	BEGIN_INTERFACE_PART(DropTarget, IDropTarget)
		INIT_INTERFACE_PART(COleDropTarget, DropTarget)
		STDMETHOD(DragEnter)(LPDATAOBJECT, DWORD, POINTL, LPDWORD);
		STDMETHOD(DragOver)(DWORD, POINTL, LPDWORD);
		STDMETHOD(DragLeave)();
		STDMETHOD(Drop)(LPDATAOBJECT, DWORD, POINTL pt, LPDWORD);
	END_INTERFACE_PART(DropTarget)

	DECLARE_INTERFACE_MAP()
};

/////////////////////////////////////////////////////////////////////////////
// COleMessageFilter (implements IMessageFilter)

class COleMessageFilter : public CCmdTarget
{
// Constructors
public:
	COleMessageFilter();

// Operations
	BOOL Register();
	void Revoke();

	// for controlling the busy state of the server application (called app)
	virtual void BeginBusyState();
	virtual void EndBusyState();
	void SetBusyReply(SERVERCALL nBusyReply);

	// for controlling actions taken against rejected/retried calls
	void SetRetryReply(DWORD nRetryReply = 0);
		// only used when the "not responding" dialog is disabled
	void SetMessagePendingDelay(DWORD nTimeout = 5000);
		// used to determine amount of time before significant message
	void EnableBusyDialog(BOOL bEnableBusy = TRUE);
	void EnableNotRespondingDialog(BOOL bEnableNotResponding = TRUE);
		// used to enable/disable the two types of busy dialogs

// Overridables
	virtual BOOL OnMessagePending(const MSG* pMsg);
		// return TRUE to eat the message (usually only if processed)

// Implementation
public:
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif
	virtual ~COleMessageFilter();
	virtual BOOL IsSignificantMessage(MSG* pMsg);
		// determine if any significant messages are present in the queue
	virtual int OnBusyDialog(HTASK htaskBusy);
	virtual int OnNotRespondingDialog(HTASK htaskBusy);
		// these functions display the busy dialog

protected:
	BOOL m_bRegistered;
	LONG m_nBusyCount;  // for BeginBusyState & EndBusyState
	BOOL m_bEnableBusy;
	BOOL m_bEnableNotResponding;
	BOOL m_bUnblocking;
	DWORD m_nRetryReply;    // only used if m_bEnableNotResponding == FALSE
	DWORD m_nBusyReply;
	DWORD m_nTimeout;

// Interface Maps
public:
	BEGIN_INTERFACE_PART(MessageFilter, IMessageFilter)
		INIT_INTERFACE_PART(COleMessageFilter, MessageFilter)
		STDMETHOD_(DWORD, HandleInComingCall)(DWORD, HTASK, DWORD,
			LPINTERFACEINFO);
		STDMETHOD_(DWORD, RetryRejectedCall)(HTASK, DWORD, DWORD);
		STDMETHOD_(DWORD, MessagePending)(HTASK, DWORD, DWORD);
	END_INTERFACE_PART(MessageFilter)

	DECLARE_INTERFACE_MAP()
};

/////////////////////////////////////////////////////////////////////////////
// message map entries for OLE verbs

#define ON_STDOLEVERB(iVerb, memberFxn) \
	{ 0xC002, 0, (UINT)iVerb, (UINT)iVerb, (UINT)-1, \
		(AFX_PMSG)(BOOL (AFX_MSG_CALL CCmdTarget::*)(LPMSG, HWND, LPCRECT))&memberFxn },

#define ON_OLEVERB(idsVerbName, memberFxn) \
	{ 0xC002, 0, 1, 1, idsVerbName, \
		(AFX_PMSG)(BOOL (AFX_MSG_CALL CCmdTarget::*)(LPMSG, HWND, LPCRECT))&memberFxn },

/////////////////////////////////////////////////////////////////////////////
// global helpers and debugging

void AFXAPI AfxOleSetEditMenu(COleClientItem* pClient, CMenu* pMenu,
	UINT iMenuItem, UINT nIDVerbMin, UINT nIDVerbMax = 0, UINT nIDConvert = 0);

#ifdef _DEBUG
// Mapping SCODEs to readable text
LPCTSTR AFXAPI AfxGetFullScodeString(SCODE sc);
LPCTSTR AFXAPI AfxGetScodeString(SCODE sc);
LPCTSTR AFXAPI AfxGetScodeRangeString(SCODE sc);
LPCTSTR AFXAPI AfxGetSeverityString(SCODE sc);
LPCTSTR AFXAPI AfxGetFacilityString(SCODE sc);

// Mapping IIDs to readable text
LPCTSTR AFXAPI AfxGetIIDString(REFIID iid);
#endif

/////////////////////////////////////////////////////////////////////////////
// Inline function declarations

#ifdef _AFX_PACKING
#pragma pack(pop)
#endif

#ifdef _AFX_ENABLE_INLINES
#define _AFXOLE_INLINE AFX_INLINE
#define _AFXOLECLI_INLINE AFX_INLINE
#define _AFXOLESVR_INLINE AFX_INLINE
#define _AFXOLEDOBJ_INLINE AFX_INLINE
#define _AFXOLEMONIKER_INLINE AFX_INLINE
#include <afxole.inl>
#undef _AFXOLE_INLINE
#undef _AFXOLECLI_INLINE
#undef _AFXOLESVR_INLINE
#undef _AFXOLEDOBJ_INLINE
#undef _AFXOLEMONIKER_INLINE
#endif

#undef AFX_DATA
#define AFX_DATA

#ifdef _AFX_MINREBUILD
#pragma component(minrebuild, on)
#endif
#ifndef _AFX_FULLTYPEINFO
#pragma component(mintypeinfo, off)
#endif

#endif //__AFXOLE_H__

/////////////////////////////////////////////////////////////////////////////
