//+--------------------------------------------------------------------------- // // File: o2base.hxx // // Contents: Compound Document Object helper library definitions // // Classes: // OLEBorder // InPlaceBorder // StdClassFactory // ViewAdviseHolder // // --- // // StatusBar // Included only if INC_STATUS_BAR defined // // Functions: // HimetricFromHPix // HimetricFromVPix // HPixFromHimetric // VPixFromHimetric // // WatchInterface // // OleAllocMem // OleFreeMem // OleAllocString // OleFreeString // // IsCompatibleOleVersion // IsDraggingDistance // // TraceIID // TraceHRESULT // // RECTtoRECTL // RECTLtoRECT // ProportionateRectl // RectToScreen // RectToClient // IsRectInRect // lMulDiv // // LeadResourceData // GetChildWindowRect // SizeClientRect // // RegisterOleClipFormats // IsCompatibleDevice // IsCompatibleFormat // FindCompatibleFormat // GetObjectDescriptor // UpdateObjectDescriptor // DrawMetafile // // InsertServerMenus // RemoteServerMenus // // RegisterAsRunning // RevokeAsRunning // // CreateStreamOnFile // // CreateOLEVERBEnum // CreateFORMATETCEnum // CreateStaticEnum // // GetMonikerDisplayName // CreateStorageOnHGlobal // ConvertToMemoryStream // StmReadString // StmWriteString // // CreateViewAdviseHolder // // --- // // Macros: WATCHINTERFACE // IsSameIID // // TaskAllocMem // TaskFreeMem // TaskAllocString // TaskFreeString // // OK // NOTOK // // DECLARE_IUNKNOWN_METHODS // DECLARE_PURE_IUNKNOWN_METHODS // DECLARE_STANDARD_IUNKNOWN // IMPLEMENT_STANDARD_IUNKNOWN // DECLARE_DELEGATING_IUNKNOWN // IMPLEMENT_DELEGATING_IUNKNOWN // DECLARE_PRIVATE_IUNKNOWN // IMPLEMENT_PRIVATE_IUNKNOWN // // DECLARE_CODE_TIMER // IMPLEMENT_CODE_TIMER // START_CODE_TIMER // STOP_CODE_TIMER // // Enums: // OLE_SERVER_STATE // // OBPARTS // OLECLIPFORMAT // // --- // // Notes: Define INC_STATUS_BAR to include the status bar // class definition. // //---------------------------------------------------------------------------- #ifndef _O2BASE_HXX_ #define _O2BASE_HXX_ // resource ID offsets for class descriptor information #define IDOFF_CLASSID 0 #define IDOFF_USERTYPEFULL 1 #define IDOFF_USERTYPESHORT 2 #define IDOFF_USERTYPEAPP 3 #define IDOFF_DOCFEXT 5 #define IDOFF_ICON 10 #define IDOFF_ACCELS 11 #define IDOFF_MENU 12 #define IDOFF_MGW 13 #define IDOFF_MISCSTATUS 14 #ifndef RC_INVOKED // the resource compiler is not interested in the rest #if DBG extern "C" void FAR PASCAL AssertSFL( LPSTR lpszClause, LPSTR lpszFileName, int nLine); #define Assert(f) ((f)? (void)0 : AssertSFL(#f, __FILE__, __LINE__)) #else // !DBG #define Assert(x) #endif // DBG //+--------------------------------------------------------------------- // // Windows helper functions // //---------------------------------------------------------------------- LPVOID LoadResourceData(HINSTANCE hinst, LPCWSTR lpstrId, LPVOID lpvBuf, int cbBuf); void GetChildWindowRect(HWND hwndChild, LPRECT lprect); void SizeClientRect(HWND hwnd, RECT& rc, BOOL fMove); //+--------------------------------------------------------------------- // // Generally useful #defines and inline functions for OLE2. // //------------------------------------------------------------------------ // this macro can be used to put string constants in a read-only code segment // usage: char CODE_BASED szFoo[] = "Bar"; #define CODE_BASED __based(__segname("_CODE")) // These are the major and minor version returned by OleBuildVersion #define OLE_MAJ_VER 0x0003 #define OLE_MIN_VER 0x003A //--------------------------------------------------------------- // SCODE and HRESULT macros //--------------------------------------------------------------- #define OK(r) (SUCCEEDED(r)) #define NOTOK(r) (FAILED(r)) //--------------------------------------------------------------- // GUIDs, CLSIDs, IIDs //--------------------------------------------------------------- #define IsSameIID(iid1, iid2) ((iid1)==(iid2)) //--------------------------------------------------------------- // IUnknown //--------------------------------------------------------------- // // This declares the set of IUnknown methods and is for general-purpose // use inside classes that inherit from IUnknown #define DECLARE_IUNKNOWN_METHODS \ STDMETHOD(QueryInterface) (REFIID riid, LPVOID FAR* ppvObj); \ STDMETHOD_(ULONG,AddRef) (void); \ STDMETHOD_(ULONG,Release) (void) // // This declares the set of IUnknown methods as pure virtual methods // #define DECLARE_PURE_IUNKNOWN_METHODS \ STDMETHOD(QueryInterface) (REFIID riid, LPVOID FAR* ppvObj) = 0; \ STDMETHOD_(ULONG,AddRef) (void) = 0; \ STDMETHOD_(ULONG,Release) (void) = 0 // // This is for use in declaring non-aggregatable objects. It declares the // IUnknown methods and reference counter, _ulRefs. // _ulRefs should be initialized to 1 in the constructor of the object #define DECLARE_STANDARD_IUNKNOWN(cls) \ DECLARE_IUNKNOWN_METHODS; \ ULONG _ulRefs // note: this does NOT implement QueryInterface, which must be // implemented by each object #define IMPLEMENT_STANDARD_IUNKNOWN(cls) \ STDMETHODIMP_(ULONG) cls##::AddRef(void) \ { ++_ulRefs; \ return _ulRefs;} \ STDMETHODIMP_(ULONG) cls##::Release(void) \ { ULONG ulRet = --_ulRefs; \ if (ulRet == 0) delete this; \ return ulRet; } // This is for use in declaring aggregatable objects. It declares the IUnknown // methods and a member pointer to the aggregate controlling unknown, _pUnkOuter, // that all IUnknowns delegate to except the controlling unknown of the object // itself. // _pUnkOuter must be initialized to point to either an external controlling // unknown or the object's own controlling unknown, depending on whether the // object is being created as part of an aggregate or not. #define DECLARE_DELEGATING_IUNKNOWN(cls) \ DECLARE_IUNKNOWN_METHODS; \ LPUNKNOWN _pUnkOuter // This, correspondingly, is for use in implementing aggregatable objects. // It implements the IUnknown methods by trivially delegating to the controlling // unknown described by _pUnkOuter. #define IMPLEMENT_DELEGATING_IUNKNOWN(cls) \ STDMETHODIMP cls##::QueryInterface (REFIID riid, LPVOID FAR* ppvObj) \ { return _pUnkOuter->QueryInterface(riid, ppvObj); } \ STDMETHODIMP_(ULONG) cls##::AddRef (void) \ { return _pUnkOuter->AddRef(); } \ STDMETHODIMP_(ULONG) cls##::Release (void) \ { return _pUnkOuter->Release(); } // This declares a nested class that is the private unknown of the object #define DECLARE_PRIVATE_IUNKNOWN(cls) \ class PrivateUnknown: public IUnknown { \ public: \ PrivateUnknown(cls* p##cls); \ DECLARE_IUNKNOWN_METHODS; \ private: \ ULONG _ulRefs; \ cls* _p##cls; }; \ friend class PrivateUnknown; \ PrivateUnknown _PrivUnk // // note: this does NOT implement QueryInterface, which must be // implemented by each object #define IMPLEMENT_PRIVATE_IUNKNOWN(cls) \ cls##::PrivateUnknown::PrivateUnknown(cls* p##cls) \ { _p##cls = p##cls; _ulRefs = 1; } \ STDMETHODIMP_(ULONG) cls##::PrivateUnknown::AddRef(void) \ { ++_ulRefs; \ return _ulRefs; } \ STDMETHODIMP_(ULONG) cls##::PrivateUnknown::Release(void) \ { ULONG ulRet = --_ulRefs; \ if (ulRet == 0) delete _p##cls; \ return ulRet; } //+--------------------------------------------------------------------- // // Miscellaneous useful OLE helper and debugging functions // //---------------------------------------------------------------------- // // Some convenient OLE-related definitions and declarations // typedef unsigned short far * LPUSHORT; //REVIEW we are experimenting with a non-standard OLEMISC flag. #define OLEMISC_STREAMABLE 1024 IsCompatibleOleVersion(WORD wMaj, WORD wMin); inline BOOL IsDraggingDistance(POINT pt1, POINT pt2) { #define MIN_DRAG_DIST 12 return (abs(pt1.x - pt2.x) >= MIN_DRAG_DIST || abs(pt1.y - pt2.y) >= MIN_DRAG_DIST); #undef MIN_DRAG_DIST } #if ENABLED_DBG == 1 void TraceIID(REFIID riid); HRESULT TraceHRESULT(HRESULT r); #define TRACEIID(iid) TraceIID(iid) #define TRACEHRESULT(r) TraceHRESULT(r) #else // DBG == 0 #define TRACEIID(iid) #define TRACEHRESULT(r) #endif // DBG //+--------------------------------------------------------------------- // // Routines to convert Pixels to Himetric and vice versa // //---------------------------------------------------------------------- long HimetricFromHPix(int iPix); long HimetricFromVPix(int iPix); int HPixFromHimetric(long lHi); int VPixFromHimetric(long lHi); //+--------------------------------------------------------------------- // // Timing helpers // //------------------------------------------------------------------------ #ifdef _TIMING #define DECLARE_CODE_TIMER(t) extern CTimer t #define IMPLEMENT_CODE_TIMER(t,s) CTimer t(s) #define START_CODE_TIMER(t) t.Start() #define STOP_CODE_TIMER(t) t.Stop() #else // !_TIMING #define DECLARE_CODE_TIMER(t) #define IMPLEMENT_CODE_TIMER(t,s) #define START_CODE_TIMER(t) #define STOP_CODE_TIMER(t) #endif // _TIMING //+--------------------------------------------------------------------- // // Rectangle helper functions // //---------------------------------------------------------------------- //+--------------------------------------------------------------- // // Function: RECTtoRECTL // // Synopsis: Converts a RECT structure to a RECTL // //---------------------------------------------------------------- inline void RECTtoRECTL(RECT& rc, LPRECTL lprcl) { lprcl->left = (long)rc.left; lprcl->top = (long)rc.top; lprcl->bottom = (long)rc.bottom; lprcl->right = (long)rc.right; } //+--------------------------------------------------------------- // // Function: RECTLtoRECT // // Synopsis: Converts a RECTL structure to a RECT // //---------------------------------------------------------------- inline void RECTLtoRECT(RECTL& rcl, LPRECT lprc) { lprc->left = (int)rcl.left; lprc->top = (int)rcl.top; lprc->bottom = (int)rcl.bottom; lprc->right = (int)rcl.right; } //+--------------------------------------------------------------- // // Function: lMulDiv, private // // Synopsis: Does a long MulDiv operation // //---------------------------------------------------------------- inline long lMulDiv(long lMultiplicand, long lMultiplier, long lDivisor) { return (lMultiplicand * lMultiplier)/lDivisor; //FEATURE: 64bit intermediate? } //+--------------------------------------------------------------- // // Function: ProportionateRectl // // Synopsis: Calculates rectangle A that is proportionate to rectangle B // as rectangle C is to rectangle D, // i.e. determine A such that A's relation to B is the same as // C's relation to D. // // Arguments: [lprclA] -- rectangle A to be computed // [rclB] -- rectangle B // [rclC] -- rectangle C // [rclD] -- rectangle D // //---------------------------------------------------------------- inline void ProportionateRectl(LPRECTL lprclA, RECTL& rclB, RECTL& rclC, RECTL& rclD) { // start with rectangle C *lprclA = rclC; // translate it so the UL corner of D is at the origin lprclA->left -= rclD.left; lprclA->top -= rclD.top; lprclA->right -= rclD.left; lprclA->bottom -= rclD.top; // scale it by the ratio of the size of B to D (each axis independently) SIZEL sizelB = { rclB.right - rclB.left, rclB.bottom - rclB.top }; SIZEL sizelD = { rclD.right - rclD.left, rclD.bottom - rclD.top }; lprclA->left = lMulDiv(lprclA->left, sizelB.cx, sizelD.cx); lprclA->top = lMulDiv(lprclA->top, sizelB.cy, sizelD.cy); lprclA->right = lMulDiv(lprclA->right, sizelB.cx, sizelD.cx); lprclA->bottom = lMulDiv(lprclA->bottom, sizelB.cy, sizelD.cy); // translate it to the coordinates represented by B lprclA->left += rclB.left; lprclA->top += rclB.top; lprclA->right += rclB.left; lprclA->bottom += rclB.top; } //+--------------------------------------------------------------- // // Function: RectToScreen // // Synopsis: Converts a rectangle in client coordinates of a window // to screen coordinates. // // Arguments: [hwnd] -- the window defining the client coordinate space // [lprect] -- the rectangle to be converted // //---------------------------------------------------------------- inline void RectToScreen(HWND hwnd, LPRECT lprect) { POINT ptUL = { lprect->left, lprect->top }; ClientToScreen(hwnd,&ptUL); POINT ptLR = { lprect->right, lprect->bottom }; ClientToScreen(hwnd,&ptLR); lprect->left = ptUL.x; lprect->top = ptUL.y; lprect->right = ptLR.x; lprect->bottom = ptLR.y; } //+--------------------------------------------------------------- // // Function: RectToClient // // Synopsis: Converts a rectangle in screen coordinates to client // coordinates of a window. // // Arguments: [hwnd] -- the window defining the client coordinate space // [lprect] -- the rectangle to be converted // //---------------------------------------------------------------- inline void RectToClient(HWND hwnd, LPRECT lprect) { POINT ptUL = { lprect->left, lprect->top }; ScreenToClient(hwnd,&ptUL); POINT ptLR = { lprect->right, lprect->bottom }; ScreenToClient(hwnd,&ptLR); lprect->left = ptUL.x; lprect->top = ptUL.y; lprect->right = ptLR.x; lprect->bottom = ptLR.y; } //+--------------------------------------------------------------- // // Function: IsRectInRect // // Synopsis: Determines whether one rectangle is wholly contained within // another rectangle. // // Arguments: [rcOuter] -- the containing rectangle // [lprect] -- the contained rectangle // //---------------------------------------------------------------- inline BOOL IsRectInRect(RECT& rcOuter, RECT& rcInner) { POINT pt1 = { rcInner.left, rcInner.top }; POINT pt2 = { rcInner.right, rcInner.bottom }; return PtInRect(&rcOuter, pt1) && PtInRect(&rcOuter, pt2); } //+--------------------------------------------------------------------- // // IMalloc-related helpers // //---------------------------------------------------------------------- //REVIEW: We may want to cache the IMalloc pointer for efficiency #ifdef WIN16 // // C++ new/delete replacements that use OLE's allocators // void FAR* operator new(size_t size); void FAR* operator new(size_t size, MEMCTX memctx); void operator delete(void FAR* lpv); #endif //WIN16 // // inline IMalloc memory allocation functions // HRESULT OleAllocMem(MEMCTX ctx, ULONG cb, LPVOID FAR* ppv); void OleFreeMem(MEMCTX ctx, LPVOID pv); HRESULT OleAllocString(MEMCTX ctx, LPCWSTR lpstrSrc, LPWSTR FAR* ppstr); void OleFreeString(MEMCTX ctx, LPWSTR lpstr); #define TaskAllocMem(cb, ppv) OleAllocMem(MEMCTX_TASK, cb, ppv) #define TaskFreeMem(pv) OleFreeMem(MEMCTX_TASK, pv) #define TaskAllocString(lpstr, ppstr) OleAllocString(MEMCTX_TASK, lpstr, ppstr) #define TaskFreeString(lpstr) OleFreeString(MEMCTX_TASK, lpstr) //+--------------------------------------------------------------------- // // Border definitions and helper class // //------------------------------------------------------------------------ // Default value for border thickness unless over-ridden via SetThickness #define FBORDER_THICKNESS 4 // Default values for border minimums (customize via SetMinimums) #define FBORDER_MINHEIGHT (FBORDER_THICKNESS*2 + 8); #define FBORDER_MINWIDTH (FBORDER_THICKNESS*2 + 8); #define OBSTYLE_MODMASK 0xff00 /* Mask style modifier bits */ #define OBSTYLE_TYPEMASK 0x00ff /* Mask basic type definition bits */ #define OBSTYLE_RESERVED 0x8000 /* bit reserved for internal use */ #define OBSTYLE_INSIDE 0x4000 /* Inside or Outside rect? */ #define OBSTYLE_HANDLED 0x2000 /* Size Handles Drawn? */ #define OBSTYLE_ACTIVE 0x1000 /* Active Border Shading? */ #define OBSTYLE_XOR 0x0800 /* Draw with XOR? */ #define OBSTYLE_THICK 0x0400 /* double up lines? */ #define OBSTYLE_DIAGONAL_FILL 0x0001 /* Open editing */ #define OBSTYLE_SOLID_PEN 0x0002 /* Simple Outline */ #define FB_HANDLED (OBSTYLE_HANDLED | OBSTYLE_SOLID_PEN) #define FB_OPEN OBSTYLE_DIAGONAL_FILL #define FB_OUTLINED OBSTYLE_SOLID_PEN #define FB_HIDDEN 0 #define MAX_OBPART 13 enum OBPARTS { BP_NOWHERE, BP_TOP, BP_RIGHT, BP_BOTTOM, BP_LEFT, BP_TOPRIGHT, BP_BOTTOMRIGHT, BP_BOTTOMLEFT, BP_TOPLEFT, BP_TOPHAND, BP_RIGHTHAND, BP_BOTTOMHAND, BP_LEFTHAND, BP_INSIDE }; class OLEBorder { public: OLEBorder(RECT& r); OLEBorder(void); ~OLEBorder(void); void SetMinimums( SHORT sMinHeight, SHORT sMinWidth ); int SetThickness(int sBorderThickness); int GetThickness(void); USHORT SetState(HDC hdc, HWND hwnd, USHORT usBorderState); USHORT GetState(void); void Draw(HDC hdc, HWND hwnd); void Erase(HWND hwnd); USHORT QueryHit(POINT point); HCURSOR MapPartToCursor(USHORT usPart); HCURSOR QueryMoveCursor(POINT ptCurrent, BOOL fMustMove); HCURSOR BeginMove(HDC hdc, HWND hwnd, POINT ptStart, BOOL fMustMove); RECT& UpdateMove(HDC hdc, HWND hwnd, POINT ptCurrent, BOOL fNewRegion); RECT& EndMove(HDC hdc, HWND hwnd, POINT ptCurrent, USHORT usBorderState); void SwitchCoords( HWND hwndFrom, HWND hwndTo ); // //OLEBorder exposes it's RECT as a public data member // RECT rect; private: enum ICURS { ICURS_STD, ICURS_NWSE, ICURS_NESW, ICURS_NS, ICURS_WE }; static BOOL fInit; static HCURSOR ahc[5]; static int iPartMap[14]; void InitClass(void); void GetBorderRect(RECT& rDest, int iEdge); void GetInsideBorder(RECT& rDest, int iEdge); void GetOutsideBorder(RECT& rDest, int iEdge); USHORT _state; int _sMinHeight; int _sMinWidth; int _sThickness; USHORT _usPart; //which portion of border was hit? POINT _pt; //last known point BOOL _fErased; }; inline void OLEBorder::SetMinimums( SHORT sMinHeight, SHORT sMinWidth ) { _sMinHeight = sMinHeight; _sMinWidth = sMinWidth; } inline int OLEBorder::GetThickness(void) { return(_sThickness); } inline int OLEBorder::SetThickness(int sBorderThickness) { if(sBorderThickness > 0) { _sThickness = sBorderThickness; } return(_sThickness); } inline USHORT OLEBorder::GetState(void) { return(_state); } //+--------------------------------------------------------------------- // // Helper functions for implementing IDataObject and IViewObject // //---------------------------------------------------------------------- // // Useful #defines // #define DVASPECT_ALL \ DVASPECT_CONTENT|DVASPECT_THUMBNAIL|DVASPECT_ICON|DVASPECT_DOCPRINT // // Standard OLE Clipboard formats // enum OLECLIPFORMAT { OCF_OBJECTLINK, OCF_OWNERLINK, OCF_NATIVE, OCF_FILENAME, OCF_NETWORKNAME, OCF_DATAOBJECT, OCF_EMBEDDEDOBJECT, OCF_EMBEDSOURCE, OCF_LINKSOURCE, OCF_LINKSRCDESCRIPTOR, OCF_OBJECTDESCRIPTOR, OCF_OLEDRAW, OCF_LAST = OCF_OLEDRAW }; extern UINT OleClipFormat[OCF_LAST+1]; // array of OLE standard clipboard formats // indexed by OLECLIPFORMAT enumeration. void RegisterOleClipFormats(void); // initializes OleClipFormat table. // // FORMATETC helpers // BOOL IsCompatibleDevice(DVTARGETDEVICE FAR* ptdLeft, DVTARGETDEVICE FAR* ptdRight); BOOL IsCompatibleFormat(FORMATETC& f1, FORMATETC& f2); int FindCompatibleFormat(FORMATETC FmtTable[], int iSize, FORMATETC& formatetc); // // OBJECTDESCRIPTOR clipboard format helpers // HRESULT GetObjectDescriptor(LPDATAOBJECT pDataObj, LPOBJECTDESCRIPTOR pDescOut); HRESULT UpdateObjectDescriptor(LPDATAOBJECT pDataObj, POINTL& ptl, DWORD dwAspect); // // Other helper functions // HRESULT DrawMetafile(LPVIEWOBJECT pVwObj, RECT& rc, DWORD dwAspect, HMETAFILE FAR* pHMF); //+--------------------------------------------------------------------- // // IStream on top of a DOS (non-docfile) file // //---------------------------------------------------------------------- HRESULT CreateStreamOnFile(LPCSTR lpstrFile, DWORD stgm, LPSTREAM FAR* ppstrm); //+--------------------------------------------------------------------- // // Class: InPlaceBorder Class (IP) // // Synopsis: Helper Class to draw inplace activation borders around an // object. // // Notes: Use of this class limits windows to the use of the // non-client region for UIAtive borders only: Standard // (non-control window) scroll bars are specifically NOT // supported. // // History: 14-May-93 CliffG Created. // //------------------------------------------------------------------------ #define IPBORDER_THICKNESS 6 class InPlaceBorder { public: InPlaceBorder(void); ~InPlaceBorder(void); // //Substitute for standard windows API: identical signature & semantics // LRESULT DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); // //Change the server state: reflected in the nonclient window border // void SetUIActive(BOOL fUIActive); BOOL GetUIActive(void); // //Force border state to OS_LOADED, managing the cooresponding change //in border appearance: guaranteed redraw // void Erase(void); void SetBorderSize( int cx, int cy ); void GetBorderSize( LPINT pcx, LPINT pcy ); void Bind(LPOLEINPLACESITE pSite, HWND hwnd, BOOL fUIActive ); void Attach( HWND hwnd, BOOL fUIActive ); void Detach(void); void SetSize(HWND hwnd, RECT& rc); void SetParentActive( BOOL fActive ); private: BOOL _fUIActive; //current state of border BOOL _fParentActive; //shade as active border? HWND _hwnd; //attached window (if any) LPOLEINPLACESITE _pSite; //InPlace site we are bound to int _cxFrame; //border horizontal thickness int _cyFrame; //border vertical thickness int _cResizing; //reentrancy control flag static WORD _cUsage; //refcount for static resources static HBRUSH _hbrActiveCaption; static HBRUSH _hbrInActiveCaption; void DrawFrame(HWND hwnd); void CalcClientRect(HWND hwnd, LPRECT lprc); LONG HitTest(HWND hwnd, int x, int y); void InvalidateFrame(void); void RedrawFrame(void); }; inline void InPlaceBorder::Detach(void) { _pSite = NULL; _hwnd = NULL; } inline void InPlaceBorder::InvalidateFrame(void) { //cause a WM_NCCALCRECT to be generated if(_hwnd != NULL) { ++_cResizing; SetWindowPos( _hwnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); _cResizing--; } } inline void InPlaceBorder::RedrawFrame(void) { if(_hwnd != NULL) { ++_cResizing; UINT afuRedraw = RDW_INVALIDATE | RDW_UPDATENOW; RedrawWindow(_hwnd, NULL, NULL, afuRedraw); _cResizing--; } } inline void InPlaceBorder::SetParentActive( BOOL fActive ) { _fParentActive = fActive; RedrawFrame(); } inline void InPlaceBorder::CalcClientRect(HWND hwnd, LPRECT lprc) { if(_fUIActive) InflateRect(lprc, -_cxFrame, -_cyFrame); } inline BOOL InPlaceBorder::GetUIActive(void) { return _fUIActive; } //+--------------------------------------------------------------------- // // Helper functions for in-place activation // //---------------------------------------------------------------------- HRESULT InsertServerMenus(HMENU hmenuShared, HMENU hmenuObject, LPOLEMENUGROUPWIDTHS lpmgw); void RemoveServerMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpmgw); //--------------------------------------------------------------- // IStorage //--------------------------------------------------------------- #define STGM_SHARE 0x000000F0 //+--------------------------------------------------------------------- // // Running Object Table helper functions // //---------------------------------------------------------------------- void RegisterAsRunning(LPUNKNOWN lpUnk, LPMONIKER lpmkFull, DWORD FAR* lpdwRegister); void RevokeAsRunning(DWORD FAR* lpdwRegister); //+--------------------------------------------------------------------- // // Standard implementations of common enumerators // //---------------------------------------------------------------------- HRESULT CreateOLEVERBEnum(LPOLEVERB pVerbs, ULONG cVerbs, LPENUMOLEVERB FAR* ppenum); HRESULT CreateFORMATETCEnum(LPFORMATETC pFormats, ULONG cFormats, LPENUMFORMATETC FAR* ppenum); #if 0 // currently not used but useful in the future. // we ifdef it out so it doesn't take up space // in our servers. HRESULT CreateStaticEnum(REFIID riid, LPVOID pStart, ULONG cSize, ULONG cCount, LPVOID FAR* ppenum); #endif //0 //+--------------------------------------------------------------------- // // Standard IClassFactory implementation // //---------------------------------------------------------------------- //+--------------------------------------------------------------- // // Class: StdClassFactory // // Purpose: Standard implementation of a class factory object // // Notes: * // //--------------------------------------------------------------- class StdClassFactory: public IClassFactory { public: StdClassFactory(void); DECLARE_IUNKNOWN_METHODS; STDMETHOD(CreateInstance)(LPUNKNOWN pUnkOuter, REFIID iid, LPVOID FAR* ppv) PURE; STDMETHOD(LockServer) (BOOL fLock); BOOL CanUnload(void); private: ULONG _ulRefs; ULONG _ulLocks; }; //+--------------------------------------------------------------------- // // IStorage and IStream Helper functions // //---------------------------------------------------------------------- #define STGM_DFRALL (STGM_READWRITE|STGM_TRANSACTED|STGM_SHARE_DENY_WRITE) #define STGM_DFALL (STGM_READWRITE | STGM_TRANSACTED | STGM_SHARE_EXCLUSIVE) #define STGM_SALL (STGM_READWRITE | STGM_SHARE_EXCLUSIVE) #define STGM_SRO (STGM_READ | STGM_SHARE_EXCLUSIVE) HRESULT GetMonikerDisplayName(LPMONIKER pmk, LPWSTR FAR* ppstr); HRESULT CreateStorageOnHGlobal(HGLOBAL hgbl, LPSTORAGE FAR* ppStg); LPSTREAM ConvertToMemoryStream(LPSTREAM pStrmFrom); //+--------------------------------------------------------------- // // Function: StmReadString // // Synopsis: Reads a string from a stream // // Arguments: [pStrm] -- the stream to read from // [ppstr] -- where the string read is returned // // Returns: Success if the string was read successfully // // Notes: The string is allocated with the task allocator // and needs to be freed by the same. // This is an inline function. // //---------------------------------------------------------------- inline HRESULT StmReadString(LPSTREAM pStrm, LPSTR FAR *ppstr) { HRESULT r; USHORT cb; LPSTR lpstr = NULL; if (OK(r = pStrm->Read(&cb, sizeof(cb), NULL))) { if (OK(r = TaskAllocMem(cb+1, (LPVOID FAR*)&lpstr))) { r = pStrm->Read(lpstr, cb, NULL); *(lpstr+cb) = '\0'; } } *ppstr = lpstr; return r; } //+--------------------------------------------------------------- // // Function: StmWriteString // // Synopsis: Writes a string to a stream // // Arguments: [pStrm] -- the stream to write to // [lpstr] -- the string to write // // Returns: Success iff the string was written successfully // // Notes: This is an inline function. // //---------------------------------------------------------------- inline HRESULT StmWriteString(LPSTREAM pStrm, LPSTR lpstr) { HRESULT r; USHORT cb = strlen(lpstr); if (OK(r = pStrm->Write(&cb, sizeof(cb), NULL))) r = pStrm->Write(lpstr, cb, NULL); return r; } //+--------------------------------------------------------------------- // // View advise holder // //---------------------------------------------------------------------- // // forward declaration // class ViewAdviseHolder; typedef ViewAdviseHolder FAR* LPVIEWADVISEHOLDER; //+--------------------------------------------------------------- // // Class: ViewAdviseHolder // // Purpose: Manages the view advises on behalf of a IViewObject object // // Notes: This is analogous to the standard DataAdviseHolder provided // by OLE. c.f. CreateViewAdviseHolder. // //--------------------------------------------------------------- class ViewAdviseHolder: public IUnknown { friend HRESULT CreateViewAdviseHolder(LPVIEWADVISEHOLDER FAR*); public: //*** IUnknown methods ***/ STDMETHOD(QueryInterface) (REFIID riid, LPVOID FAR* ppvObj); STDMETHOD_(ULONG,AddRef) (void); STDMETHOD_(ULONG,Release) (void); //*** ViewAdviseHolder methods STDMETHOD(SetAdvise) (DWORD aspects, DWORD advf, LPADVISESINK pAdvSink); STDMETHOD(GetAdvise) (DWORD FAR* pAspects, DWORD FAR* pAdvf, LPADVISESINK FAR* ppAdvSink); void SendOnViewChange(DWORD dwAspect); private: ViewAdviseHolder(); ~ViewAdviseHolder(); ULONG _refs; LPADVISESINK _pAdvSink; // THE view advise sink DWORD _dwAdviseAspects; // view aspects of interest to advise sink DWORD _dwAdviseFlags; // view advise flags }; HRESULT CreateViewAdviseHolder(LPVIEWADVISEHOLDER FAR* ppViewHolder); #ifdef INC_STATUS_BAR // // forward declarations // extern "C" LRESULT CALLBACK StatusWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); class StatusBar; typedef StatusBar FAR* LPSTATUSBAR; //+------------------------------------------------------------------- // // Class: StatusBar // // Purpose: A status bar. // // Notes: Of the guidelines laid down by the UI people, the // current implementation violates the following:: // - height of status bar should equal the height of // the window's title bar. // //-------------------------------------------------------------------- class StatusBar { friend LRESULT CALLBACK StatusWndProc(HWND, UINT, WPARAM, LPARAM); public: static BOOL ClassInit(HINSTANCE hinst); // registers window class StatusBar(); HWND Init(HINSTANCE hinst, HWND hwndParent); ~StatusBar(); void OnSize(LPRECT lprc); void DisplayMessage(LPCWSTR); WORD GetHeight(void); private: void OnPaint(HWND hwnd); // handles WM_PAINT message HWND _hwnd; // our status bar window HFONT _hfont; // font used to display messages. WCHAR _lpstrString[128]; // string currently being displayed. // various metrics: WORD _wHeight; // current height, once computed. WORD _wUnitBorder; // border, based on _wHeight; WORD _wSpace; // space between controls on bar. WORD _wAboveBelow; // space above and below }; //+--------------------------------------------------------------- // // Member: StatusBar::GetHeight, public // // Synopsis: Returns the height of the status bar in pixels // //---------------------------------------------------------------- inline WORD StatusBar::GetHeight(void) { return _wHeight; } #endif // INC_STATUS_BAR //+------------------------------------------------------------------------ // // Macro that calculates the number of elements in a statically-defined // array. // //------------------------------------------------------------------------- #define ARRAY_SIZE(_a) (sizeof(_a) / sizeof(_a[0])) //+------------------------------------------------------------------------ // // Class: CEnumGeneric (enum) // // Purpose: Implements an OLE2 enumerator for arrays of data. The CAry // class uses this class for its enumerator. // // Interface: Next Returns the next element[s] in the array // Skip Skips the next element[s] in the array // Reset Restarts at the beginning of the array // Clone Creates a copy of theis enumerator // // Create Creates a new instance of this enumerator, given // an interface ID, element size, count, and pointer // // Members: _refs Ref count // _iid Interface implemented by this enumerator // _cb Size of each element // _c Number of elements // _i Current index in the array // _pv Pointer to array data // //------------------------------------------------------------------------- class CEnumGeneric : public IUnknown { public: // IUnknown methods STDMETHOD(QueryInterface) (REFIID riid, LPVOID FAR* ppvObj); STDMETHOD_(ULONG,AddRef) (THIS); STDMETHOD_(ULONG,Release) (THIS); // IEnum methods STDMETHOD(Next) (ULONG celt, void FAR* reelt, ULONG FAR* pceltFetched); STDMETHOD(Skip) (ULONG celt); STDMETHOD(Reset) (); STDMETHOD(Clone) (CEnumGeneric FAR* FAR* ppenm); // CEnumGeneric methods static CEnumGeneric FAR* Create(REFIID, int cb, int c, void FAR* pv, BOOL fAddRef); protected: CEnumGeneric( REFIID, int cb, int c, void FAR* pv, BOOL fAddRef ); CEnumGeneric( CEnumGeneric * ); ULONG _refs; IID _iid; BOOL _fAddRef; int _cb; int _c; int _i; void FAR* _pv; }; //+------------------------------------------------------------------------ // // Class: CAry (ary) // // Purpose: Generic resizeable array class // // Interface: CAry, ~CAry // EnsureSize Ensures that the array is at least a certain // size, allocating more memory if necessary. // Note that the array size is measured in elements, // rather than in bytes. // Size Returns the current size of the array. // SetSize Sets the array size; EnsureSize must be called // first to reserve space if the array is growing // // operator LPVOID Allow the CAry class to be cast to a (void *) // // Append Adds a new pointer to the end of the array, // growing the array if necessary. Only works // for arrays of pointers. // AppendIndirect As Append, for non-pointer arrays // // Insert Inserts a new pointer at the given index in // the array, growing the array if necessary. Any // elements at or following the index are moved // out of the way. // InsertIndirect As Insert, for non-pointer arrays // // Delete Deletes an element of the array, moving any // elements that follow it to fill // DeleteMultiple Deletes a range of elements from the array, // moving to fill // BringToFront Moves an element of the array to index 0, // shuffling elements to make room // SendToBack Moves an element to the end of the array, // shuffling elements to make room // // Find Returns the index at which a given pointer // is found // FindIndirect As Find, for non-pointer arrays // // EnumElements Create an enumerator which supports the given // interface ID for the contents of the array // // Deref [prot] Returns a pointer to an element of the array; // normally used by type-safe methods in derived // classes // // Members: _c Current size of the array // _cMac Current number of elements allocated // _cb Size of each element // _pv Buffer storing the elements // // Note: The CAry class only supports arrays of elements whose size is // less than CARY_MAXELEMSIZE (currently 32). // //------------------------------------------------------------------------- class CAry { public: CAry(size_t cb); ~CAry(); HRESULT EnsureSize(int c); int Size(void) { return _c; } void SetSize(int c) { _c = c; } operator LPVOID(void) { return _pv; } HRESULT Append(void *); HRESULT AppendIndirect(void *); HRESULT Insert(int, void *); HRESULT InsertIndirect(int, void *); void Delete(int); void DeleteAll(void); void DeleteMultiple(int, int); void BringToFront(int); void SendToBack(int); int Find(void *); int FindIndirect(void **); HRESULT EnumElements(REFIID iid, LPVOID * ppv, BOOL fAddRef); protected: int _c; int _cMac; size_t _cb; void * _pv; void * Deref(int i); }; #define CARY_MAXELEMSIZE 32 //+------------------------------------------------------------------------ // // Macro: DECLARE_ARY // // Purpose: Declares a type-safe class derived from CAry. // // Arguments: _Cls -- Name of new array class // _Ty -- Type of array element (e.g. FOO) // _pTy -- Type which is a pointer to _Ty (e.g. LPFOO) // // Interface: operator [] Provides a type-safe pointer to an element // of the array // operator LPFOO Allows the array to be cast to a type-safe // pointer to its first element // //------------------------------------------------------------------------- #define DECLARE_ARY(_Cls, _Ty, _pTy) \ class _Cls : public CAry { public: \ _Cls(void) : CAry(sizeof(_Ty)) { ; } \ _Ty& operator[] (int i) { return * (_pTy) Deref(i); } \ operator _pTy(void) { return (_pTy) _pv; } }; //**************************************************************************** // // IconBar Class // //**************************************************************************** // WM_COMMAND notification codes #define IBI_NEWSELECTION 1 #define IBI_STATUSAVAIL 2 #define IBP_LEFTBELOW 0 #define IBP_RIGHTABOVE 1 #define IBP_RIGHTBELOW 2 #define IBP_LEFTABOVE 3 extern "C" LRESULT CALLBACK IconBarWndProc(HWND,UINT,WPARAM,LPARAM); class IconBar; typedef IconBar FAR* LPICONBAR; class IconBar { friend LRESULT CALLBACK IconBarWndProc(HWND,UINT,WPARAM,LPARAM); public: static LPICONBAR Create(HINSTANCE hinst, HWND hwndParent, HWND hwndNotify, SHORT sIdChild); ~IconBar(void); HWND GetHwnd(void); void Position(int sTop, int sLeft, int sWhere); HRESULT AddCellsFromRegDB(LPWSTR pszFilter); void AddCell(CLSID& clsid, HICON hIcon, LPWSTR szTitle); void SetCellAspect( int cWide, int cHigh ); void SelectCell(int iCell, BOOL fStick); int GetSelectedCell(void); CLSID& GetSelectedClassId(void); LPWSTR GetStatusMessage(void); BOOL IsStuck(void); private: #define MAX_CELLS 24 #define MAX_ICON_TITLE 64 struct IconCell { CLSID clsid; HICON hIcon; HBITMAP hBmp; WCHAR achTitle[MAX_ICON_TITLE]; }; typedef IconCell FAR *LPICONCELL; IconBar(HWND hwndParent, HWND hwndNotify, SHORT sIDChild); int AddCell(LPICONCELL pCells, int i, CLSID& clsid, HICON hIcon, LPWSTR szTitle); void AddCache(void); void Draw(HDC hdc, POINT pt, BOOL fDown, int iCell); void ncCalcRect(HWND hwnd, LPRECT lprc); void ncDrawFrame(HWND hwnd); LONG ncHitTest(HWND hwnd, POINT pt); LRESULT ncMsgFilter(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); static ATOM InitClass(HINSTANCE hinst); static BOOL _fInit; static ATOM _atomClass; static HBRUSH hbrActiveCaption; static HBRUSH hbrInActiveCaption; static HBRUSH hbrWindowFrame; static HBRUSH hbrSysBox; static WORD wCnt; static COLORREF crLtGray; static COLORREF crGray; static COLORREF crDkGray; static COLORREF crBlack; //windows message handling BOOL OnCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct); void OnDestroy(HWND hwnd); void OnPaint(HWND hwnd); void OnGetMinMaxInfo(HWND hwnd, LPMINMAXINFO lpMinMaxInfo); void OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags); void OnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags); SHORT _dxMargin; // horizontal margin between tray border and icon SHORT _dyMargin; // vertical margin between tray border and icon SHORT _dxCell; // horizontal size of icon SHORT _dyCell; // vertical size of icon SHORT _cyCaption; // title bar height SHORT _cxFrame; // thickness of nc frame SHORT _cyFrame; SHORT _cxSize; // size of sizing corner SHORT _cySize; BOOL _fFloating; // free-floating window? HWND _hwnd; // the icon toolbar window HWND _hwndNotify; // the window to notify via WM_COMMAND SHORT _sIdChild; // child identifier for WM_COMMAND int _numCells; // the number of icon "cells" that have been loaded IconCell _cell[MAX_CELLS]; // the array of icon cells static int _cUsed; // outstanding users of cached cells static int _cCache; // total cached cells static IconCell _cache[MAX_CELLS]; // a cache array of icon cells int _cellsPerRow; int _selectedCell; int _iCellAtCursor; BOOL _fStuck; // other private helper members void GetCellPoint(LPPOINT lppt, int i); void GetCellRect(LPRECT lprc, int i); void InvalidateCell(HWND hwnd, int i); int CellIndexFromPoint(POINT pt); }; inline void IconBar::OnDestroy(HWND hwnd) { _hwnd = NULL; } inline BOOL IconBar::OnCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct) { return TRUE; } inline BOOL IconBar::IsStuck(void) { return _fStuck; } inline int IconBar::GetSelectedCell(void) { return _selectedCell; } inline HWND IconBar::GetHwnd(void) { return _hwnd; } //**************************************************************************** // // Macros // //**************************************************************************** //+------------------------------------------------------------------------ // // Macro: DECLARE_ARY // // Purpose: Declares a type-safe class derived from CAry. // // Arguments: _Cls -- Name of new array class // _Ty -- Type of array element (e.g. FOO) // _pTy -- Type which is a pointer to _Ty (e.g. LPFOO) // // Interface: operator [] Provides a type-safe pointer to an element // of the array // operator LPFOO Allows the array to be cast to a type-safe // pointer to its first element // //------------------------------------------------------------------------- #define DECLARE_ARY(_Cls, _Ty, _pTy) \ class _Cls : public CAry { public: \ _Cls(void) : CAry(sizeof(_Ty)) { ; } \ _Ty& operator[] (int i) { return * (_pTy) Deref(i); } \ operator _pTy(void) { return (_pTy) _pv; } }; //====================================================================== // // The base class stuff... // // // Classes: ClassDescriptor // SrvrCtrl // SrvrDV // SrvrInPlace // //---------------------------------------------------------------------------- enum OLE_SERVER_STATE { OS_PASSIVE, OS_LOADED, // handler but no server OS_RUNNING, // server running, invisible OS_INPLACE, // server running, inplace-active, no U.I. OS_UIACTIVE, // server running, inplace-active, w/ U.I. OS_OPEN // server running, open-edited }; // forward declarations of classes class ClassDescriptor; typedef ClassDescriptor FAR* LPCLASSDESCRIPTOR; class SrvrCtrl; typedef SrvrCtrl FAR* LPSRVRCTRL; class SrvrDV; typedef SrvrDV FAR* LPSRVRDV; class SrvrInPlace; typedef SrvrInPlace FAR* LPSRVRINPLACE; //+--------------------------------------------------------------- // // Class: ClassDescriptor // // Purpose: Global, static information about a server class // // Notes: This allows the base classes to implement a lot of // OLE functionality with requiring additional virtual // method calls on the derived classes. // //--------------------------------------------------------------- class ClassDescriptor { public: ClassDescriptor(void); BOOL Init(HINSTANCE hinst, WORD wBaseID); HMENU LoadMenu(void); HINSTANCE _hinst; // instance handle of module serving this class WORD _wBaseResID; // base resource identifier (see IDOFF_ ) CLSID _clsid; // class's unique identifier HICON _hicon; // iconic representation of class HACCEL _haccel; // accelerators for those menus OLEMENUGROUPWIDTHS _mgw; // the number of Edit, Object, and Help menus WCHAR _szUserClassType[4][64];// [0] unused // [1] the string assigned to classid key in reg db. // [2] reg db: \CLSID\\AuxUserType\2 // [3] reg db: \CLSID\\AuxUserType\3 WCHAR _szDocfileExt[8]; // extension for docfile files DWORD _dwMiscStatus; // reg db: \CLSID\\MiscStatus //DERIVED: The derived class must supply these tables. //REVIEW: These could be loaded from resources, too! LPOLEVERB _pVerbTable; // pointer to list of verbs available int _cVerbTable; // number of entries in the verb table LPFORMATETC _pGetFmtTable; // format table for IDataObject::GetData[Here] int _cGetFmtTable; // number of entries in the table LPFORMATETC _pSetFmtTable; // format table for IDataObject::SetData int _cSetFmtTable; // number of entries in the table }; //+--------------------------------------------------------------- // // Class: SrvrCtrl // // Purpose: Control subobject of OLE compound document server // // Notes: This class supports the IOleObject interface. // //--------------------------------------------------------------- class SrvrCtrl : public IOleObject { public: // standard verb implementations typedef HRESULT (*LPFNDOVERB) (LPVOID, LONG, LPMSG, LPOLECLIENTSITE, LONG, HWND, LPCRECT); static HRESULT DoShow(LPVOID, LONG, LPMSG, LPOLECLIENTSITE, LONG, HWND, LPCRECT); static HRESULT DoOpen(LPVOID, LONG, LPMSG, LPOLECLIENTSITE, LONG, HWND, LPCRECT); static HRESULT DoHide(LPVOID, LONG, LPMSG, LPOLECLIENTSITE, LONG, HWND, LPCRECT); static HRESULT DoUIActivate(LPVOID, LONG, LPMSG, LPOLECLIENTSITE, LONG, HWND, LPCRECT); static HRESULT DoInPlaceActivate(LPVOID, LONG, LPMSG, LPOLECLIENTSITE, LONG, HWND, LPCRECT); //DERIVED: IUnknown methods are left pure virtual and must be implemented // by the derived class // IOleObject interface methods STDMETHOD(SetClientSite) (LPOLECLIENTSITE pClientSite); STDMETHOD(GetClientSite) (LPOLECLIENTSITE FAR* ppClientSite); STDMETHOD(SetHostNames) (LPCWSTR szContainerApp, LPCWSTR szContainerObj); STDMETHOD(Close) (DWORD dwSaveOption); STDMETHOD(SetMoniker) (DWORD dwWhichMoniker, LPMONIKER pmk); STDMETHOD(GetMoniker) (DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER FAR* ppmk); STDMETHOD(InitFromData) (LPDATAOBJECT pDataObject,BOOL fCreation, DWORD dwReserved); STDMETHOD(GetClipboardData) (DWORD dwReserved, LPDATAOBJECT FAR* ppDataObject); STDMETHOD(DoVerb) (LONG iVerb, LPMSG lpmsg, LPOLECLIENTSITE pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect); STDMETHOD(EnumVerbs) (LPENUMOLEVERB FAR* ppenumOleVerb); STDMETHOD(Update) (void); STDMETHOD(IsUpToDate) (void); STDMETHOD(GetUserClassID) (CLSID FAR* pClsid); STDMETHOD(GetUserType) (DWORD dwFormOfType, LPWSTR FAR* pszUserType); STDMETHOD(SetExtent) (DWORD dwDrawAspect, LPSIZEL lpsizel); STDMETHOD(GetExtent) (DWORD dwDrawAspect, LPSIZEL lpsizel); STDMETHOD(Advise)(IAdviseSink FAR* pAdvSink, DWORD FAR* pdwConnection); STDMETHOD(Unadvise)(DWORD dwConnection); STDMETHOD(EnumAdvise) (LPENUMSTATDATA FAR* ppenumAdvise); STDMETHOD(GetMiscStatus) (DWORD dwAspect, DWORD FAR* pdwStatus); STDMETHOD(SetColorScheme) (LPLOGPALETTE lpLogpal); // pointers to our data/view and inplace subobjects LPSRVRDV _pDV; // our persistent data/view subobject LPSRVRINPLACE _pInPlace; // our inplace-active subobject // pointers to those objects' private unknowns LPUNKNOWN _pPrivUnkDV; LPUNKNOWN _pPrivUnkIP; // methods and members required by our data/view and inplace subobjects. OLE_SERVER_STATE State(void); void SetState(OLE_SERVER_STATE state) { _state = state; }; HRESULT TransitionTo(OLE_SERVER_STATE state); LPOLECLIENTSITE _pClientSite; void OnSave(void); void EnableIPB(BOOL fEnabled); BOOL IsIPBEnabled(void); virtual HRESULT Init(LPCLASSDESCRIPTOR pClass); // IOleObject-related members DWORD _dwRegROT; // our R.O.T. registration value LPOLEADVISEHOLDER _pOleAdviseHolder;// for collection our advises LPWSTR _lpstrCntrApp; // top-level container application LPWSTR _lpstrCntrObj; // and object names protected: // // DERIVED: Each of these correspond to a unique state transition. // The derived class may want to override to do additional processing. // virtual HRESULT PassiveToLoaded(); virtual HRESULT LoadedToPassive(); virtual HRESULT LoadedToRunning(); virtual HRESULT RunningToLoaded(); virtual HRESULT RunningToInPlace(); virtual HRESULT InPlaceToRunning(); virtual HRESULT InPlaceToUIActive(); virtual HRESULT UIActiveToInPlace(); virtual HRESULT RunningToOpened(); virtual HRESULT OpenedToRunning(); // constructors, initializers, and destructors SrvrCtrl(void); virtual ~SrvrCtrl(void); LPCLASSDESCRIPTOR _pClass; // global info about our OLE server OLE_SERVER_STATE _state; // our current state BOOL _fEnableIPB; // FALSE turns off built-in border //DERIVED: The derived class must supply table of verb functions // parallel to the table of verbs in the class descriptor LPFNDOVERB FAR* _pVerbFuncs; // verb function table }; //+--------------------------------------------------------------- // // Member: SrvrCtrl::State, public // // Synopsis: Returns the current state of the object // // Notes: The valid object states are closed, loaded, inplace, // U.I. active, and open. These states are defined // by the OLE_SERVER_STATE enumeration. // //--------------------------------------------------------------- inline OLE_SERVER_STATE SrvrCtrl::State(void) { return _state; } //+--------------------------------------------------------------- // // Member: SrvrCtrl::EnableIPB, public // // Synopsis: Enables/Disables built in InPlace border // //--------------------------------------------------------------- inline void SrvrCtrl::EnableIPB(BOOL fEnabled) { _fEnableIPB = fEnabled; } //+--------------------------------------------------------------- // // Member: SrvrCtrl::IsIPBEnabled, public // // Synopsis: Answers whether built-in InPlace border is enabled // //--------------------------------------------------------------- inline BOOL SrvrCtrl::IsIPBEnabled(void) { return _fEnableIPB; } //+--------------------------------------------------------------- // // Class: SrvrDV // // Purpose: Data/View subobject of OLE compound document server // // Notes: This class supports the IDataObject and IViewObject interfaces. // It also supports the IPersist-derived interfaces. // Objects of this class can operate as part of a complete // server aggregation or independently as a transfer data // object. // //--------------------------------------------------------------- class SrvrDV: public IDataObject, public IViewObject, public IPersistStorage, public IPersistStream, public IPersistFile { public: typedef HRESULT (*LPFNGETDATA) (LPSRVRDV, LPFORMATETC, LPSTGMEDIUM, BOOL); typedef HRESULT (*LPFNSETDATA) (LPSRVRDV, LPFORMATETC, LPSTGMEDIUM); // standard format Get/Set implementations static HRESULT GetEMBEDDEDOBJECT(LPSRVRDV, LPFORMATETC, LPSTGMEDIUM, BOOL); static HRESULT GetMETAFILEPICT(LPSRVRDV, LPFORMATETC, LPSTGMEDIUM, BOOL); static HRESULT GetOBJECTDESCRIPTOR(LPSRVRDV, LPFORMATETC, LPSTGMEDIUM, BOOL); static HRESULT GetLINKSOURCE(LPSRVRDV, LPFORMATETC, LPSTGMEDIUM, BOOL); // //DERIVED: IUnknown methods are left pure virtual and must be implemented // by the derived class // // IDataObject interface methods // STDMETHOD(GetData) (LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium); STDMETHOD(GetDataHere) (LPFORMATETC pformatetc, LPSTGMEDIUM pmedium); STDMETHOD(QueryGetData) (LPFORMATETC pformatetc); STDMETHOD(GetCanonicalFormatEtc) (LPFORMATETC pformatetc, LPFORMATETC pformatetcOut); STDMETHOD(SetData) (LPFORMATETC pformatetc, LPSTGMEDIUM pmedium, BOOL fRelease); STDMETHOD(EnumFormatEtc) (DWORD dwDirection, LPENUMFORMATETC FAR* ppenum); STDMETHOD(DAdvise) (FORMATETC FAR* pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD FAR* pdwConnection); STDMETHOD(DUnadvise) (DWORD dwConnection); STDMETHOD(EnumDAdvise) (LPENUMSTATDATA FAR* ppenumAdvise); // // IViewObject interface methods // STDMETHOD(Draw) (DWORD dwDrawAspect, LONG lindex, void FAR* pvAspect, DVTARGETDEVICE FAR * ptd, HDC hicTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, BOOL (CALLBACK * pfnContinue) (DWORD), DWORD dwContinue); STDMETHOD(GetColorSet) (DWORD dwDrawAspect, LONG lindex, void FAR* pvAspect, DVTARGETDEVICE FAR * ptd, HDC hicTargetDev, LPLOGPALETTE FAR* ppColorSet); STDMETHOD(Freeze)(DWORD dwDrawAspect, LONG lindex, void FAR* pvAspect, DWORD FAR* pdwFreeze); STDMETHOD(Unfreeze) (DWORD dwFreeze); STDMETHOD(SetAdvise) (DWORD aspects, DWORD advf, LPADVISESINK pAdvSink); STDMETHOD(GetAdvise) (DWORD FAR* pAspects, DWORD FAR* pAdvf, LPADVISESINK FAR* ppAdvSink); // // IPersist interface methods // STDMETHOD(GetClassID) (LPCLSID lpClassID); STDMETHOD(IsDirty) (void); // // IPersistStream interface methods // STDMETHOD(Load) (LPSTREAM pStm); STDMETHOD(Save) (LPSTREAM pStm, BOOL fClearDirty); STDMETHOD(GetSizeMax) (ULARGE_INTEGER FAR * pcbSize); // // IPersistStorage interface methods // STDMETHOD(InitNew) (LPSTORAGE pStg); STDMETHOD(Load) (LPSTORAGE pStg); STDMETHOD(Save) (LPSTORAGE pStgSave, BOOL fSameAsLoad); STDMETHOD(SaveCompleted) (LPSTORAGE pStgNew); STDMETHOD(HandsOffStorage) (void); // // IPersistFile interface methods // STDMETHOD(Load) (LPCOLESTR lpszFileName, DWORD grfMode); STDMETHOD(Save) (LPCOLESTR lpszFileName, BOOL fRemember); STDMETHOD(SaveCompleted) (LPCOLESTR lpszFileName); STDMETHOD(GetCurFile) (LPOLESTR FAR * lplpszFileName); // // DERIVED: methods required by the control // virtual HRESULT GetClipboardCopy(LPSRVRDV FAR* ppDV) = 0; virtual HRESULT GetExtent(DWORD dwAspect, LPSIZEL lpsizel); virtual HRESULT SetExtent(DWORD dwAspect, SIZEL& sizel); virtual void SetMoniker(LPMONIKER pmk); HRESULT GetMoniker(DWORD dwAssign, LPMONIKER FAR* ppmk); LPWSTR GetMonikerDisplayName(DWORD dwAssign = OLEGETMONIKER_ONLYIFTHERE); // //DERIVED: The derived class should call this base class method whenever // the data changes. This launches all appropriate advises. // void OnDataChange(DWORD dwAdvf = 0); // //DERIVED: The derived class should override these methods to perform // rendering of its native data. These are used in the implementation of // the IViewObject interface // virtual HRESULT RenderContent(DWORD dwDrawAspect, LONG lindex, void FAR* pvAspect, DVTARGETDEVICE FAR * ptd, HDC hicTargetDev, HDC hdcDraw, LPCRECTL lprectl, LPCRECTL lprcWBounds, BOOL (CALLBACK * pfnContinue) (DWORD), DWORD dwContinue); virtual HRESULT RenderPrint(DWORD dwDrawAspect, LONG lindex, void FAR* pvAspect, DVTARGETDEVICE FAR * ptd, HDC hicTargetDev, HDC hdcDraw, LPCRECTL lprectl, LPCRECTL lprcWBounds, BOOL (CALLBACK * pfnContinue) (DWORD), DWORD dwContinue); virtual HRESULT RenderThumbnail(DWORD dwDrawAspect, LONG lindex, void FAR* pvAspect, DVTARGETDEVICE FAR * ptd, HDC hicTargetDev, HDC hdcDraw, LPCRECTL lprectl, LPCRECTL lprcWBounds, BOOL (CALLBACK * pfnContinue) (DWORD), DWORD dwContinue); BOOL IsInNoScrible(void); virtual HRESULT Init(LPCLASSDESCRIPTOR pClass, LPSRVRCTRL pCtrl); virtual HRESULT Init(LPCLASSDESCRIPTOR pClass, LPSRVRDV pDV); protected: // //DERIVED: The derived class should override these methods to perform // persistent serialization and deserialization. These are used in the // implementation of IPersistStream/Storage/File // virtual HRESULT LoadFromStream(LPSTREAM pStrm); virtual HRESULT SaveToStream(LPSTREAM pStrm); virtual DWORD GetStreamSizeMax(void); virtual HRESULT LoadFromStorage(LPSTORAGE pStg); virtual HRESULT SaveToStorage(LPSTORAGE pStg, BOOL fSameAsLoad); // // constructors, initializers, and destructors // SrvrDV(void); virtual ~SrvrDV(void); LPCLASSDESCRIPTOR _pClass; // global info about our OLE server LPSRVRCTRL _pCtrl; // control of server aggregate or // NULL if transfer object // // IDataObject-related members // LPMONIKER _pmk; // moniker used for LINKSOURCE LPWSTR _lpstrDisplayName; // cached display name of moniker SIZEL _sizel; // used for OBJECTDESCRIPTOR and Extent LPDATAADVISEHOLDER _pDataAdviseHolder; // //DERIVED: The derived class must supply table of Get functions // and a table of Set functions parallel to the FORMATETC tables // in the class descriptor. // LPFNGETDATA FAR* _pGetFuncs; // GetData(Here) function table LPFNSETDATA FAR* _pSetFuncs; // SetData function table LPVIEWADVISEHOLDER _pViewAdviseHolder; unsigned _fFrozen: 1; // blocked from updating unsigned _fDirty: 1; // TRUE iff persistent data has changed unsigned _fNoScribble: 1; // between save and save completed // IPersistStorage-related members LPSTORAGE _pStg; // our home IStorage instance }; //+--------------------------------------------------------------- // // Member: SrvrDV::IsInNoScrible, public // // Synopsis: Answers wether we are currently in no-scribble mode // //--------------------------------------------------------------- inline BOOL SrvrDV::IsInNoScrible(void) { return _fNoScribble; } //+--------------------------------------------------------------- // // Class: SrvrInPlace // // Purpose: Inplace subobject of OLE compound document server // // Notes: This class supports the IOleInPlaceObject and // IOleInPlaceActiveObject interfaces. // //--------------------------------------------------------------- class SrvrInPlace: public IOleInPlaceObject, public IOleInPlaceActiveObject { public: //DERIVED: IUnknown methods are left pure virtual and must be implemented // by the derived class // IOleWindow interface methods STDMETHOD(GetWindow) (HWND FAR* lphwnd); STDMETHOD(ContextSensitiveHelp) (BOOL fEnterMode); // IOleInPlaceObject interface methods STDMETHOD(InPlaceDeactivate) (void); STDMETHOD(UIDeactivate) (void); STDMETHOD(SetObjectRects) (LPCRECT lprcPosRect, LPCRECT lprcClipRect); STDMETHOD(ReactivateAndUndo) (void); // IOleInPlaceActiveObject methods STDMETHOD(TranslateAccelerator) (LPMSG lpmsg); STDMETHOD(OnFrameWindowActivate) (BOOL fActivate); STDMETHOD(OnDocWindowActivate) (BOOL fActivate); STDMETHOD(ResizeBorder) (LPCRECT lprectBorder, LPOLEINPLACEUIWINDOW lpUIWindow, BOOL fFrameWindow); STDMETHOD(EnableModeless) (BOOL fEnable); // methods and members required by the other subobjects. HWND WindowHandle(void); void SetChildActivating(BOOL fGoingActive); BOOL GetChildActivating(void); BOOL IsDeactivating(void); void ReflectState(BOOL fUIActive); LPOLEINPLACEFRAME _pFrame; // our in-place active frame LPOLEINPLACEUIWINDOW _pDoc; // our in-place active document //DERIVED: These methods are called by the control to effect a // state transition. The derived class can override these methods if // it requires additional processing. virtual HRESULT ActivateInPlace(IOleClientSite *pClientSite); virtual HRESULT DeactivateInPlace(void); virtual HRESULT ActivateUI(void); virtual HRESULT DeactivateUI(void); //DERIVED: These methods are related to U.I. activation. The derived // class should override these to perform additional processing for // any frame, document, or floating toolbars or palettes. virtual void InstallUI(void); virtual void RemoveUI(void); LPOLEINPLACESITE _pInPlaceSite; // our in-place client site virtual HRESULT Init(LPCLASSDESCRIPTOR pClass, LPSRVRCTRL pCtrl); protected: //DERIVED: More U.I. activation-related methods. virtual void CreateUI(void); virtual void DestroyUI(void); virtual void InstallFrameUI(void); virtual void RemoveFrameUI(void); virtual void InstallDocUI(void); virtual void RemoveDocUI(void); virtual void ClearSelection(void); virtual void SetFocus(HWND hwnd); //DERIVED: The derived class must override this function to // attach the servers in-place active window. virtual HWND AttachWin(HWND hwndParent) = 0; virtual void DetachWin(void); SrvrInPlace(void); virtual ~SrvrInPlace(void); LPCLASSDESCRIPTOR _pClass; // global info about our class LPSRVRCTRL _pCtrl; // the control we are part of. // IOleInPlaceObject-related members unsigned _fUIDown: 1; // menu/tools integrated with container? unsigned _fChildActivating: 1; // site going UIActive? unsigned _fDeactivating: 1; // being deactivated from the outside? unsigned _fCSHelpMode: 1; // in context-sensitive help state? OLEINPLACEFRAMEINFO _frameInfo; // accelerator information from our container InPlaceBorder _IPB; // our In-Place border when UIActive RECT _rcFrame; // our frame rect HWND _hwnd; // our InPlace window HMENU _hmenu; HOLEMENU _hOleMenu; // menu registered w/ OLE HMENU _hmenuShared; // the shared menu when we are UI active OLEMENUGROUPWIDTHS _mgw; // menu interleaving information BOOL _fClientResize; // TRUE during calls to SetObjectRects }; //+--------------------------------------------------------------- // // Member: SrvrInPlace::IsDeactivating, public // // Synopsis: Gets value of a flag indicating deactivation // (from the outside) in progress // //--------------------------------------------------------------- inline BOOL SrvrInPlace::IsDeactivating(void) { return _fDeactivating; } //+--------------------------------------------------------------- // // Member: SrvrInPlace::GetChildActivating, public // // Synopsis: Gets value of a flag indicating that a child is // activating to prevent menu flashing // //--------------------------------------------------------------- inline BOOL SrvrInPlace::GetChildActivating(void) { return _fChildActivating; } //+--------------------------------------------------------------- // // Member: SrvrInPlace::SetChildActivating, public // // Synopsis: Sets or clears a flag indicating that a child is // activating to prevent menu flashing // //--------------------------------------------------------------- inline void SrvrInPlace::SetChildActivating(BOOL fGoingActive) { _fChildActivating = fGoingActive; } //+--------------------------------------------------------------- // // Member: SrvrInPlace::WindowHandle, public // // Synopsis: Returns object window handle // //--------------------------------------------------------------- inline HWND SrvrInPlace::WindowHandle(void) { return _hwnd; } //+--------------------------------------------------------------- // // Member: SrvrInPlace::ReflectState, public // // Synopsis: TBD // //--------------------------------------------------------------- inline void SrvrInPlace::ReflectState(BOOL fActive) { if(_pCtrl->IsIPBEnabled()) { _IPB.SetUIActive(fActive); } } #endif // !RC_INVOKED #endif //_O2BASE_HXX_