IE原始碼摘抄,基於洩漏的IE5.0(持續更新)

Ox9A82發表於2016-08-25

下載了一份很久以前洩漏的IE5.0的原始碼,雖然已經是很古遠的版本了。但是透過除錯現有版本瀏覽器與檢視原始碼,發現關鍵部分的差距並不是很大,程式碼很有參考意義。這裡把重要的函式、資料結構摘抄出來以備參考。

  1 class NOVTABLE CTreeNode : public CVoid
  2 {
  3     friend class CTreePos;
  4 
  5     DECLARE_CLASS_TYPES(CTreeNode, CVoid)
  6 
  7 public:
  8     DECLARE_MEMCLEAR_NEW_DELETE();
  9 
 10     CTreeNode(CTreeNode* pParent, CElement* pElement=NULL);
 11 
 12     // Use this to get an interface to the element/node
 13     HRESULT GetElementInterface(REFIID riid, void** ppUnk);
 14 
 15     // NOTE: these functions may look like IUnknown functions
 16     //       but don't make that mistake.  They are here to
 17     //       manage creation of the tearoff to handle all
 18     //       external references.
 19     // These functions should not be called!
 20     NV_DECLARE_TEAROFF_METHOD(GetInterface, getinterface, (REFIID riid, LPVOID* ppv));
 21     NV_DECLARE_TEAROFF_METHOD_(ULONG, PutRef, putref, ());
 22     NV_DECLARE_TEAROFF_METHOD_(ULONG, RemoveRef, removeref, ());
 23 
 24     // These functions are to be used to keep a node/element
 25     // combination alive while it may leave the tree.
 26     // BEWARE: this may cause the creation of a tearoff.
 27     ULONG   NodeAddRef();
 28     ULONG   NodeRelease();
 29 
 30     // These functions manage the _fInMarkup bit
 31     void    PrivateEnterTree();
 32     void    PrivateExitTree();
 33     void    PrivateMakeDead();
 34     void    PrivateMarkupRelease();
 35 
 36     void    SetElement(CElement* pElement);
 37     void    SetParent(CTreeNode* pNodeParent);
 38 
 39     // Element access and structure methods
 40     CElement*   Element()       { return _pElement; }
 41     CElement*   SafeElement()   { return this?_pElement:NULL; }
 42 
 43     CTreePos*   GetBeginPos()   { return &_tpBegin; }
 44     CTreePos*   GetEndPos()     { return &_tpEnd;   }
 45 
 46     // Context chain access
 47     BOOL        IsFirstBranch() { return _tpBegin.IsEdgeScope(); }
 48     BOOL        IsLastBranch()  { return _tpEnd.IsEdgeScope(); }
 49     CTreeNode*  NextBranch();
 50     CTreeNode*  PreviousBranch();
 51 
 52     CDocument*  Doc();
 53 
 54     BOOL            IsInMarkup()    { return _fInMarkup; }
 55     BOOL            IsDead()        { return ! _fInMarkup; }
 56     CRootElement*   IsRoot();
 57     CMarkup*        GetMarkup();
 58     CRootElement*   MarkupRoot();
 59 
 60     // Does the element that this node points to have currency?
 61     BOOL        HasCurrency();
 62 
 63     BOOL        IsContainer();
 64     CTreeNode*  GetContainerBranch();
 65     CElement*   GetContainer()      { return GetContainerBranch()->SafeElement(); }
 66 
 67     BOOL        SupportsHtml();
 68 
 69     CTreeNode*  Parent()            { return _pNodeParent; }
 70 
 71     CTreeNode*  Ancestor(ELEMENT_TAG etag);
 72     CTreeNode*  Ancestor(ELEMENT_TAG* arytag);
 73 
 74     CElement*   ZParent()           { return ZParentBranch()->SafeElement(); }
 75     CTreeNode*  ZParentBranch();
 76 
 77     CElement*   RenderParent()      { return RenderParentBranch()->SafeElement(); }
 78     CTreeNode*  RenderParentBranch();
 79 
 80     CElement*   ClipParent()        { return ClipParentBranch()->SafeElement(); }
 81     CTreeNode*  ClipParentBranch();
 82 
 83     CElement*   ScrollingParent()   { return ScrollingParentBranch()->SafeElement(); }
 84     CTreeNode*  ScrollingParentBranch();
 85 
 86     inline ELEMENT_TAG Tag()        { return (ELEMENT_TAG)_etag; }
 87 
 88     ELEMENT_TAG TagType()
 89     {
 90         switch(_etag)
 91         {
 92         case ETAG_GENERIC_LITERAL:
 93         case ETAG_GENERIC_BUILTIN:
 94             return ETAG_GENERIC;
 95         default:
 96             return (ELEMENT_TAG)_etag;
 97         }
 98     }
 99 
100     CTreeNode* GetFirstCommonAncestor(CTreeNode* pNode, CElement* pEltStop);
101     CTreeNode* GetFirstCommonBlockOrLayoutAncestor(CTreeNode* pNodeTwo, CElement* pEltStop);
102     CTreeNode* GetFirstCommonAncestorNode(CTreeNode* pNodeTwo, CElement* pEltStop);
103 
104     CTreeNode* SearchBranchForPureBlockElement(CFlowLayout*);
105     CTreeNode* SearchBranchToFlowLayoutForTag(ELEMENT_TAG etag);
106     CTreeNode* SearchBranchToRootForTag(ELEMENT_TAG etag);
107     CTreeNode* SearchBranchToRootForScope(CElement* pElementFindMe);
108     BOOL       SearchBranchToRootForNode(CTreeNode* pNodeFindMe);
109 
110     CTreeNode* GetCurrentRelativeNode(CElement* pElementFL);
111 
112     // The layout attached to the current element may not be accurate, when a
113     // property changes, current element can gain/lose layoutness. When an
114     // element gains/loses layoutness, its layout is created/destroyed lazily.
115     //
116     // So, for the following functions "cur" means return the layout currently
117     // associated with the layout which may not be accurate. "Updated" means
118     // compute the state and return the accurate information.
119     //
120     // Note: Calling "Updated" function may cause the formats to be computed.
121     //
122     // If there is any confusion please talk to (srinib/lylec/brendand)
123     inline  CLayout*    GetCurLayout();
124     inline  BOOL        HasLayout();
125 
126     CLayout*            GetCurNearestLayout();
127     CTreeNode*          GetCurNearestLayoutNode();
128     CElement*           GetCurNearestLayoutElement();
129 
130     CLayout*            GetCurParentLayout();
131     CTreeNode*          GetCurParentLayoutNode();
132     CElement*           GetCurParentLayoutElement();
133 
134     // the following get functions may create the layout if it is not
135     // created yet.
136     inline  CLayout*    GetUpdatedLayout();     // checks for NeedsLayout()
137     inline  CLayout*    GetUpdatedLayoutPtr();  // Call this if NeedsLayout() is already called
138     inline  BOOL        NeedsLayout();
139 
140     CLayout*            GetUpdatedNearestLayout();
141     CTreeNode*          GetUpdatedNearestLayoutNode();
142     CElement*           GetUpdatedNearestLayoutElement();
143 
144     CLayout*            GetUpdatedParentLayout();
145     CTreeNode*          GetUpdatedParentLayoutNode();
146     CElement*           GetUpdatedParentLayoutElement();
147 
148     // BUGBUG - these functions should go, we should not need
149     // to know if the element has flowlayout.
150     CFlowLayout*        GetFlowLayout();
151     CTreeNode*          GetFlowLayoutNode();
152     CElement*           GetFlowLayoutElement();
153     CFlowLayout*        HasFlowLayout();
154 
155     // Helper methods
156     htmlBlockAlign      GetParagraphAlign(BOOL fOuter);
157     htmlControlAlign    GetSiteAlign();
158 
159     BOOL                IsInlinedElement();
160 
161     BOOL                IsPositionStatic(void);
162     BOOL                IsPositioned(void);
163     BOOL                IsAbsolute(stylePosition st);
164     BOOL                IsAbsolute(void);
165 
166     BOOL                IsAligned();
167 
168     // IsRelative() tells you if the specific element has had a CSS position
169     // property set on it ( by examining _fRelative and _bPositionType on the
170     // FF).  It will NOT tell you if something is relative because one of its
171     // ancestors is relative; that information is stored in the CF, and can be
172     // had via IsInheritingRelativeness()
173     BOOL IsRelative(stylePosition st);
174     BOOL IsRelative(void);
175     BOOL IsInheritingRelativeness(void);
176 
177     BOOL IsScrollingParent(void);
178     BOOL IsClipParent(void);
179     BOOL IsZParent(void);
180     BOOL IsDisplayNone(void);
181     BOOL IsVisibilityHidden(void);
182 
183     // Depth is defined to be 1 plus the count of parents above this element
184     int  Depth() const;
185 
186     // Format info functions
187     HRESULT             CacheNewFormats(CFormatInfo* pCFI);
188 
189     void                EnsureFormats();
190     BOOL                IsCharFormatValid()     { return _iCF>=0; }
191     BOOL                IsParaFormatValid()     { return _iPF>=0; }
192     BOOL                IsFancyFormatValid()    { return _iFF>=0; }
193     const CCharFormat*  GetCharFormat()         { return (_iCF>=0 ? ::GetCharFormatEx(_iCF) : GetCharFormatHelper()); }
194     const CParaFormat*  GetParaFormat()         { return (_iPF>=0 ? ::GetParaFormatEx(_iPF) : GetParaFormatHelper()); }
195     const CFancyFormat* GetFancyFormat()        { return (_iFF>=0 ? ::GetFancyFormatEx(_iFF) : GetFancyFormatHelper()); }
196     const CCharFormat*  GetCharFormatHelper();
197     const CParaFormat*  GetParaFormatHelper();
198     const CFancyFormat* GetFancyFormatHelper();
199     long                GetCharFormatIndex()    { return (_iCF>=0 ? _iCF : GetCharFormatIndexHelper()); }
200     long                GetParaFormatIndex()    { return (_iPF>=0 ? _iPF : GetParaFormatIndexHelper()); }
201     long                GetFancyFormatIndex()   { return (_iFF>=0 ? _iFF : GetFancyFormatIndexHelper()); }
202     long                GetCharFormatIndexHelper();
203     long                GetParaFormatIndexHelper();
204     long                GetFancyFormatIndexHelper();
205 
206     long                GetFontHeightInTwips(CUnitValue* pCuv);
207     void                GetRelTopLeft(CElement* pElementFL, CParentInfo* ppi, long* pxOffset, long* pyOffset);
208 
209     // These GetCascaded methods are taken from style.hdl where they were
210     // originally generated by the PDL parser.
211     CColorValue        GetCascadedbackgroundColor();
212     CColorValue        GetCascadedcolor();
213     CUnitValue         GetCascadedletterSpacing();
214     styleTextTransform GetCascadedtextTransform();
215     CUnitValue         GetCascadedpaddingTop();
216     CUnitValue         GetCascadedpaddingRight();
217     CUnitValue         GetCascadedpaddingBottom();
218     CUnitValue         GetCascadedpaddingLeft();
219     CColorValue        GetCascadedborderTopColor();
220     CColorValue        GetCascadedborderRightColor();
221     CColorValue        GetCascadedborderBottomColor();
222     CColorValue        GetCascadedborderLeftColor();
223     styleBorderStyle   GetCascadedborderTopStyle();
224     styleBorderStyle   GetCascadedborderRightStyle();
225     styleBorderStyle   GetCascadedborderBottomStyle();
226     styleBorderStyle   GetCascadedborderLeftStyle();
227     CUnitValue         GetCascadedborderTopWidth();
228     CUnitValue         GetCascadedborderRightWidth();
229     CUnitValue         GetCascadedborderBottomWidth();
230     CUnitValue         GetCascadedborderLeftWidth();
231     CUnitValue         GetCascadedwidth();
232     CUnitValue         GetCascadedheight();
233     CUnitValue         GetCascadedtop();
234     CUnitValue         GetCascadedbottom();
235     CUnitValue         GetCascadedleft();
236     CUnitValue         GetCascadedright();
237     styleOverflow      GetCascadedoverflowX();
238     styleOverflow      GetCascadedoverflowY();
239     styleOverflow      GetCascadedoverflow();
240     styleStyleFloat    GetCascadedfloat();
241     stylePosition      GetCascadedposition();
242     long               GetCascadedzIndex();
243     CUnitValue         GetCascadedclipTop();
244     CUnitValue         GetCascadedclipLeft();
245     CUnitValue         GetCascadedclipRight();
246     CUnitValue         GetCascadedclipBottom();
247     BOOL               GetCascadedtableLayout();    // fixed - 1, auto - 0
248     BOOL               GetCascadedborderCollapse(); // collapse - 1, separate - 0
249     BOOL               GetCascadedborderOverride();
250     WORD               GetCascadedfontWeight();
251     WORD               GetCascadedfontHeight();
252     CUnitValue         GetCascadedbackgroundPositionX();
253     CUnitValue         GetCascadedbackgroundPositionY();
254     BOOL               GetCascadedbackgroundRepeatX();
255     BOOL               GetCascadedbackgroundRepeatY();
256     htmlBlockAlign     GetCascadedblockAlign();
257     styleVisibility    GetCascadedvisibility();
258     styleDisplay       GetCascadeddisplay();
259     BOOL               GetCascadedunderline();
260     styleAccelerator   GetCascadedaccelerator();
261     BOOL               GetCascadedoverline();
262     BOOL               GetCascadedstrikeOut();
263     CUnitValue         GetCascadedlineHeight();
264     CUnitValue         GetCascadedtextIndent();
265     BOOL               GetCascadedsubscript();
266     BOOL               GetCascadedsuperscript();
267     BOOL               GetCascadedbackgroundAttachmentFixed();
268     styleListStyleType GetCascadedlistStyleType();
269     styleListStylePosition GetCascadedlistStylePosition();
270     long               GetCascadedlistImageCookie();
271     const TCHAR*       GetCascadedfontFaceName();
272     const TCHAR*       GetCascadedfontFamilyName();
273     BOOL               GetCascadedfontItalic();
274     long               GetCascadedbackgroundImageCookie();
275     BOOL               GetCascadedclearLeft();
276     BOOL               GetCascadedclearRight();
277     styleCursor        GetCascadedcursor();
278     styleTableLayout   GetCascadedtableLayoutEnum();
279     styleBorderCollapse GetCascadedborderCollapseEnum();
280     styleDir           GetCascadedBlockDirection();
281     styleDir           GetCascadeddirection();
282     styleBidi          GetCascadedunicodeBidi();
283     styleLayoutGridMode GetCascadedlayoutGridMode();
284     styleLayoutGridType GetCascadedlayoutGridType();
285     CUnitValue         GetCascadedlayoutGridLine();
286     CUnitValue         GetCascadedlayoutGridChar();
287     LONG               GetCascadedtextAutospace();
288     styleWordBreak     GetCascadedwordBreak();
289     styleLineBreak     GetCascadedlineBreak();
290     styleTextJustify   GetCascadedtextJustify();
291     styleTextJustifyTrim GetCascadedtextJustifyTrim();
292     CUnitValue         GetCascadedmarginTop();
293     CUnitValue         GetCascadedmarginRight();
294     CUnitValue         GetCascadedmarginBottom();
295     CUnitValue         GetCascadedmarginLeft();
296     CUnitValue         GetCascadedtextKashida();
297 
298     // Ref helpers
299     // Right now these just drop right through to the element
300     static void ReplacePtr      (CTreeNode** ppNodelhs, CTreeNode* pNoderhs);
301     static void SetPtr          (CTreeNode** ppNodelhs, CTreeNode* pNoderhs);
302     static void ClearPtr        (CTreeNode** ppNodelhs);
303     static void StealPtrSet     (CTreeNode** ppNodelhs, CTreeNode* pNoderhs);
304     static void StealPtrReplace (CTreeNode** ppNodelhs, CTreeNode* pNoderhs);
305     static void ReleasePtr      (CTreeNode*  pNode);
306 
307     // Other helpers
308     void VoidCachedInfo();
309     void VoidCachedNodeInfo();
310     void VoidFancyFormat();
311 
312     // Helpers for contained CTreePos's
313     CTreePos* InitBeginPos(BOOL fEdge)
314     {
315         _tpBegin.SetFlags(
316             (_tpBegin.GetFlags()&~(CTreePos::TPF_ETYPE_MASK|CTreePos::TPF_DATA_POS|CTreePos::TPF_EDGE))
317             | CTreePos::NodeBeg
318             | BOOLFLAG(fEdge, CTreePos::TPF_EDGE));
319         return &_tpBegin;
320     }
321 
322     CTreePos* InitEndPos(BOOL fEdge)
323     {
324         _tpEnd.SetFlags(
325             (_tpEnd.GetFlags()&~(CTreePos::TPF_ETYPE_MASK|CTreePos::TPF_DATA_POS|CTreePos::TPF_EDGE))
326             | CTreePos::NodeEnd
327             | BOOLFLAG(fEdge, CTreePos::TPF_EDGE));
328         return &_tpEnd;
329     }
330 
331     //+-----------------------------------------------------------------------
332     //
333     //  CTreeNode::CLock
334     //
335     //------------------------------------------------------------------------
336     class CLock
337     {
338     public:
339         DECLARE_MEMALLOC_NEW_DELETE()
340         CLock(CTreeNode* pNode);
341         ~CLock();
342 
343     private:
344         CTreeNode* _pNode;
345     };
346 
347     // Lookaside pointers
348     enum
349     {
350         LOOKASIDE_PRIMARYTEAROFF    = 0,
351         LOOKASIDE_CURRENTSTYLE      = 1,
352         LOOKASIDE_NODE_NUMBER       = 2
353         // *** There are only 2 bits reserved in the node.
354         // *** if you add more lookasides you have to make sure 
355         // *** that you make room for those bits.
356     };
357 
358     BOOL            HasLookasidePtr(int iPtr)                   { return (_fHasLookasidePtr&(1<<iPtr)); }
359     void*           GetLookasidePtr(int iPtr);
360     HRESULT         SetLookasidePtr(int iPtr, void* pv);
361     void*           DelLookasidePtr(int iPtr);
362 
363     // Primary Tearoff pointer management
364     BOOL            HasPrimaryTearoff()                         { return (HasLookasidePtr(LOOKASIDE_PRIMARYTEAROFF)); }
365     IUnknown*       GetPrimaryTearoff()                         { return ((IUnknown*)GetLookasidePtr(LOOKASIDE_PRIMARYTEAROFF)); }
366     HRESULT         SetPrimaryTearoff(IUnknown* pTearoff)       { return (SetLookasidePtr(LOOKASIDE_PRIMARYTEAROFF, pTearoff)); }
367     IUnknown*       DelPrimaryTearoff()                         { return ((IUnknown*)DelLookasidePtr(LOOKASIDE_PRIMARYTEAROFF)); }
368 
369     // Class Data
370     CElement*   _pElement;                          // The element for this node
371     CTreeNode*  _pNodeParent;                       // The parent in the CTreeNode tree
372 
373     // DWORD 1
374     BYTE        _etag;                              // 0-7:     element tag
375     BYTE        _fFirstCommonAncestorNode   : 1;    // 8:       for finding common ancestor
376     BYTE        _fInMarkup                  : 1;    // 9:       this node is in a markup and shouldn't die
377     BYTE        _fInMarkupDestruction       : 1;    // 10:      Used by CMarkup::DestroySplayTree
378     BYTE        _fHasLookasidePtr           : 2;    // 11-12    Lookaside flags
379     BYTE        _fBlockNess                 : 1;    // 13:      Cached from format -- valid if _iFF != -1
380     BYTE        _fHasLayout                 : 1;    // 14:      Cached from format -- valid if _iFF != -1
381     BYTE        _fUnused                    : 1;    // 15:      Unused
382 
383     SHORT       _iPF;                               // 16-31:   Paragraph Format
384 
385     // DWORD 2
386     SHORT       _iCF;                               // 0-15:    Char Format
387     SHORT       _iFF;                               // 16-31:   Fancy Format
388 
389 protected:
390     // Use GetBeginPos() or GetEndPos() to get at these members
391     CTreePos    _tpBegin;                           // The begin CTreePos for this node
392     CTreePos    _tpEnd;                             // The end CTreePos for this node
393 
394 public:
395     // STATIC MEMBERS
396     DECLARE_TEAROFF_TABLE_NAMED(s_apfnNodeVTable)
397 
398 private:
399     NO_COPY(CTreeNode);
400 };
class CTreeNode

 

 1 void CMarkup::FreeTreePos(CTreePos* ptp)
 2 {
 3     Assert(ptp);
 4 
 5     // set a sentinel to make the traversal terminate
 6     ptp->MarkFirst();
 7     ptp->SetNext(NULL);
 8 
 9     // release the subtree, adding its nodes to the free list
10     while(ptp)
11     {
12         if (ptp->FirstChild())
13         {
14             ptp = ptp->FirstChild();
15         }
16         else
17         {
18             CTreePos* ptpNext;
19             BOOL fRelease = TRUE;
20             while(fRelease)
21             {
22                 fRelease = ptp->IsLastChild();
23                 ptpNext = ptp->Next();
24                 ReleaseTreePos(ptp);
25                 ptp = ptpNext;
26             }
27         }
28     }
29 }
CTreePos的釋放函式 CMarkup::FreeTreePos

 

  1 class CElement : public CBase
  2 {
  3     DECLARE_CLASS_TYPES(CElement, CBase)
  4 
  5     friend class CDBindMethods;
  6     friend class CLayout;
  7     friend class CFlowLayout;
  8 
  9 private:
 10     DECLARE_MEMCLEAR_NEW_DELETE();
 11 
 12 public:
 13     CElement(ELEMENT_TAG etag, CDocument* pDoc);
 14     virtual ~CElement();
 15 
 16     CDocument* Doc() const { return GetDocPtr(); }
 17 
 18     // creating thunks with AddRef and Release set to peer holder, if present
 19     HRESULT CreateTearOffThunk(
 20         void*       pvObject1,
 21         const void* apfn1,
 22         IUnknown*   pUnkOuter,
 23         void**      ppvThunk,
 24         void*       appropdescsInVtblOrder=NULL);
 25 
 26     HRESULT CreateTearOffThunk(
 27         void*       pvObject1,
 28         const void* apfn1,
 29         IUnknown*   pUnkOuter,
 30         void**      ppvThunk,
 31         void*       pvObject2,
 32         void*       apfn2,
 33         DWORD       dwMask,
 34         const IID* const* apIID,
 35         void*       appropdescsInVtblOrder=NULL);
 36 
 37     CAttrArray** GetAttrArray() const
 38     {
 39         return CBase::GetAttrArray();
 40     }
 41     void SetAttrArray(CAttrArray* pAA)
 42     {
 43         CBase::SetAttrArray(pAA);
 44     }
 45 
 46     // *********************************************
 47     //
 48     // ENUMERATIONS, CLASSES, & STRUCTS
 49     //
 50     // *********************************************
 51     enum ELEMENTDESC_FLAG
 52     {
 53         ELEMENTDESC_DONTINHERITSTYLE= (1 << 1), // Do not inherit style from parent
 54         ELEMENTDESC_NOANCESTORCLICK = (1 << 2), // We don't want our ancestors to fire clicks
 55         ELEMENTDESC_NOTIFYENDPARSE  = (1 << 3), // We want to be notified when we're parsed
 56 
 57         ELEMENTDESC_OLESITE         = (1 << 4), // class derived from COleSite
 58         ELEMENTDESC_OMREADONLY      = (1 << 5), // element's value can not be accessed through OM (input/file)
 59         ELEMENTDESC_ALLOWSCROLLING  = (1 << 6), // allow scrolling
 60         ELEMENTDESC_HASDEFDESCENT   = (1 << 7), // use 4 pixels descent for default vertical alignment
 61         ELEMENTDESC_BODY            = (1 << 8), // class is used the BODY element
 62         ELEMENTDESC_TEXTSITE        = (1 << 9), // class derived from CTxtSite
 63         ELEMENTDESC_ANCHOROUT       = (1 <<10), // draw anchor border outside site/inside
 64         ELEMENTDESC_SHOWTWS         = (1 <<11), // show trailing whitespaces
 65         ELEMENTDESC_XTAG            = (1 <<12), // an xtag - derived from CXElement
 66         ELEMENTDESC_NOOFFSETCTX     = (1 <<13), // Shift-F10 context menu shows on top-left (not offset)
 67         ELEMENTDESC_CARETINS_SL     = (1 <<14), // Dont select site after inserting site
 68         ELEMENTDESC_CARETINS_DL     = (1 <<15), // show caret (SameLine or DifferntLine)
 69         ELEMENTDESC_NOSELECT        = (1 <<16), // do not select site in edit mode
 70         ELEMENTDESC_TABLECELL       = (1 <<17), // site is a table cell. Also implies do not
 71                                                 // word break before sites.
 72         ELEMENTDESC_VPADDING        = (1 <<18), // add a pixel vertical padding for this site
 73         ELEMENTDESC_EXBORDRINMOV    = (1 <<19), // Exclude the border in CSite::Move
 74         ELEMENTDESC_DEFAULT         = (1 <<20), // acts like a default site to receive return key
 75         ELEMENTDESC_CANCEL          = (1 <<21), // acts like a cancel site to receive esc key
 76         ELEMENTDESC_NOBKGRDRECALC   = (1 <<22), // Dis-allow background recalc
 77         ELEMENTDESC_NOPCTRESIZE     = (1 <<23), // Don't force resize due to percentage height/width
 78         ELEMENTDESC_NOLAYOUT        = (1 <<24), // element's like script and comment etc. cannot have layout
 79         ELEMENTDESC_NEVERSCROLL     = (1 <<26), // element can scroll
 80         ELEMENTDESC_CANSCROLL       = (1 <<27), // element can scroll
 81         ELEMENTDESC_LAST            = ELEMENTDESC_CANSCROLL,
 82         ELEMENTDESC_MAX             = LONG_MAX  // Force enum to DWORD on Macintosh.
 83     };
 84 
 85     NV_DECLARE_TEAROFF_METHOD(IsEqualObject, isequalobject, (IUnknown* ppunk));
 86 
 87     // ******************************************
 88     //
 89     // Virtual overrides
 90     //
 91     // ******************************************
 92     virtual void Passivate();
 93 
 94     DECLARE_PLAIN_IUNKNOWN(CElement);
 95 
 96     STDMETHOD(PrivateQueryInterface)(REFIID, void**);
 97     STDMETHOD_(ULONG, PrivateAddRef)();
 98     STDMETHOD_(ULONG, PrivateRelease)();
 99 
100     void PrivateEnterTree();
101     void PrivateExitTree(CMarkup* pMarkupOld);
102 
103     virtual HRESULT OnPropertyChange(DISPID dispid, DWORD dwFlags);
104 
105     virtual HRESULT GetNaturalExtent(DWORD dwExtentMode, SIZEL* psizel) { return E_FAIL; }
106 
107     typedef enum
108     {
109         GETINFO_ISCOMPLETED,    // Has loading of an element completed
110         GETINFO_HISTORYCODE     // Code used to validate history
111     } GETINFO;
112 
113     virtual DWORD GetInfo(GETINFO gi);
114 
115     DWORD HistoryCode() { return GetInfo(GETINFO_HISTORYCODE); }
116 
117     NV_DECLARE_TEAROFF_METHOD(get_tabIndex, GET_tabIndex, (short*));
118 
119     // The dir property is declared baseimplementation in the pdl.
120     // We need prototype here
121     NV_DECLARE_TEAROFF_METHOD(put_dir, PUT_dir, (BSTR v));
122     NV_DECLARE_TEAROFF_METHOD(get_dir, GET_dir, (BSTR* p));
123 
124     // these delegaters implement redirection to the window object
125     NV_DECLARE_TEAROFF_METHOD(get_onload, GET_onload, (VARIANT*));
126     NV_DECLARE_TEAROFF_METHOD(put_onload, PUT_onload, (VARIANT));
127     NV_DECLARE_TEAROFF_METHOD(get_onunload, GET_onunload, (VARIANT*));
128     NV_DECLARE_TEAROFF_METHOD(put_onunload, PUT_onunload, (VARIANT));
129     NV_DECLARE_TEAROFF_METHOD(get_onfocus, GET_onfocus, (VARIANT*));
130     NV_DECLARE_TEAROFF_METHOD(put_onfocus, PUT_onfocus, (VARIANT));
131     NV_DECLARE_TEAROFF_METHOD(get_onblur, GET_onblur, (VARIANT*));
132     NV_DECLARE_TEAROFF_METHOD(put_onblur, PUT_onblur, (VARIANT));
133     NV_DECLARE_TEAROFF_METHOD(get_onbeforeunload, GET_onbeforeunload, (VARIANT*));
134     NV_DECLARE_TEAROFF_METHOD(put_onbeforeunload, PUT_onbeforeunload, (VARIANT));
135     NV_DECLARE_TEAROFF_METHOD(get_onhelp, GET_onhelp, (VARIANT*));
136     NV_DECLARE_TEAROFF_METHOD(put_onhelp, PUT_onhelp, (VARIANT));
137 
138     NV_DECLARE_TEAROFF_METHOD(get_onscroll, GET_onscroll, (VARIANT*));
139     NV_DECLARE_TEAROFF_METHOD(put_onscroll, PUT_onscroll, (VARIANT));
140     NV_DECLARE_TEAROFF_METHOD(get_onresize, GET_onresize, (VARIANT*));
141     NV_DECLARE_TEAROFF_METHOD(put_onresize, PUT_onresize, (VARIANT));
142 
143     // non-abstract getters for tagName and scopeName. See element.pdl
144     NV_DECLARE_TEAROFF_METHOD(GettagName, gettagname, (BSTR*));
145 
146     // IServiceProvider methods
147     NV_DECLARE_TEAROFF_METHOD(QueryService, queryservice, (REFGUID guidService, REFIID iid, LPVOID* ppv));
148 
149     virtual CAtomTable* GetAtomTable(BOOL* pfExpando=NULL);
150 
151     // init / deinit methods
152     class CInit2Context
153     {
154     public:
155         CInit2Context(CHtmTag* pht, CMarkup* pTargetMarkup, DWORD dwFlags) :
156           _pTargetMarkup(pTargetMarkup), _pht(pht), _dwFlags(dwFlags)
157           {
158           }
159 
160           CInit2Context(CHtmTag* pht, CMarkup* pTargetMarkup) :
161           _pTargetMarkup(pTargetMarkup), _pht(pht), _dwFlags(0)
162           {
163           }
164 
165           CHtmTag*  _pht;
166           CMarkup*  _pTargetMarkup;
167           DWORD     _dwFlags;
168     };
169 
170     virtual HRESULT Init();
171     virtual HRESULT Init2(CInit2Context* pContext);
172 
173     HRESULT         InitAttrBag(CHtmTag* pht);
174     HRESULT         MergeAttrBag(CHtmTag* pht);
175 
176     virtual void    Notify (CNotification* pnf);
177 
178     HRESULT         EnterTree();
179     void            ExitTree(DWORD dwExitFlags);
180 
181     // other
182     CBase*          GetOmWindow(void);
183 
184     // Get the Base Object that owns the attr array for a given property
185     // Allows us to re-direct properties to another objects storage
186     CBase*          GetBaseObjectFor(DISPID dispID);
187 
188     // Pass the call to the form.
189     //-------------------------------------------------------------------------
190     //  +override : special process
191     //  +call super : first
192     //  -call parent : no
193     //  -call children : no
194     //-------------------------------------------------------------------------
195     virtual HRESULT CloseErrorInfo(HRESULT hr);
196 
197     // Scrolling methods
198     // Scroll this element into view
199     virtual HRESULT ScrollIntoView(
200         SCROLLPIN spVert=SP_MINIMAL,
201         SCROLLPIN spHorz=SP_MINIMAL,
202         BOOL fScrollBits=TRUE);
203 
204     HRESULT DeferScrollIntoView(
205         SCROLLPIN spVert=SP_MINIMAL,
206         SCROLLPIN spHorz=SP_MINIMAL);
207 
208     NV_DECLARE_ONCALL_METHOD(DeferredScrollIntoView, deferredscrollintoview, (DWORD_PTR dwParam));
209 
210     // Relative element (non-site) helper methods
211     virtual HTC HitTestPoint(CMessage* pMessage, CTreeNode** ppNodeElement, DWORD dwFlags);
212 
213     BOOL CanHandleMessage()
214     {
215         return (HasLayout())?(IsEnabled()&&IsVisible(TRUE)):(TRUE);
216     }
217 
218     // STDMETHODCALLTYPE required when passing fn through generic ptr
219     virtual HRESULT STDMETHODCALLTYPE HandleMessage(CMessage* pMessage);
220 
221     HRESULT STDMETHODCALLTYPE HandleCaptureMessage(CMessage* pMessage)
222     {
223         return HandleMessage(pMessage);
224     }
225 
226     // marka these are to be DELETED !!
227     BOOL    DisallowSelection();
228 
229     // set the state of the IME.
230     HRESULT SetImeState();
231     HRESULT ComputeExtraFormat(DISPID dispID, BOOL fInherits, CTreeNode* pTreeNode, VARIANT* pVarReturn);
232 
233     // DoClick() is called by click(). It is also called internally in response
234     // to a mouse click by user.
235     // DoClick() fires the click event and then calls ClickAction() if the event
236     // is not cancelled.
237     // Derived classes can override ClickAction() to provide specific functionality.
238     virtual HRESULT DoClick(
239         CMessage*   pMessage=NULL,
240         CTreeNode*  pNodeContext=NULL,
241         BOOL        fFromLabel=FALSE);
242     virtual HRESULT ClickAction(CMessage* pMessage);
243 
244     virtual HRESULT ShowTooltip(CMessage* pmsg, POINT pt);
245 
246     HRESULT SetCursorStyle(LPCTSTR pstrIDC, CTreeNode* pNodeContext=NULL);
247 
248     void    Invalidate();
249 
250     // Element rect and element invalidate support
251     enum GERC_FLAGS
252     {
253         GERC_ONALINE = 1,
254         GERC_CLIPPED = 2
255     };
256 
257     void    GetElementRegion(CDataAry<RECT>* paryRects, RECT* prcBound=NULL, DWORD dwFlags=0);
258     HRESULT GetElementRc(RECT* prc, DWORD dwFlags, POINT* ppt=NULL);
259 
260     // these helper functions return in container coordinates
261     void    GetBoundingSize(SIZE& sz);
262     HRESULT GetBoundingRect(CRect* pRect, DWORD dwFlags=0);
263     HRESULT GetElementTopLeft(POINT& pt);
264 
265     // helper to return the actual background color
266     COLORREF GetInheritedBackgroundColor(CTreeNode* pNodeContext=NULL);
267     HRESULT  GetInheritedBackgroundColorValue(CColorValue* pVal, CTreeNode* pNodeContext=NULL);
268     virtual HRESULT GetColors(CColorInfo* pCI);
269     COLORREF GetBackgroundColor()
270     {
271         CTreeNode* pNodeContext = GetFirstBranch();
272         CTreeNode* pNodeParent  = pNodeContext->Parent() ? pNodeContext->Parent() : pNodeContext;
273 
274         return pNodeParent->Element()->GetInheritedBackgroundColor(pNodeParent);
275     }
276 
277     // Events related stuff
278     //--------------------------------------------------------------------------------------
279     inline BOOL ShouldFireEvents() { return _fEventListenerPresent; }
280     inline void SetEventsShouldFire() { _fEventListenerPresent = TRUE;  }
281     BOOL    FireCancelableEvent(DISPID dispidMethod, DISPID dispidProp, LPCTSTR pchEventType, BYTE* pbTypes, ...);
282     BOOL    BubbleCancelableEvent(CTreeNode* pNodeContext, long lSubDivision, DISPID dispidMethod, DISPID dispidProp, LPCTSTR pchEventType, BYTE* pbTypes, ...);
283     HRESULT FireEventHelper(DISPID dispidMethod, DISPID dispidProp, BYTE* pbTypes,  ...);
284     HRESULT FireEvent(DISPID dispidMethod, DISPID dispidProp, LPCTSTR pchEventType, BYTE* pbTypes, ...);
285     HRESULT BubbleEvent(CTreeNode* pNodeContext, long lSubDivision, DISPID dispidMethod, DISPID dispidProp, LPCTSTR pchEventType, BYTE* pbTypes, ...);
286     HRESULT BubbleEventHelper(CTreeNode* pNodeContext, long lSubDivision, DISPID dispidMethod, DISPID dispidProp, BOOL fRaisedByPeer, VARIANT* pvb, BYTE* pbTypes, ...);
287     virtual HRESULT DoSubDivisionEvents(long lSubDivision, DISPID dispidMethod, DISPID dispidProp, VARIANT* pvb, BYTE* pbTypes, ...);
288     HRESULT FireStdEventOnMessage(
289         CTreeNode* pNodeContext,
290         CMessage* pMessage,
291         CTreeNode* pNodeBeginBubbleWith=NULL,
292         CTreeNode* pNodeEvent=NULL);
293     BOOL FireStdEvent_KeyDown(CTreeNode* pNodeContext, CMessage* pMessage, int* piKeyCode, short shift);
294     BOOL FireStdEvent_KeyUp(CTreeNode* pNodeContext, CMessage* pMessage, int* piKeyCode, short shift);
295     BOOL FireStdEvent_KeyPress(CTreeNode* pNodeContext, CMessage* pMessage, int* piKeyCode);
296     BOOL FireStdEvent_MouseHelper(
297         CTreeNode*  pNodeContext,
298         CMessage *  pMessage,
299         DISPID      dispidMethod,
300         DISPID      dispidProp,
301         short       button,
302         short       shift,
303         float       x,
304         float       y,
305         CTreeNode*  pNodeFrom=NULL,
306         CTreeNode*  pNodeTo=NULL,
307         CTreeNode*  pNodeBeginBubbleWith=NULL,
308         CTreeNode* pNodeEvent=NULL);
309     void    Fire_onpropertychange(LPCTSTR strPropName);
310     void    Fire_onscroll();
311     HRESULT Fire_PropertyChangeHelper(DISPID dispid, DWORD dwFlags);
312 
313     void STDMETHODCALLTYPE Fire_onfocus(DWORD_PTR dwContext);
314     void STDMETHODCALLTYPE Fire_onblur(DWORD_PTR dwContext);
315 
316     BOOL DragElement(
317         CLayout*                    pFlowLayout,
318         DWORD                       dwStateKey,
319         IUniformResourceLocator*    pUrlToDrag,
320         long                        lSubDivision);
321 
322     BOOL Fire_ondragHelper(
323         long    lSubDivision,
324         DISPID  dispidEvent,
325         DISPID  dispidProp,
326         LPCTSTR pchType,
327         DWORD*  pdwDropEffect);
328     void Fire_ondragend(long lSubDivision, DWORD dwDropEffect);
329 
330     // Associated image context helpers
331     HRESULT GetImageUrlCookie(LPCTSTR lpszURL, long* plCtxCookie);
332     HRESULT AddImgCtx(DISPID dispID, LONG lCookie);
333     void    ReleaseImageCtxts();
334     void    DeleteImageCtx(DISPID dispid);
335 
336     // Internal events
337     HRESULT EnsureFormatCacheChange(DWORD dwFlags);
338     BOOL    IsFormatCacheValid();
339 
340     // Element Tree methods
341     BOOL IsAligned();
342     BOOL IsContainer();
343     BOOL IsNoScope();
344     BOOL IsBlockElement();
345     BOOL IsBlockTag();
346     BOOL IsOwnLineElement(CFlowLayout* pFlowLayoutContext);
347     BOOL IsRunOwner() { return _fOwnsRuns; }
348     BOOL BreaksLine();
349     BOOL IsTagAndBlock(ELEMENT_TAG eTag) { return Tag()==eTag&&IsBlockElement(); }
350     BOOL IsFlagAndBlock(TAGDESC_FLAGS flag) { return HasFlag(flag)&&IsBlockElement(); }
351 
352     HRESULT     ClearRunCaches(DWORD dwFlags);
353 
354     // Get the first branch for this element
355     CTreeNode*  GetFirstBranch() const { return __pNodeFirstBranch; }
356     CTreeNode*  GetLastBranch();
357     BOOL        IsOverlapped();
358 
359     // Get the CTreePos extent of this element
360     void        GetTreeExtent(CTreePos** pptpStart, CTreePos** pptpEnd);
361 
362     //-------------------------------------------------------------------------
363     //
364     // Layout related functions
365     //
366     //-------------------------------------------------------------------------
367 private:
368     BOOL HasLayoutLazy();   // should only be called by HasLayout
369     inline CLayout* GetLayoutLazy();
370     // Create the layout object to be associated with the current element
371     virtual HRESULT CreateLayout();
372 
373 public:
374     // CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION
375     // CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION
376     // (please read the comments below)
377     //
378     // The layout attached to the current element may not be accurate, when a
379     // property changes, current element can gain/lose layoutness. When an
380     // element gains/loses layoutness, its layout is created/destroyed lazily.
381     //
382     // So, for the following functions "cur" means return the layout currently
383     // associated with the layout which may not be accurate. "Updated" means
384     // compute the state and return the accurate information.
385     //
386     // Note: Calling "Updated" function may cause the formats to be computed.
387     //
388     // If there is any confusion please talk to (srinib/lylec/brendand)
389     CLayout*    GetCurLayout() { return GetLayoutPtr(); }
390     BOOL        HasLayout() { return !!HasLayoutPtr(); }
391 
392     CLayout*    GetCurNearestLayout();
393     CTreeNode*  GetCurNearestLayoutNode();
394     CElement*   GetCurNearestLayoutElement();
395 
396     CLayout*    GetCurParentLayout();
397     CTreeNode*  GetCurParentLayoutNode();
398     CElement*   GetCurParentLayoutElement();
399 
400     // CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION
401     // CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION
402     // (please read the comments above)
403     //
404     //
405     // the following get functions may create the layout if it is not
406     // created yet.
407     inline CLayout*     GetUpdatedLayout();     // checks for NeedsLayout()
408     inline CLayout*     GetUpdatedLayoutPtr();  // Call this if NeedsLayout() is already called
409     inline BOOL         NeedsLayout();
410 
411     CLayout*            GetUpdatedNearestLayout();
412     CTreeNode*          GetUpdatedNearestLayoutNode();
413     CElement*           GetUpdatedNearestLayoutElement();
414 
415     CLayout*            GetUpdatedParentLayout();
416     CTreeNode*          GetUpdatedParentLayoutNode();
417     CElement*           GetUpdatedParentLayoutElement();
418 
419 
420     void                DestroyLayout();
421 
422     // this functions return GetFirstBranch()->Parent()->Ancestor(etag)->Element(); safely
423     // returns NULL if the element is not in the tree, or it doesn't have a parent, or no such ansectors in the tree, etc.
424     CElement*           GetParentAncestorSafe(ELEMENT_TAG etag) const;
425     CElement*           GetParentAncestorSafe(ELEMENT_TAG* arytag) const;
426 
427     // BUGBUG - these functions should go, we should not need
428     // to know if the element has flowlayout.
429     CFlowLayout*        GetFlowLayout();
430     CTreeNode*          GetFlowLayoutNode();
431     CElement*           GetFlowLayoutElement();
432     CFlowLayout*        HasFlowLayout();
433 
434     // Notification helpers
435     void InvalidateElement(DWORD grfFlags=0);
436     void MinMaxElement(DWORD grfFlags=0);
437     void ResizeElement(DWORD grfFlags=0);
438     void RemeasureElement(DWORD grfFlags=0);
439     void RemeasureInParentContext(DWORD grfFlags=0);
440     void RepositionElement(DWORD grfFlags=0);
441     void ZChangeElement(DWORD grfFlags=0, CPoint* ppt=NULL);
442 
443     void SendNotification(enum NOTIFYTYPE ntype, DWORD grfFlags=0, void* pvData=0);
444     void SendNotification(enum NOTIFYTYPE ntype, void* pvData)
445     {
446         SendNotification(ntype, 0, pvData);
447     }
448     void SendNotification(CNotification* pNF);
449 
450     long GetSourceIndex(void);
451 
452     long CompareZOrder(CElement* pElement);
453 
454     // Mark an element's layout (if any) dirty
455     void DirtyLayout(DWORD grfLayout=0);
456     BOOL OpenView();
457 
458     BOOL HasPercentBgImg();
459 
460     // cp and run related helper functions
461     long GetFirstCp();
462     long GetLastCp();
463     long GetElementCch();
464     long GetFirstAndLastCp(long* pcpFirst, long* pcpLast);
465 
466     // get the border information related to the element
467     virtual DWORD GetBorderInfo(CDocInfo* pdci, CBorderInfo* pbi, BOOL fAll=FALSE);
468 
469     HRESULT GetRange(long* pcp, long* pcch);
470     HRESULT GetPlainTextInScope(CString* pstrText);
471 
472     virtual HRESULT Save(CStreamWriteBuff* pStreamWrBuff, BOOL fEnd);
473     HRESULT WriteTag(CStreamWriteBuff* pStreamWrBuff, BOOL fEnd, BOOL fForce=FALSE);
474     virtual HRESULT SaveAttributes(CStreamWriteBuff* pStreamWrBuff, BOOL* pfAny=NULL);
475     HRESULT SaveAttributes(IPropertyBag* pPropBag, BOOL fSaveBlankAttributes=TRUE);
476     HRESULT SaveAttribute(
477         CStreamWriteBuff*   pStreamWrBuff,
478         LPTSTR              pchName,
479         LPTSTR              pchValue,
480         const PROPERTYDESC* pPropDesc=NULL,
481         CBase*              pBaseObj=NULL,
482         BOOL                fEqualSpaces=TRUE,
483         BOOL                fAlwaysQuote=FALSE);
484 
485     ELEMENT_TAG Tag() const { return (ELEMENT_TAG)_etag; }
486     inline ELEMENT_TAG TagType() const
487     {
488         switch(_etag)
489         {
490         case ETAG_GENERIC_LITERAL:
491         case ETAG_GENERIC_BUILTIN:
492             return ETAG_GENERIC;
493         default:
494             return (ELEMENT_TAG)_etag;
495         }
496     }
497 
498     virtual const TCHAR* TagName();
499     const TCHAR* NamespaceHtml();
500 
501     // Support for sub-objects created through pdl's
502     // CStyle & Celement implement this differently
503     CElement* GetElementPtr() { return this; }
504 
505     BOOL CanShow();
506 
507     BOOL HasFlag(TAGDESC_FLAGS) const;
508 
509     static void ReplacePtr(CElement** pplhs, CElement* prhs);
510     static void ReplacePtrSub(CElement** pplhs, CElement* prhs);
511     static void SetPtr(CElement** pplhs, CElement* prhs);
512     static void ClearPtr(CElement** pplhs);
513     static void StealPtrSet(CElement** pplhs, CElement* prhs);
514     static void StealPtrReplace(CElement** pplhs, CElement* prhs);
515     static void ReleasePtr(CElement* pElement);
516 
517     // Write unknown attr set
518     HRESULT SaveUnknown(CStreamWriteBuff* pStreamWrBuff, BOOL* pfAny=NULL);
519     HRESULT SaveUnknown(IPropertyBag* pPropBag, BOOL fSaveBlankAttributes=TRUE);
520 
521     // Helpers
522     BOOL IsNamed() const { return !!_fIsNamed; }
523 
524     // comparison
525     LPCTSTR NameOrIDOfParentForm();
526 
527     // Helper for name or ID
528     LPCTSTR GetIdentifier(void);
529     HRESULT GetUniqueIdentifier(CString* pcstr, BOOL fSetWhenCreated=FALSE, BOOL* pfDidCreate=NULL);
530     LPCTSTR GetAAname() const;
531     LPCTSTR GetAAsubmitname() const;
532 
533     // Paste helpers
534     enum Where
535     {
536         Inside,
537         Outside,
538         BeforeBegin,
539         AfterBegin,
540         BeforeEnd,
541         AfterEnd
542     };
543 
544     HRESULT Inject(Where, BOOL fIsHtml, LPTSTR pStr, long cch);
545 
546     virtual HRESULT PasteClipboard() { return S_OK; }
547 
548     HRESULT InsertAdjacent(Where where, CElement* pElementInsert);
549 
550     HRESULT RemoveOuter();
551 
552     // Helper to get the specified text under the element -- invokes saver.
553     HRESULT GetText(BSTR* pbstr, DWORD dwStm);
554 
555     // Another helper for databinding
556     HRESULT GetBstrFromElement(BOOL fHTML, BSTR* pbstr);
557 
558     // Collection Management helpers
559     NV_DECLARE_PROPERTY_METHOD(GetIDHelper, GETIDHelper, (CString* pf));
560     NV_DECLARE_PROPERTY_METHOD(SetIDHelper, SETIDHelper, (CString* pf));
561     NV_DECLARE_PROPERTY_METHOD(GetnameHelper, GETNAMEHelper, (CString* pf));
562     NV_DECLARE_PROPERTY_METHOD(SetnameHelper, SETNAMEHelper, (CString* pf));
563     LPCTSTR GetAAid() const;
564     void    InvalidateCollection(long lIndex);
565     NV_STDMETHOD(removeAttribute)(BSTR strPropertyName, LONG lFlags, VARIANT_BOOL* pfSuccess);
566     HRESULT SetUniqueNameHelper(LPCTSTR szUniqueName);
567     HRESULT SetIdentifierHelper(LPCTSTR lpszValue, DISPID dspIDThis, DISPID dspOther1, DISPID dspOther2);
568     void    OnEnterExitInvalidateCollections(BOOL);
569     void    DoElementNameChangeCollections(void);
570 
571     // Clone - make a duplicate new element
572     //
573     // !! returns an element with no node!
574     virtual HRESULT Clone(CElement** ppElementClone, CDocument* pDoc);
575 
576     void ComputeHorzBorderAndPadding(
577         CCalcInfo*  pci,
578         CTreeNode*  pNodeContext,
579         CElement*   pTxtSite,
580         LONG*       pxBorderLeft,
581         LONG*       pxPaddingLeft,
582         LONG*       pxBorderRight,
583         LONG*       pxPaddingRight);
584 
585     HRESULT SetDim(
586         DISPID                      dispID,
587         float                       fValue,
588         CUnitValue::UNITVALUETYPE   uvt,
589         long                        lDimOf,
590         CAttrArray**                ppAA,
591         BOOL                        fInlineStyle,
592         BOOL*                       pfChanged);
593 
594     virtual HRESULT ComputeFormats(CFormatInfo* pCFI, CTreeNode* pNodeTarget);
595     virtual HRESULT ApplyDefaultFormat(CFormatInfo* pCFI);
596     BOOL    ElementNeedsLayout(CFormatInfo* pCFI);
597     BOOL    DetermineBlockness(CFormatInfo* pCFI);
598     HRESULT ApplyInnerOuterFormats(CFormatInfo* pCFI);
599     CImgCtx* GetBgImgCtx();
600 
601     // Access Key Handling Helper Functions
602     FOCUS_ITEM GetMnemonicTarget();
603     HRESULT HandleMnemonic(CMessage* pmsg, BOOL fDoClick, BOOL* pfYieldFailed=NULL);
604     HRESULT GotMnemonic(CMessage* pMessage);
605     HRESULT LostMnemonic(CMessage* pMessage);  
606     BOOL    MatchAccessKey(CMessage* pmsg);
607     HRESULT OnTabIndexChange();
608 
609     // Styles
610     HRESULT      GetStyleObject(CStyle** ppStyle);
611     CAttrArray*  GetInLineStyleAttrArray();
612     CAttrArray** CreateStyleAttrArray(DISPID);
613 
614     BOOL         HasInLineStyles(void);
615     BOOL         HasClassOrID(void);
616 
617     CStyle*      GetInLineStylePtr();
618     CStyle*      GetRuntimeStylePtr();
619 
620     // Helpers for abstract name properties implemented on derived elements
621     DECLARE_TEAROFF_METHOD(put_name, PUT_name, (BSTR v));
622     DECLARE_TEAROFF_METHOD(get_name, GET_name, (BSTR* p));
623 
624     htmlBlockAlign      GetParagraphAlign(BOOL fOuter);
625     htmlControlAlign    GetSiteAlign();
626 
627     BOOL IsInlinedElement();
628 
629     BOOL IsPositionStatic();
630     BOOL IsPositioned();
631     BOOL IsAbsolute();
632     BOOL IsRelative();
633     BOOL IsInheritingRelativeness();
634     BOOL IsScrollingParent();
635     BOOL IsClipParent();
636     BOOL IsZParent();
637     BOOL IsLocked();
638     BOOL IsDisplayNone();
639     BOOL IsVisibilityHidden();
640 
641     // Reset functionallity
642     // Returns S_OK if successful and E_NOTIMPL if not applicable
643     virtual HRESULT DoReset(void) { return E_NOTIMPL; }
644 
645     // Get control's window, does control have window?
646     virtual HWND GetHwnd() { return NULL; }
647 
648     // Take the capture.
649     void TakeCapture(BOOL fTake);
650     BOOL HasCapture();
651 
652     // IMsoCommandTarget methods
653     HRESULT STDMETHODCALLTYPE QueryStatus(
654         GUID*       pguidCmdGroup,
655         ULONG       cCmds,
656         MSOCMD      rgCmds[],
657         MSOCMDTEXT* pcmdtext);
658     HRESULT STDMETHODCALLTYPE Exec(
659         GUID*       pguidCmdGroup,
660         DWORD       nCmdID,
661         DWORD       nCmdexecopt,
662         VARIANTARG* pvarargIn,
663         VARIANTARG* pvarargOut);
664 
665     BOOL IsEditable(BOOL fCheckContainerOnly=FALSE);
666 
667     HRESULT EnsureInMarkup();
668 
669     // Currency / UI-Activity
670 
671     // Does this element (or its master) have currency?
672     BOOL HasCurrency();
673 
674     virtual HRESULT RequestYieldCurrency(BOOL fForce);
675 
676     // Relinquishes currency
677     virtual HRESULT YieldCurrency(CElement* pElemNew);
678 
679     // Relinquishes UI
680     virtual void YieldUI(CElement* pElemNew);
681 
682     // Forces UI upon an element
683     virtual HRESULT BecomeUIActive();
684 
685     BOOL    NoUIActivate(); // tell us if element can be UIActivate
686 
687     BOOL    IsFocussable(long lSubDivision);
688     BOOL    IsTabbable(long lSubDivision);
689 
690     HRESULT PreBecomeCurrent(long lSubDivision, CMessage* pMessage);
691     HRESULT BecomeCurrentFailed(long lSubDivision, CMessage* pMessage);
692     HRESULT PostBecomeCurrent(CMessage* pMessage);
693 
694     HRESULT BecomeCurrent(
695         long        lSubDivision,
696         BOOL*       pfYieldFailed=NULL,
697         CMessage*   pMessage=NULL,
698         BOOL        fTakeFocus=FALSE);
699 
700     HRESULT BubbleBecomeCurrent(
701         long        lSubDivision,
702         BOOL*       pfYieldFailed=NULL,
703         CMessage*   pMessage=NULL,
704         BOOL        fTakeFocus=FALSE);
705 
706     CElement* GetFocusBlurFireTarget(long lSubDiv);
707 
708     HRESULT focusHelper(long lSubDivision);
709 
710     virtual HRESULT GetFocusShape(long lSubDivision, CDocInfo* pdci, CShape** ppShape);
711 
712     // Forces Currency and uiactivity upon an element
713     HRESULT BecomeCurrentAndActive(
714         CMessage*   pmsg=NULL,
715         long        lSubDivision=0,
716         BOOL        fTakeFocus=FALSE, 
717         BOOL*       pfYieldFailed=NULL);
718     HRESULT BubbleBecomeCurrentAndActive(CMessage* pmsg=NULL, BOOL fTakeFocus=FALSE);
719 
720     virtual HRESULT GetSubDivisionCount(long* pc);
721     virtual HRESULT GetSubDivisionTabs(long* pTabs, long c);
722     virtual HRESULT SubDivisionFromPt(POINT pt, long* plSub);
723 
724     // Find an element with the given set of SITE_FLAG's set
725     CElement* FindDefaultElem(BOOL fDefault, BOOL fFull=FALSE);
726 
727     // set the default element in a form or in the doc
728     void SetDefaultElem(BOOL fFindNew = FALSE);
729 
730     HRESULT GetNextSubdivision(FOCUS_DIRECTION dir, long lSubDivision, long* plSubNew);
731 
732     virtual BOOL IsEnabled();
733 
734     virtual BOOL IsValid() { return TRUE; }
735 
736     BOOL IsVisible(BOOL fCheckParent);
737     BOOL IsParent(CElement* pElement); // Is pElement a parent of this element?
738 
739     virtual HRESULT GetControlInfo(CONTROLINFO* pCI) { return E_FAIL; }
740     virtual BOOL OnMenuEvent(int id, UINT code) { return FALSE; }
741     HRESULT STDMETHODCALLTYPE OnCommand(int id, HWND hwndCtrl, UINT codeNotify) { return S_OK; }
742     HRESULT OnContextMenu(int x, int y, int id);
743 
744     HRESULT OnInitMenuPopup(HMENU hmenu, int item, BOOL fSystemMenu);
745     HRESULT OnMenuSelect(UINT uItem, UINT fuFlags, HMENU hmenu);
746 
747     // Helper for translating keystrokes into commands
748     HRESULT PerformTA(CMessage* pMessage);
749 
750     CImgCtx* GetNearestBgImgCtx();
751 
752     DWORD GetCommandID(LPMSG lpmsg);
753 
754     //+---------------------------------------------------------------------------
755     //
756     //  Flag values for CElement::CLock
757     //
758     //----------------------------------------------------------------------------
759     enum ELEMENTLOCK_FLAG
760     {
761         ELEMENTLOCK_NONE            = 0,
762         ELEMENTLOCK_CLICK           = 1 <<  0,
763         ELEMENTLOCK_PROCESSPOSITION = 1 <<  1,
764         ELEMENTLOCK_PROCESSADORNERS = 1 <<  2,
765         ELEMENTLOCK_DELETE          = 1 <<  3,
766         ELEMENTLOCK_FOCUS           = 1 <<  4,
767         ELEMENTLOCK_CHANGE          = 1 <<  5,
768         ELEMENTLOCK_UPDATE          = 1 <<  6,
769         ELEMENTLOCK_SIZING          = 1 <<  7,
770         ELEMENTLOCK_COMPUTEFORMATS  = 1 <<  8,
771         ELEMENTLOCK_QUERYSTATUS     = 1 <<  9,
772         ELEMENTLOCK_BLUR            = 1 << 10,
773         ELEMENTLOCK_RECALC          = 1 << 11,
774         ELEMENTLOCK_BLOCKCALC       = 1 << 12,
775         ELEMENTLOCK_ATTACHPEER      = 1 << 13,
776         ELEMENTLOCK_PROCESSREQUESTS = 1 << 14,
777         ELEMENTLOCK_PROCESSMEASURE  = 1 << 15,
778         ELEMENTLOCK_LAST            = 1 << 15,
779 
780         // don't add anymore flags, we only have 16 bits
781     };
782 
783     //+-----------------------------------------------------------------------
784     //
785     //  CElement::CLock
786     //
787     //------------------------------------------------------------------------
788     class CLock
789     {
790     public:
791         DECLARE_MEMALLOC_NEW_DELETE();
792         CLock(CElement* pElement, ELEMENTLOCK_FLAG enumLockFlags=ELEMENTLOCK_NONE);
793         ~CLock();
794 
795     private:
796         CElement* _pElement;
797         WORD _wLockFlags;
798     };
799 
800     BOOL TestLock(ELEMENTLOCK_FLAG enumLockFlags) { return _wLockFlags&((WORD)enumLockFlags); }
801 
802     BOOL TestClassFlag(ELEMENTDESC_FLAG dwFlag) const { return ElementDesc()->_classdescBase._dwFlags&dwFlag; }
803 
804     inline BOOL WantEndParseNotification() { return TestClassFlag(CElement::ELEMENTDESC_NOTIFYENDPARSE); }
805 
806     // BUGBUG: we should have a general notification mechanism to tell what
807     // elements are listening to which notifications
808     BOOL WantTextChangeNotifications();
809 
810     //+-----------------------------------------------------------------------
811     //
812     //  CLASSDESC (class descriptor)
813     //
814     //------------------------------------------------------------------------
815     class ACCELS
816     {
817     public:
818         ACCELS(ACCELS* pSuper, WORD wAccels);
819         ~ACCELS();
820         HRESULT EnsureResources();
821         HRESULT LoadAccelTable();
822         DWORD   GetCommandID(LPMSG pmsg);
823 
824         ACCELS* _pSuper;
825 
826         BOOL    _fResourcesLoaded;
827 
828         WORD    _wAccels;
829         LPACCEL _pAccels;
830         int     _cAccels;
831     };
832 
833     struct CLASSDESC
834     {
835         CBase::CLASSDESC _classdescBase;
836         void* _apfnTearOff;
837 
838         BOOL TestFlag(ELEMENTDESC_FLAG dw) const { return (_classdescBase._dwFlags&dw)!=0; }
839 
840         // move from CSite::CLASSDESC
841         ACCELS* _pAccelsDesign;
842         ACCELS* _pAccelsRun;
843     };
844 
845     const CLASSDESC* ElementDesc() const
846     {
847         return (const CLASSDESC*)BaseDesc();
848     }
849 
850 public:
851     // Lookaside pointers
852     enum
853     {
854         LOOKASIDE_FILTER            = 0,
855         LOOKASIDE_DATABIND          = 1,
856         LOOKASIDE_PEER              = 2,
857         LOOKASIDE_PEERMGR           = 3,
858         LOOKASIDE_ACCESSIBLE        = 4,
859         LOOKASIDE_SLAVEMARKUP       = 5,
860         LOOKASIDE_REQUEST           = 6,
861         LOOKASIDE_ELEMENT_NUMBER    = 7
862 
863         // *** There are only 7 bits reserved in the element.
864         // *** if you add more lookasides you have to make sure 
865         // *** that you make room for those bits.
866     };
867 
868 private:
869     BOOL        HasLookasidePtr(int iPtr)                       { return (_fHasLookasidePtr&(1<<iPtr)); }
870     void*       GetLookasidePtr(int iPtr);
871     HRESULT     SetLookasidePtr(int iPtr, void* pv);
872     void*       DelLookasidePtr(int iPtr);
873 
874 public:
875 
876     BOOL        HasLayoutPtr() const                            { return _fHasLayoutPtr; }
877     CLayout*    GetLayoutPtr() const;
878     void        SetLayoutPtr(CLayout* pLayout);
879     CLayout*    DelLayoutPtr();
880 
881     BOOL        IsInMarkup() const                              { return _fHasMarkupPtr; }
882     BOOL        HasMarkupPtr() const                            { return _fHasMarkupPtr; }
883     CMarkup*    GetMarkupPtr() const;
884     void        SetMarkupPtr(CMarkup* pMarkup);
885     void        DelMarkupPtr();
886 
887     CRootElement* IsRoot()                                      { return Tag()==ETAG_ROOT?(CRootElement*)this:NULL; }
888     CMarkup*    GetMarkup() const                               { return GetMarkupPtr(); }
889     BOOL        IsInPrimaryMarkup() const;
890     BOOL        IsInThisMarkup(CMarkup* pMarkup) const;
891     CRootElement* MarkupRoot();
892 
893     CElement*   MarkupMaster() const;
894     CMarkup*    SlaveMarkup() const                             { return ((CElement*)this)->GetSlaveMarkupPtr(); }
895     CElement*   FireEventWith();
896 
897     CDocument*  GetDocPtr() const;
898 
899     BOOL        HasSlaveMarkupPtr()                             { return (HasLookasidePtr(LOOKASIDE_SLAVEMARKUP)); }
900     CMarkup*    GetSlaveMarkupPtr()                             { return ((CMarkup*)GetLookasidePtr(LOOKASIDE_SLAVEMARKUP)); }
901     HRESULT     SetSlaveMarkupPtr(CMarkup* pSlaveMarkup)        { return (SetLookasidePtr(LOOKASIDE_SLAVEMARKUP, pSlaveMarkup)); }
902     CMarkup*    DelSlaveMarkupPtr()                             { return ((CMarkup*)DelLookasidePtr(LOOKASIDE_SLAVEMARKUP)); }
903 
904     BOOL        HasRequestPtr()                                 { return (HasLookasidePtr(LOOKASIDE_REQUEST)); }
905     CRequest*   GetRequestPtr()                                 { return ((CRequest*)GetLookasidePtr(LOOKASIDE_REQUEST)); }
906     HRESULT     SetRequestPtr(CRequest* pRequest)               { return (SetLookasidePtr(LOOKASIDE_REQUEST, pRequest)); }
907     CRequest*   DelRequestPtr()                                 { return ((CRequest*)DelLookasidePtr(LOOKASIDE_REQUEST)); }
908 
909     long        GetReadyState();
910     virtual void OnReadyStateChange();
911 
912     // The element is the head of a linked list of important structures.  If the element has layout,
913     // then the __pvChain member points to that layout.  If not and if the element is in a tree then
914     // then the __pvChain member points to the ped that it is in.  Otherwise __pvChain points to the
915     // document.
916 private:
917     void* __pvChain;
918 
919 public:
920     CTreeNode* __pNodeFirstBranch;
921 
922     // First DWORD of bits
923     ELEMENT_TAG _etag                    : 8; //  0- 7 element tag
924     unsigned _fHasLookasidePtr           : 7; //  8-14 TRUE if lookaside table has pointer
925     unsigned _fIsNamed                   : 1; // 15 set if element has a name or ID attribute
926     unsigned _wLockFlags                 :16; // 16-31 Element lock flags for preventing recursion
927 
928     // Second DWORD of bits
929     //
930     // Note that the _fMark1 and _fMark2 bits are only safe to use in routines which can *guarantee*
931     // their processing will not be interrupted. If there is a chance that a message loop can cause other,
932     // unrelated code, to execute, these bits could get reset before the original caller is finished.
933     unsigned _fHasMarkupPtr              : 1; //  0 TRUE if element has a Markup pointer
934     unsigned _fHasLayoutPtr              : 1; //  1 TRUE if element has layout ptr
935     unsigned _fHasPendingFilterTask      : 1; //  2 TRUE if there is a pending filter task (see EnsureView)
936     unsigned _fHasPendingRecalcTask      : 1; //  3 TRUE if there is a pending recalc task (see EnsureView)
937     unsigned _fLayoutAlwaysValid         : 1; //  4 TRUE if element is a site or never has layout
938     unsigned _fOwnsRuns                  : 1; //  5 TRUE if element owns the runs underneath it
939     unsigned _fInheritFF                 : 1; //  6 TRUE if element to inherit site and fancy format
940     unsigned _fBreakOnEmpty              : 1; //  7 this element breaks a line even is it own no text
941     unsigned _fUnused2                   : 4; //  8-11
942     unsigned _fDefinitelyNoBorders       : 1; // 12 There are no borders on this element
943     unsigned _fHasTabIndex               : 1; // 13 Has a tabindex associated with this element. Look in doc _aryTabIndexInfo
944     unsigned _fHasImage                  : 1; // 14 has at least one image context
945     unsigned _fResizeOnImageChange       : 1; // 15 need to force resize when image changes
946     unsigned _fExplicitEndTag            : 1; // 16 element had a close tag (for P)
947     unsigned _fSynthesized               : 1; // 17 FALSE (default) if user created, TRUE if synthesized
948     unsigned _fUnused3                   : 1; // 18 Unused bit
949     unsigned _fActsLikeButton            : 1; // 19 does element act like a push button?
950     unsigned _fEditAtBrowse              : 1; // 20 to TestClassFlag(SITEDESC_EDITATBROWSE) in init
951     unsigned _fSite                      : 1; // 21 element with layout by default
952     unsigned _fDefault                   : 1; // 22 Is this the default "ok" button/control
953     unsigned _fCancel                    : 1; // 23 Is this the default "cancel" button/control
954     unsigned _fHasPendingEvent           : 1; // 24 A posted event for element is pending
955     unsigned _fEventListenerPresent      : 1; // 25 Someone has asked for a connection point/ or set an event handler
956     unsigned _fHasFilterCollectionPtr    : 1; // 26 FilterCollectionPtr has been added to _pAA
957     unsigned _fExittreePending           : 1; // 27 There is a pending Exittree notification for this element
958     unsigned _fFirstCommonAncestor       : 1; // 28 Used in GetFirstCommonAncestor - don't touch!
959     unsigned _fMark1                     : 1; // 29 Random mark
960     unsigned _fMark2                     : 1; // 30 Another random mark
961     unsigned _fHasStyleExpressions       : 1; // 31 There are style expressions on this element
962 
963     // STATIC DATA
964 
965     //  Default property page list for elements that don't have their own.
966     //  This gives them the allpage by default.
967     static ACCELS s_AccelsElementDesign;
968     static ACCELS s_AccelsElementRun;
969 
970     // Style methods
971 #include "../gen/style.hdl"
972     
973     // IHTMLElement methods
974 #define _CElement_
975 #include "../gen/element.hdl"
976 
977     DECLARE_TEAROFF_TABLE(IServiceProvider)
978 
979 private:
980     NO_COPY(CElement);
981 };
元素的基類 CElement

 

 

 1 ULONG CBase::SubRelease()
 2 {
 3 #ifdef _DEBUG
 4     ULONG ulAllRefs = _ulAllRefs;
 5 #endif
 6     if(--_ulAllRefs == 0)
 7     {
 8         _ulAllRefs = ULREF_IN_DESTRUCTOR;
 9         _ulRefs = ULREF_IN_DESTRUCTOR;
10         delete this;
11     }
12 #ifdef _DEBUG
13     return ulAllRefs-1;
14 #else
15     return 0;
16 #endif
17 }
CElement的最終釋放函式 CBase::SubRelease
ULONG CBase::PrivateRelease()
{
    ULONG ulRefs = --_ulRefs;
    if(ulRefs == 0)
    {
        _ulRefs = ULREF_IN_DESTRUCTOR;
        Passivate();
        Assert("Unexpected refcnt on return from CBase::Passivate" && _ulRefs==ULREF_IN_DESTRUCTOR);
        _ulRefs = 0;
        SubRelease();
    }

    return ulRefs;
}
CBase::SubRelease的上層函式 CBase::PrivateRelease

 

  1 class CMarkup : public CBase
  2 {
  3     friend class CTxtPtr;
  4     friend class CTreePos;
  5     friend class CMarkupPointer;
  6 
  7     DECLARE_CLASS_TYPES(CMarkup, CBase)
  8 
  9 public:
 10     DECLARE_TEAROFF_TABLE(ISelectionRenderingServices)
 11     DECLARE_TEAROFF_TABLE(IMarkupContainer)
 12 
 13     DECLARE_MEMCLEAR_NEW_DELETE()
 14 
 15     CMarkup(CDocument* pDoc, CElement* pElementMaster=NULL);
 16     ~CMarkup();
 17 
 18     HRESULT Init(CRootElement* pElementRoot);
 19 
 20     HRESULT CreateInitialMarkup(CRootElement* pElementRoot);
 21 
 22     HRESULT UnloadContents(BOOL fForPassivate=FALSE);
 23 
 24     HRESULT DestroySplayTree(BOOL fReinit);
 25 
 26     void Passivate();
 27 
 28     HRESULT CreateElement(
 29         ELEMENT_TAG    etag,
 30         CElement**    ppElementNew);
 31 
 32 #define _CMarkup_
 33 #include "../gen/markup.hdl"
 34 
 35     // Document props\methods:
 36     NV_DECLARE_TEAROFF_METHOD(get_Script, GET_Script, (IDispatch** p));
 37     NV_DECLARE_TEAROFF_METHOD(get_all, GET_all, (IHTMLElementCollection** p));
 38     NV_DECLARE_TEAROFF_METHOD(get_body, GET_body, (IHTMLElement** p));
 39     NV_DECLARE_TEAROFF_METHOD(get_activeElement, GET_activeElement, (IHTMLElement** p));
 40    NV_DECLARE_TEAROFF_METHOD(put_title, PUT_title, (BSTR v));
 41     NV_DECLARE_TEAROFF_METHOD(get_title, GET_title, (BSTR* p));
 42     NV_DECLARE_TEAROFF_METHOD(get_readyState, GET_readyState, (BSTR* p));
 43     NV_DECLARE_TEAROFF_METHOD(put_expando, PUT_expando, (VARIANT_BOOL v));
 44     NV_DECLARE_TEAROFF_METHOD(get_expando, GET_expando, (VARIANT_BOOL* p));
 45     NV_DECLARE_TEAROFF_METHOD(get_parentWindow, GET_parentWindow, (IHTMLWindow2** p));
 46     NV_DECLARE_TEAROFF_METHOD(get_nameProp, GET_nameProp, (BSTR* p));
 47     NV_DECLARE_TEAROFF_METHOD_(HRESULT, queryCommandSupported, querycommandsupported, (BSTR cmdID,VARIANT_BOOL* pfRet));
 48     NV_DECLARE_TEAROFF_METHOD_(HRESULT, queryCommandEnabled, querycommandenabled, (BSTR cmdID,VARIANT_BOOL* pfRet));
 49     NV_DECLARE_TEAROFF_METHOD_(HRESULT, queryCommandState, querycommandstate, (BSTR cmdID,VARIANT_BOOL* pfRet));
 50     NV_DECLARE_TEAROFF_METHOD_(HRESULT, queryCommandIndeterm, querycommandindeterm, (BSTR cmdID,VARIANT_BOOL* pfRet));
 51     NV_DECLARE_TEAROFF_METHOD_(HRESULT, queryCommandText, querycommandtext, (BSTR cmdID,BSTR* pcmdText));
 52     NV_DECLARE_TEAROFF_METHOD_(HRESULT, queryCommandValue, querycommandvalue, (BSTR cmdID,VARIANT* pcmdValue));
 53     NV_DECLARE_TEAROFF_METHOD_(HRESULT, execCommand, execcommand, (BSTR cmdID,VARIANT_BOOL showUI,VARIANT value,VARIANT_BOOL* pfRet));
 54     NV_DECLARE_TEAROFF_METHOD_(HRESULT, execCommandShowHelp, execcommandshowhelp, (BSTR cmdID,VARIANT_BOOL* pfRet));
 55     NV_DECLARE_TEAROFF_METHOD_(HRESULT, createElement, createelement, (BSTR eTag,IHTMLElement** newElem));
 56     NV_DECLARE_TEAROFF_METHOD_(HRESULT, elementFromPoint, elementfrompoint, (long x,long y,IHTMLElement** elementHit));
 57     NV_DECLARE_TEAROFF_METHOD_(HRESULT, toString, tostring, (BSTR* String));
 58     NV_DECLARE_TEAROFF_METHOD_(HRESULT, releaseCapture, releasecapture, ());
 59     NV_DECLARE_TEAROFF_METHOD(get_documentElement, GET_documentelement, (IHTMLElement**pRootElem));
 60     NV_DECLARE_TEAROFF_METHOD(get_uniqueID, GET_uniqueID, (BSTR* p));
 61     NV_DECLARE_TEAROFF_METHOD_(HRESULT, attachEvent, attachevent, (BSTR event,IDispatch* pDisp,VARIANT_BOOL* pfResult));
 62     NV_DECLARE_TEAROFF_METHOD_(HRESULT, detachEvent, detachevent, (BSTR event,IDispatch* pDisp));
 63     NV_DECLARE_TEAROFF_METHOD(get_bgColor, GET_bgColor, (VARIANT* p));
 64     NV_DECLARE_TEAROFF_METHOD(put_bgColor, PUT_bgColor, (VARIANT p));
 65     NV_DECLARE_TEAROFF_METHOD(get_fgColor, GET_fgColor, (VARIANT* p));
 66     NV_DECLARE_TEAROFF_METHOD(put_fgColor, PUT_fgColor, (VARIANT p));
 67     NV_DECLARE_TEAROFF_METHOD(get_linkColor, GET_linkColor, (VARIANT* p));
 68     NV_DECLARE_TEAROFF_METHOD(put_linkColor, PUT_linkColor, (VARIANT p));
 69     NV_DECLARE_TEAROFF_METHOD(get_alinkColor, GET_alinkColor, (VARIANT* p));
 70     NV_DECLARE_TEAROFF_METHOD(put_alinkColor, PUT_alinkColor, (VARIANT p));
 71     NV_DECLARE_TEAROFF_METHOD(get_vlinkColor, GET_vlinkColor, (VARIANT* p));
 72     NV_DECLARE_TEAROFF_METHOD(put_vlinkColor, PUT_vlinkColor, (VARIANT p));
 73     NV_DECLARE_TEAROFF_METHOD(get_parentDocument, GET_parentDocument, (IHTMLDocument2** p));
 74     NV_DECLARE_TEAROFF_METHOD(put_enableDownload, PUT_enableDownload, (VARIANT_BOOL v));
 75     NV_DECLARE_TEAROFF_METHOD(get_enableDownload, GET_enableDownload, (VARIANT_BOOL* p));
 76     NV_DECLARE_TEAROFF_METHOD(put_baseUrl, PUT_baseUrl, (BSTR v));
 77     NV_DECLARE_TEAROFF_METHOD(get_baseUrl, GET_baseUrl, (BSTR* p));
 78     NV_DECLARE_TEAROFF_METHOD(put_inheritStyleSheets, PUT_inheritStyleSheets, (VARIANT_BOOL v));
 79     NV_DECLARE_TEAROFF_METHOD(get_inheritStyleSheets, GET_inheritStyleSheets, (VARIANT_BOOL* p));
 80     NV_DECLARE_TEAROFF_METHOD(getElementsByName, getelementsbyname, (BSTR v, IHTMLElementCollection** p));
 81     NV_DECLARE_TEAROFF_METHOD(getElementsByTagName, getelementsbytagname, (BSTR v, IHTMLElementCollection** p));
 82     NV_DECLARE_TEAROFF_METHOD(getElementById, getelementbyid, (BSTR v, IHTMLElement** p));
 83 
 84     // IServiceProvider
 85     STDMETHOD(QueryService)(REFGUID guidService, REFIID riid, void** ppv);
 86 
 87     // Data Access
 88     CDocument*                Doc() { return _pDoc; }
 89     CRootElement*            Root() { return _pElementRoot; }
 90 
 91     BOOL                    HasCollectionCache() { return HasLookasidePtr(LOOKASIDE_COLLECTIONCACHE); }
 92     CCollectionCache*        CollectionCache() { return (CCollectionCache*)GetLookasidePtr(LOOKASIDE_COLLECTIONCACHE); }
 93     CCollectionCache*        DelCollectionCache() { return (CCollectionCache*)DelLookasidePtr(LOOKASIDE_COLLECTIONCACHE); }
 94     HRESULT                    SetCollectionCache(CCollectionCache* pCollectionCache) { return SetLookasidePtr(LOOKASIDE_COLLECTIONCACHE, pCollectionCache); }
 95 
 96     BOOL                    HasParentMarkup() { return HasLookasidePtr(LOOKASIDE_PARENTMARKUP); }
 97     CMarkup*                ParentMarkup() { return (CMarkup*)GetLookasidePtr(LOOKASIDE_PARENTMARKUP); }
 98     CMarkup*                DelParentMarkup() { return (CMarkup*)DelLookasidePtr(LOOKASIDE_PARENTMARKUP); }
 99     HRESULT                    SetParentMarkup(CMarkup* pMarkup) { return SetLookasidePtr(LOOKASIDE_PARENTMARKUP, pMarkup); }
100 
101     CElement*                Master() { return _pElementMaster; }
102     void                    ClearMaster() { _pElementMaster = NULL; }
103 
104     CProgSink*              GetProgSinkC();
105     IProgSink*              GetProgSink();
106 
107     CElement*                FirstElement();
108 
109     // Remove 'Assert(Master())', once the root element is gone and these functions
110     // become meaningful for non-slave markups as well.
111     long                GetContentFirstCp() { Assert(Master()); return 2; }
112     long                GetContentLastCp() { Assert(Master()); return GetTextLength()-2; }
113     long                GetContentTextLength() { Assert(Master()); return GetTextLength()-4; }
114     void                GetContentTreeExtent(CTreePos** pptpStart, CTreePos** pptpEnd);
115 
116     BOOL                GetAutoWordSel() const { return TRUE; }
117 
118     BOOL                GetOverstrike() const { return _fOverstrike; }
119     void                SetOverstrike(BOOL fSet) { _fOverstrike = (fSet) ? 1 : 0;}
120 
121     BOOL                GetLoaded() const { return _fLoaded;     }
122     void                SetLoaded(BOOL fLoaded) { _fLoaded = fLoaded;  }
123 
124     void                SetStreaming(BOOL flag) { _fStreaming = (flag) ? 1 : 0; }
125     BOOL                IsStreaming() const { return _fStreaming; } 
126 
127     // BUGBUG: need to figure this function out...
128     BOOL                IsEditable(BOOL fCheckContainerOnly=FALSE) const;
129 
130     // Top element cache
131     void                EnsureTopElems();
132     CElement*            GetElementTop();
133     CElement*            GetElementClient() { EnsureTopElems(); return HasTopElemCache()?GetTopElemCache()->__pElementClientCached:NULL; }
134 
135     // Other helpers
136     BOOL            IsPrimaryMarkup() { return this==Doc()->_pPrimaryMarkup; }
137     long            GetTextLength() { return _TxtArray._cchText; }
138 
139     // GetRunOwner is an abomination that should be eliminated -- or at least moved off of the markup
140     CLayout*        GetRunOwner(CTreeNode* pNode, CLayout* pLayoutParent=NULL);
141     CTreeNode*        GetRunOwnerBranch(CTreeNode*, CLayout* pLayoutParent=NULL);
142 
143     // Markup manipulation functions
144     void CompactStory() { _TxtArray.ShrinkBlocks(); }
145 
146     HRESULT RemoveElementInternal(
147         CElement*    pElementRemove,
148         DWORD        dwFlags=NULL);
149 
150     HRESULT InsertElementInternal(
151         CElement*        pElementInsertThis,
152         CTreePosGap*    ptpgBegin,
153         CTreePosGap*    ptpgEnd,
154         DWORD            dwFlags=NULL);
155 
156     HRESULT SpliceTreeInternal(
157         CTreePosGap*    ptpgStartSource,
158         CTreePosGap*    ptpgEndSource,
159         CMarkup*        pMarkupTarget =NULL,
160         CTreePosGap*    ptpgTarget=NULL,
161         BOOL            fRemove=TRUE,
162         DWORD            dwFlags=NULL);
163 
164     HRESULT InsertTextInternal(
165         CTreePos*        ptpAfterInsert,
166         const TCHAR*    pch,
167         long            cch,
168         DWORD            dwFlags=NULL);
169 
170     HRESULT FastElemTextSet(
171         CElement*       pElem,
172         const TCHAR*    psz,
173         int             cch,
174         BOOL            fAsciiOnly);
175 
176     // Undo only operations
177     HRESULT UndoRemoveSplice(
178         CMarkupPointer*     pmpBegin,
179         CSpliceRecordList*  paryRegion,
180         long                cchRemove,
181         TCHAR*              pchRemove,
182         long                cchNodeReinsert,
183         DWORD               dwFlags);
184 
185     // Markup operation helpers
186     HRESULT ReparentDirectChildren(
187         CTreeNode*        pNodeParentNew,
188         CTreePosGap*    ptpgStart=NULL,
189         CTreePosGap*    ptpgEnd=NULL);
190 
191     HRESULT CreateInclusion(
192         CTreeNode*        pNodeStop,
193         CTreePosGap*    ptpgLocation,
194         CTreePosGap*    ptpgInclusion,
195         long*            pcchNeeded=NULL,
196         CTreeNode*        pNodeAboveLocation=NULL,
197         BOOL            fFullReparent=TRUE,
198         CTreeNode**        ppNodeLastAdded=NULL);
199 
200     HRESULT CloseInclusion(CTreePosGap* ptpgMiddle, long* pcchRemove=NULL);
201 
202     HRESULT RangeAffected(CTreePos* ptpStart, CTreePos* ptpFinish);
203     HRESULT ClearCaches(CTreePos* ptpStart, CTreePos* ptpFinish);
204     HRESULT ClearRunCaches(DWORD dwFlags, CElement* pElement);
205 
206     // Markup pointers
207     HRESULT EmbedPointers() { return _pmpFirst?DoEmbedPointers():S_OK; }
208 
209     HRESULT DoEmbedPointers();
210 
211     BOOL HasUnembeddedPointers() { return !!_pmpFirst; }
212 
213     // TextID manipulation
214 
215     // Give a unique text id to every text chunk in
216     // the range given
217     HRESULT SetTextID(CTreePosGap* ptpgStart, CTreePosGap* ptpgEnd, long* plNewTextID);
218 
219     // Get text ID for text to right
220     // -1 --> no text to right
221     // 0  --> no assigned TextID
222     long GetTextID(CTreePosGap* ptpg);
223 
224     // Starting with ptpgStart, look for
225     // the extent of lTextID
226     HRESULT FindTextID(long lTextID, CTreePosGap* ptpgStart, CTreePosGap* ptpgEnd);
227 
228     // If text to the left of ptpLeft has
229     // the same ID as text to the right of
230     // ptpRight, give the right fragment a
231     // new ID
232     void SplitTextID(CTreePos* ptpLeft, CTreePos* ptpRight);
233 
234     // Splay Tree Primitives
235     CTreePos* NewTextPos(long cch, SCRIPT_ID sid=sidAsciiLatin, long lTextID=0);
236     CTreePos* NewPointerPos(CMarkupPointer* pPointer, BOOL fRight, BOOL fStick);
237 
238     typedef CTreePos SUBLIST;
239     HRESULT Append(CTreePos* ptp);
240     HRESULT Insert(CTreePos* ptpNew, CTreePosGap* ptpgInsert);
241     HRESULT Insert(CTreePos* ptpNew, CTreePos* ptpInsert, BOOL fBefore);
242     HRESULT Move(CTreePos* ptpMove, CTreePosGap* ptpgDest);
243     HRESULT Move(CTreePos* ptpMove, CTreePos* ptpDest, BOOL fBefore);
244     HRESULT Remove(CTreePos* ptpStart, CTreePos* ptpFinish);
245     HRESULT Remove(CTreePos* ptp) { return Remove(ptp, ptp); }
246     HRESULT Split(CTreePos* ptpSplit, long cchLeft, SCRIPT_ID sidNew=sidNil);
247     HRESULT Join(CTreePos* ptpJoin);
248     HRESULT ReplaceTreePos(CTreePos* ptpOld, CTreePos* ptpNew); 
249     HRESULT MergeText(CTreePos* ptpMerge);
250     HRESULT SetTextPosID(CTreePos** pptpText, long lTextID);
251     HRESULT RemovePointerPos(CTreePos* ptp, CTreePos** pptpUpdate, long* pichUpdate);
252 
253     HRESULT SpliceOut(CTreePos* ptpStart, CTreePos* ptpFinish, SUBLIST* pSublistSplice);
254     HRESULT SpliceIn(SUBLIST* pSublistSplice, CTreePos* ptpSplice);
255     HRESULT InsertPosChain(CTreePos* ptpChainHead, CTreePos* ptpChainTail, CTreePos* ptpInsertBefore);
256 
257     // splay tree search routines
258     CTreePos* FirstTreePos() const;
259     CTreePos* LastTreePos() const;
260     CTreePos* TreePosAtCp(long cp, long* pcchOffset) const;
261     CTreePos* TreePosAtSourceIndex(long iSourceIndex);
262 
263     // General splay information
264     long NumElems() const { return _tpRoot.GetElemLeft(); }
265     long Cch() const { return _tpRoot._cchLeft; }
266     long CchInRange(CTreePos* ptpFirst, CTreePos* ptpLast);
267 
268     // Force a splay
269     void FocusAt(CTreePos* ptp) { ptp->Splay(); }
270 
271     // splay tree primitive helpers
272 protected:
273     CTreePos*    AllocData1Pos();
274     CTreePos*    AllocData2Pos();
275     void        FreeTreePos(CTreePos* ptp);
276     void        ReleaseTreePos(CTreePos* ptp, BOOL fLastRelease=FALSE);
277     BOOL        ShouldSplay(long cDepth) const;
278     HRESULT        MergeTextHelper(CTreePos* ptpMerge);
279 
280 public:
281     // Text Story
282     LONG        GetTextLength() const { return _TxtArray._cchText; }
283 
284     // Notifications
285     void        Notify(CNotification* pnf);
286     void        Notify(CNotification& rnf) { Notify(&rnf); }
287 
288     // notification helpers
289 protected:
290     void SendNotification(CNotification* pnf, CDataAry<CNotification>* paryNotification);
291     BOOL ElementWantsNotification(CElement* pElement, CNotification* pnf);
292 
293     void NotifyElement(CElement* pElement, CNotification* pnf);
294     void NotifyAncestors(CNotification* pnf);
295     void NotifyDescendents(CNotification* pnf);
296     void NotifyTreeLevel(CNotification* pnf);
297 
298 public:
299     // Branch searching functions - I'm sure some of these aren't needed
300     //
301     // Note: All of these (except InStory versions) implicitly stop searching at a FlowLayout
302     CTreeNode*    FindMyListContainer(CTreeNode* pNodeStartHere);
303     CTreeNode*    SearchBranchForChildOfScope(CTreeNode* pNodeStartHere, CElement* pElementFindChildOfMyScope);
304     CTreeNode*    SearchBranchForChildOfScopeInStory(CTreeNode* pNodeStartHere, CElement* pElementFindChildOfMyScope);
305     CTreeNode*    SearchBranchForScopeInStory(CTreeNode* pNodeStartHere, CElement* pElementFindMyScope);
306     CTreeNode*    SearchBranchForScope(CTreeNode* pNodeStartHere, CElement* pElementFindMyScope);
307     CTreeNode*    SearchBranchForNode(CTreeNode* pNodeStartHere, CTreeNode* brFindMe);
308     CTreeNode*    SearchBranchForNodeInStory(CTreeNode* pNodeStartHere, CTreeNode* brFindMe);
309     CTreeNode*    SearchBranchForTag(CTreeNode* pNodeStartHere, ELEMENT_TAG);
310     CTreeNode*    SearchBranchForTagInStory(CTreeNode* pNodeStartHere, ELEMENT_TAG);
311     CTreeNode*    SearchBranchForBlockElement(CTreeNode* pNodeStartHere, CFlowLayout* pFLContext=NULL);
312     CTreeNode*    SearchBranchForNonBlockElement(CTreeNode* pNodeStartHere, CFlowLayout* pFLContext=NULL);
313     CTreeNode*    SearchBranchForAnchor(CTreeNode* pNodeStartHere);
314     CTreeNode*    SearchBranchForCriteria(CTreeNode* pNodeStartHere, BOOL (*pfnSearchCriteria)(CTreeNode*));
315     CTreeNode*    SearchBranchForCriteriaInStory(CTreeNode* pNodeStartHere, BOOL (*pfnSearchCriteria)(CTreeNode*));
316 
317     void    EnsureFormats();
318 
319     // Markup TextFrag services
320     // Markup TextFrags are used to store arbitrary string data in the markup.  Mostly
321     // this is used to persist and edit conditional comment tags
322     CMarkupTextFragContext*     EnsureTextFragContext();
323 
324     BOOL                        HasTextFragContext()    { return HasLookasidePtr(LOOKASIDE_TEXTFRAGCONTEXT); }
325     CMarkupTextFragContext*     GetTextFragContext()    { return (CMarkupTextFragContext*)GetLookasidePtr(LOOKASIDE_TEXTFRAGCONTEXT); }
326     HRESULT                     SetTextFragContext(CMarkupTextFragContext* ptfc) { return SetLookasidePtr(LOOKASIDE_TEXTFRAGCONTEXT, ptfc); }
327     CMarkupTextFragContext*     DelTextFragContext()    { return (CMarkupTextFragContext*)DelLookasidePtr(LOOKASIDE_TEXTFRAGCONTEXT); }
328 
329     // Stores the cached values for the client element
330     CMarkupTopElemCache*        EnsureTopElemCache();
331 
332     BOOL                        HasTopElemCache() { return HasLookasidePtr(LOOKASIDE_TOPELEMCACHE); }
333     CMarkupTopElemCache*        GetTopElemCache() { return (CMarkupTopElemCache*)GetLookasidePtr(LOOKASIDE_TOPELEMCACHE); }
334     HRESULT                        SetTopElemCache(CMarkupTopElemCache* ptec) { return SetLookasidePtr(LOOKASIDE_TOPELEMCACHE, ptec); }
335     CMarkupTopElemCache*        DelTopElemCache() { return (CMarkupTopElemCache*)DelLookasidePtr(LOOKASIDE_TOPELEMCACHE); }
336 
337     // Selection Methods
338     VOID GetSelectionChunksForLayout(CFlowLayout* pFlowLayout, CPtrAry<HighlightSegment*>* paryHighlight, int* piCpMin, int* piCpMax);
339     HRESULT EnsureSelRenSvc();
340     VOID HideSelection();
341     VOID ShowSelection();
342     VOID InvalidateSelection(BOOL fFireOM);
343 
344 
345     // Collections support
346     enum
347     {
348         ELEMENT_COLLECTION = 0,
349         FORMS_COLLECTION,
350         ANCHORS_COLLECTION,
351         LINKS_COLLECTION,
352         IMAGES_COLLECTION,
353         APPLETS_COLLECTION,
354         SCRIPTS_COLLECTION,
355         WINDOW_COLLECTION,
356         EMBEDS_COLLECTION,
357         REGION_COLLECTION,
358         LABEL_COLLECTION,
359         NAVDOCUMENT_COLLECTION,
360         FRAMES_COLLECTION,
361         NUM_DOCUMENT_COLLECTIONS
362     };
363     // DISPID range for FRAMES_COLLECTION
364     enum
365     {
366         FRAME_COLLECTION_MIN_DISPID = ((DISPID_COLLECTION_MIN+DISPID_COLLECTION_MAX)*2)/3+1,
367         FRAME_COLLECTION_MAX_DISPID = DISPID_COLLECTION_MAX
368     };
369 
370     HRESULT EnsureCollectionCache(long lCollectionIndex);
371     HRESULT AddToCollections(CElement* pElement, CCollectionBuildContext* pWalk);
372 
373     HRESULT InitCollections(void);
374 
375     NV_DECLARE_ENSURE_METHOD(EnsureCollections, ensurecollections, (long lIndex, long* plCollectionVersion));
376     HRESULT GetCollection(int iIndex, IHTMLElementCollection** ppdisp);
377     HRESULT GetElementByNameOrID(LPTSTR szName, CElement** ppElement);
378     HRESULT GetDispByNameOrID(LPTSTR szName, IDispatch** ppDisp, BOOL fAlwaysCollection=FALSE);
379 
380     CTreeNode* InFormCollection(CTreeNode* pNode);
381 
382     // Lookaside pointers
383     enum
384     {
385         LOOKASIDE_COLLECTIONCACHE    = 0,
386         LOOKASIDE_PARENTMARKUP        = 1,
387         LOOKASIDE_BEHAVIORCONTEXT    = 2,
388         LOOKASIDE_TEXTFRAGCONTEXT    = 3,
389         LOOKASIDE_TOPELEMCACHE        = 4,
390         LOOKASIDE_STYLESHEETS        = 5,
391         LOOKASIDE_TEXTRANGE            = 6,
392         LOOKASIDE_MARKUP_NUMBER        = 7
393     };
394 
395     BOOL        HasLookasidePtr(int iPtr) { return (_fHasLookasidePtr&(1<<iPtr)); }
396     void*        GetLookasidePtr(int iPtr);
397     HRESULT        SetLookasidePtr(int iPtr, void* pv);
398     void*        DelLookasidePtr(int iPtr);
399 
400     void        ClearLookasidePtrs();
401 
402     // IUnknown
403     DECLARE_PLAIN_IUNKNOWN(CMarkup);
404     STDMETHOD(PrivateQueryInterface)(REFIID, void**);
405 
406     // ISegmentList
407     NV_DECLARE_TEAROFF_METHOD(MovePointersToSegment, movepointerstosegment, (
408         int iSegmentIndex, IMarkupPointer* pStart, IMarkupPointer* pEnd));
409     NV_DECLARE_TEAROFF_METHOD(GetSegmentCount, getsegmentcount, (
410         int* piSegmentCount, SELECTION_TYPE* peType));
411 
412     // ISelectionRenderingServices
413     NV_DECLARE_TEAROFF_METHOD(AddSegment, addsegment, (
414         IMarkupPointer* pStart, IMarkupPointer* pEnd, HIGHLIGHT_TYPE HighlightType, int* iSegmentIndex));
415     NV_DECLARE_TEAROFF_METHOD(AddElementSegment, addelementsegment, (
416         IHTMLElement* pElement, int* iSegmentIndex));
417     NV_DECLARE_TEAROFF_METHOD(MoveSegmentToPointers, movesegmenttopointers, (
418         int iSegmentIndex, IMarkupPointer* pStart, IMarkupPointer* pEnd, HIGHLIGHT_TYPE HighlightType));
419     NV_DECLARE_TEAROFF_METHOD(GetElementSegment, getelementsegment, (
420         int iSegmentIndex, IHTMLElement** ppElement));
421     NV_DECLARE_TEAROFF_METHOD(SetElementSegment, setelementsegment, (
422         int iSegmentIndex, IHTMLElement* pElement));
423     NV_DECLARE_TEAROFF_METHOD(ClearSegment, clearsegment, (
424         int iSegmentIndex, BOOL fInvalidate));
425     NV_DECLARE_TEAROFF_METHOD(ClearSegments, clearsegments, (BOOL fInvalidate));
426     NV_DECLARE_TEAROFF_METHOD(ClearElementSegments, clearelementsegments, ());
427 
428     // IMarkupContainer methods
429     NV_DECLARE_TEAROFF_METHOD(OwningDoc, owningdoc, (
430         IHTMLDocument2** ppDoc));
431 
432     // Ref counting helpers
433     static void ReplacePtr(CMarkup** pplhs, CMarkup* prhs);
434     static void SetPtr(CMarkup** pplhs, CMarkup* prhs);
435     static void ClearPtr(CMarkup** pplhs);
436     static void StealPtrSet(CMarkup** pplhs, CMarkup* prhs);
437     static void StealPtrReplace(CMarkup** pplhs, CMarkup* prhs);
438     static void ReleasePtr(CMarkup* pMarkup);
439 
440     // CMarkup::CLock
441     class CLock
442     {
443     public:
444         CLock(CMarkup* pMarkup);
445         ~CLock();
446 
447     private:
448         CMarkup* _pMarkup;
449     };
450 
451 protected:
452     static const CLASSDESC s_classdesc;
453     virtual const CBase::CLASSDESC* GetClassDesc() const { return &s_classdesc; }
454 
455     // Data
456 public:
457     CProgSink*  _pProgSink;
458 
459     CDocument*  _pDoc;
460 
461     // The following are similar to the CDoc's equivalent, but pertain to this
462     // markup alone.
463     long GetMarkupTreeVersion() { return __lMarkupTreeVersion; }
464     long GetMarkupContentsVersion() { return __lMarkupContentsVersion; }
465 
466     // Do NOT modify these version numbers unless the document structure
467     // or content is being modified.
468     //
469     // In particular, incrementing these to get a cache to rebuild is
470     // BAD because it causes all sorts of other stuff to rebuilt.
471     long __lMarkupTreeVersion;        // Element structure
472     long __lMarkupContentsVersion;    // Any content
473 
474     void UpdateMarkupTreeVersion()
475     {
476         CDocument* pDoc = Doc();
477 
478         __lMarkupTreeVersion++;
479         __lMarkupContentsVersion++;
480 
481         pDoc->__lDocTreeVersion++;
482         pDoc->__lDocContentsVersion++;
483     }
484 
485     void UpdateMarkupContentsVersion()
486     {
487         __lMarkupContentsVersion++;
488         Doc()->UpdateDocContentsVersion();
489     }
490 
491 private:
492     CRootElement*    _pElementRoot;
493     CElement*        _pElementMaster;
494 
495     // Story data
496     CTxtArray        _TxtArray;
497 
498     long _lTopElemsVersion;
499 
500     // Selection state
501     CSelectionRenderingServiceProvider* _pSelRenSvcProvider; // Object to Delegate to.
502 
503     // Notification data
504     DECLARE_CDataAry(CAryANotify, CNotification)
505     CAryANotify _aryANotification;
506 
507 private:
508     // This is the list of pointers positioned in this markup
509     // which do not have an embedding.
510     CMarkupPointer*    _pmpFirst;
511 
512     // Splay Tree Data
513     CTreePos        _tpRoot;        // dummy root node
514     CTreePos*        _ptpFirst;        // cached first (leftmost) node
515     void*            _pvPool;        // list of pool blocks (so they can be freed)
516     CTreeDataPos*    _ptdpFree;        // head of free list
517     BYTE            _abPoolInitial[sizeof(void*)+TREEDATA1SIZE*INITIAL_TREEPOS_POOL_SIZE]; // The initial pool of TreePos objects
518 
519 public:
520     struct
521     {
522         DWORD   _fOverstrike       : 1; // 1 Overstrike mode vs insert mode
523         DWORD   _fLoaded           : 1; // 3 Is the markup completely parsed
524         DWORD   _fNoUndoInfo       : 1; // 4 Don't store any undo info for this markup
525         DWORD   _fIncrementalAlloc : 1; // 5 The text array should slow start
526         DWORD   _fStreaming        : 1; // 6 True during parsing
527         DWORD   _fUnstable         : 1; // 7 the tree is unstable because of the tree services/DOM operations 
528                                         // were performed on the tree and nobody call to validate the tree
529         DWORD   _fInSendAncestor   : 1; // 8 Notification - We're sending something to ancestors
530         DWORD   _fUnused1          : 1; // 9 
531         DWORD   _fEnableDownload   : 1; // 10 Allows content to be downloaded in this markup
532         DWORD   _fPad              : 5; // 11-15 Padding to align lookaside flags on byte
533         DWORD   _fHasLookasidePtr  : 8; // 16-23 Lookaside flags
534         DWORD   _fUnused2          : 8; // 24-31
535     };
536 
537     // Style sheets moved from CDocument
538     HRESULT EnsureStyleSheets();
539     HRESULT ApplyStyleSheets(
540         CStyleInfo*     pStyleInfo,
541         ApplyPassType   passType=APPLY_All,
542         BOOL*           pfContainsImportant=NULL);
543 
544     BOOL HasStyleSheets()
545     {   
546         return FALSE; 
547     }
548 
549 private:
550     NO_COPY(CMarkup);
551 };
代表DOM樹的結構 CMarkup類

 

  1 class CTreePos
  2 {
  3     friend class CMarkup;
  4     friend class CTreePosGap;
  5     friend class CTreeNode;
  6     friend class CSpliceTreeEngine;
  7     friend class CMarkupUndoUnit;
  8 
  9 public:
 10     DECLARE_MEMALLOC_NEW_DELETE();
 11 
 12     // TreePos come in various flavors:
 13     //  Uninit  this node is uninitialized
 14     //  Node    marks begin or end of a CTreeNode's scope
 15     //  Text    holds a bunch of text (formerly known as CElementRun)
 16     //  Pointer implements an IMarkupPointer
 17     // Be sure the bit field _eType (below) is big enough for all the flavors
 18     enum EType { Uninit=0x0, NodeBeg=0x1, NodeEnd=0x2, Text=0x4, Pointer=0x8 };
 19 
 20     // cast to CTreeDataPos
 21     CTreeDataPos* DataThis();
 22     const CTreeDataPos* DataThis() const;
 23 
 24     // accessors
 25     EType   Type() const                { return (EType)(GetFlags()&TPF_ETYPE_MASK); }
 26     void    SetType(EType etype)        { Assert(etype <= Pointer); SetFlags((GetFlags()&~TPF_ETYPE_MASK)|(etype)); }
 27     BOOL    IsUninit() const            { return !TestFlag(NodeBeg|NodeEnd|Text|Pointer); }
 28     BOOL    IsNode() const              { return TestFlag(NodeBeg|NodeEnd); }
 29     BOOL    IsText() const              { return TestFlag(Text); }
 30     BOOL    IsPointer() const           { return TestFlag(Pointer); }
 31     BOOL    IsDataPos() const           { return TestFlag(TPF_DATA_POS); }
 32     BOOL    IsData2Pos() const          { Assert(!IsNode()); return TestFlag(TPF_DATA2_POS); }
 33     BOOL    IsBeginNode() const         { return TestFlag(NodeBeg); }
 34     BOOL    IsEndNode() const           { return TestFlag(NodeEnd); }
 35     BOOL    IsEdgeScope() const         { Assert(IsNode()); return TestFlag(TPF_EDGE); }
 36     BOOL    IsBeginElementScope() const { return IsBeginNode()&&IsEdgeScope(); }
 37     BOOL    IsEndElementScope() const   { return IsEndNode()&&IsEdgeScope(); }
 38     BOOL    IsBeginElementScope(CElement* pElem);
 39     BOOL    IsEndElementScope(CElement* pElem);
 40 
 41     CMarkup* GetMarkup();
 42     BOOL    IsInMarkup(CMarkup* pMarkup) { return GetMarkup()==pMarkup; }
 43 
 44     // The following are logical comparison operations (two pos are equal
 45     // when separated by only pointers or empty text positions).
 46     int InternalCompare(CTreePos* ptpThat);
 47 
 48     CTreeNode* Branch() const;      // Only valid to call on NodePoses
 49     CTreeNode* GetBranch() const;   // Can be called on any pos, may be expensive
 50 
 51     CMarkupPointer* MarkupPointer() const;
 52     void SetMarkupPointer(CMarkupPointer*);
 53 
 54     // GetInterNode finds the node with direct influence
 55     // over the position directly after this CTreePos.
 56     CTreeNode* GetInterNode() const;
 57 
 58     long Cch() const;
 59     long Sid() const;
 60 
 61     BOOL HasTextID() const { return IsText()&&TestFlag(TPF_DATA2_POS); }
 62     long TextID() const;
 63 
 64     long GetCElements() const { return IsBeginElementScope()?1:0; }
 65     long SourceIndex();
 66 
 67     long GetCch() const { return IsNode()?1:IsText()?Cch():0; }
 68 
 69     long GetCp();
 70     
 71     int  Gravity() const;
 72     void SetGravity(BOOL fRight);
 73     int  Cling() const;
 74     void SetCling(BOOL fStick);
 75 
 76     // modifiers
 77     void SetScopeFlags(BOOL fEdge);
 78     void ChangeCch(long cchDelta);
 79 
 80     // navigation
 81     CTreePos* NextTreePos();
 82     CTreePos* PreviousTreePos();
 83 
 84     CTreePos* NextNonPtrTreePos();
 85     CTreePos* PreviousNonPtrTreePos();
 86 
 87     static BOOL IsLegalPosition(CTreePos* ptpLeft, CTreePos* ptpRight);
 88     BOOL        IsLegalPosition(BOOL fBefore)
 89     {
 90         return fBefore?IsLegalPosition(PreviousTreePos(), this):IsLegalPosition(this, NextTreePos());
 91     }
 92 
 93 protected:
 94     void      InitSublist();
 95     CTreePos* Parent() const;
 96     CTreePos* LeftChild() const;
 97     CTreePos* RightChild() const;
 98     CTreePos* LeftmostDescendant() const;
 99     CTreePos* RightmostDescendant() const;
100     void      GetChildren(CTreePos** ppLeft, CTreePos** ppRight) const;
101     HRESULT   Remove();
102     void      Splay();
103     void      RotateUp(CTreePos* p, CTreePos* g);
104     void      ReplaceChild(CTreePos* pOld, CTreePos* pNew);
105     void      RemoveChild(CTreePos* pOld);
106     void      ReplaceOrRemoveChild(CTreePos* pOld, CTreePos* pNew);
107 
108     // constructors (for use only by CMarkup and CTreeNode)
109     CTreePos() {}
110 
111 private:
112     // distributed order-statistic fields
113     DWORD       _cElemLeftAndFlags; // number of elements that begin in my left subtree
114     DWORD       _cchLeft;           // number of characters in my left subtree
115                                     // structure fields (to maintain the splay tree)
116     CTreePos*   _pFirstChild;       // pointer to my leftmost child   第一個孩子(有可能是左,也有可能是右)
117     CTreePos*   _pNext;             // pointer to right sibling or parent    右兄弟或者父親
118 
119     enum
120     {
121         TPF_ETYPE_MASK      = 0x0F,
122         TPF_LEFT_CHILD      = 0x10,
123         TPF_LAST_CHILD      = 0x20,
124         TPF_EDGE            = 0x40,
125         TPF_DATA2_POS       = 0x40,
126         TPF_DATA_POS        = 0x80,
127         TPF_FLAGS_MASK      = 0xFF,
128         TPF_FLAGS_SHIFT     = 8
129     };
130 
131     DWORD   GetFlags() const                { return (_cElemLeftAndFlags); }
132     void    SetFlags(DWORD dwFlags)         { _cElemLeftAndFlags = dwFlags; }
133     BOOL    TestFlag(DWORD dwFlag) const    { return (!!(GetFlags()&dwFlag)); }
134     void    SetFlag(DWORD dwFlag)           { SetFlags(GetFlags()|dwFlag); }
135     void    ClearFlag(DWORD dwFlag)         { SetFlags(GetFlags()&~(dwFlag)); }
136 
137     long    GetElemLeft() const             { return ((long)(_cElemLeftAndFlags>>TPF_FLAGS_SHIFT)); }
138     void    SetElemLeft(DWORD cElem)        { _cElemLeftAndFlags = (_cElemLeftAndFlags&TPF_FLAGS_MASK)|(DWORD)(cElem<<TPF_FLAGS_SHIFT); }
139     void    AdjElemLeft(long cDelta)        { _cElemLeftAndFlags += cDelta << TPF_FLAGS_SHIFT; }
140     BOOL    IsLeftChild() const             { return (TestFlag(TPF_LEFT_CHILD)); } // 確保當前位置左右資訊
141     BOOL    IsLastChild() const             { return (TestFlag(TPF_LAST_CHILD)); } // 確保是否有下一個兄弟 左/右 Next表示什麼   在左邊的時候如何判斷Next表示什麼呢?這時候就需要IsLastChild判斷有兄弟沒
142     void    MarkLeft()                      { SetFlag(TPF_LEFT_CHILD); }
143     void    MarkRight()                     { ClearFlag(TPF_LEFT_CHILD); }
144     void    MarkLeft(BOOL fLeft)            { SetFlags((GetFlags()&~TPF_LEFT_CHILD)|BOOLFLAG(fLeft, TPF_LEFT_CHILD)); }
145     void    MarkFirst()                     { ClearFlag(TPF_LAST_CHILD); }
146     void    MarkLast()                      { SetFlag(TPF_LAST_CHILD); }
147     void    MarkLast(BOOL fLast)            { SetFlags((GetFlags()&~TPF_LAST_CHILD)|BOOLFLAG(fLast, TPF_LAST_CHILD)); }
148 
149     void      SetFirstChild(CTreePos* ptp)  { _pFirstChild = ptp; }
150     void      SetNext(CTreePos* ptp)        { _pNext = ptp; }
151     CTreePos* FirstChild() const            { return (_pFirstChild); }
152     CTreePos* Next() const                  { return (_pNext); }
153 
154     // support for CTreePosGap
155     CTreeNode* SearchBranchForElement(CElement* pElement, BOOL fLeft);
156 
157     // count encapsulation
158     enum ECountFlags { TP_LEFT=0x1, TP_DIRECT=0x2, TP_BOTH=0x3 };
159 
160     struct SCounts
161     {
162         DWORD _cch;
163         DWORD _cElem;
164         void Clear();
165         void Increase(const CTreePos* ptp);    // TP_DIRECT is implied
166         BOOL IsNonzero();
167     };
168 
169     void ClearCounts();
170     void IncreaseCounts(const CTreePos* ptp, unsigned fFlags);
171     void IncreaseCounts(const SCounts* pCounts );
172     void DecreaseCounts(const CTreePos* ptp, unsigned fFlags);
173     BOOL HasNonzeroCounts(unsigned fFlags);
174 
175     BOOL LogicallyEqual(CTreePos* ptpRight);
176 
177 public:
178     NO_COPY(CTreePos);
179 };
CTreePos類

 

 1 class CTreeDataPos : public CTreePos
 2 {
 3     friend class CTreePos;
 4     friend class CMarkup;
 5     friend class CMarkupUndoUnit;
 6 
 7 public:
 8     DECLARE_MEMALLOC_NEW_DELETE()
 9 
10 protected:
11     union
12     {
13         DATAPOSTEXT t;
14         DATAPOSPOINTER p;
15     };
16 
17 private:
18     CTreeDataPos() {}
19     NO_COPY(CTreeDataPos);
20 };
class CTreeDataPos

 

  1 class CMarkupPointer : public CBase, public IMarkupPointer
  2 {
  3     DECLARE_CLASS_TYPES(CMarkupPointer, CBase);
  4 
  5     friend class CDocument; // for implementation of "OrSlave" versions of Left, Right, MoveToContainer on IHTMLViewServices
  6     friend class CMarkup;
  7 
  8 public:
  9     DECLARE_MEMALLOC_NEW_DELETE()
 10 
 11     CMarkupPointer(CDocument* pDoc)
 12         : _pDoc(pDoc), _pMarkup(NULL), _pmpNext(NULL), _pmpPrev(NULL),
 13         _fRightGravity(FALSE), _fCling(FALSE), _fEmbedded(FALSE), _fKeepMarkupAlive(FALSE),
 14         _fAlwaysEmbed(FALSE), _ptpRef(NULL), _ichRef(0), _cpCache(-1), _verCp(0)
 15     {}
 16 
 17     virtual ~CMarkupPointer()
 18     {
 19         Unposition();
 20         Assert(!Markup());
 21     }
 22 
 23     //////////////////////////////////////////////
 24     // CBase methods
 25     DECLARE_PLAIN_IUNKNOWN(CMarkupPointer);
 26     DECLARE_PRIVATE_QI_FUNCS(CBase);
 27 
 28     virtual const CBase::CLASSDESC* GetClassDesc() const;
 29 
 30     ///////////////////////////////////////////////
 31     // IMarkupPointer methods
 32     STDMETHODIMP OwningDoc(IHTMLDocument2** ppDoc);
 33     STDMETHODIMP Gravity(POINTER_GRAVITY* peGravity);
 34     STDMETHODIMP SetGravity(POINTER_GRAVITY eGravity);
 35     STDMETHODIMP Cling(BOOL* pfCling);
 36     STDMETHODIMP SetCling(BOOL fCling);
 37     STDMETHODIMP MoveAdjacentToElement(IHTMLElement* pElement, ELEMENT_ADJACENCY eAdj);
 38     STDMETHODIMP MoveToPointer(IMarkupPointer* pPointer);
 39     STDMETHODIMP MoveToContainer(IMarkupContainer* pContainer, BOOL fAtStart);
 40     STDMETHODIMP Unposition();
 41     STDMETHODIMP IsPositioned(BOOL*);
 42     STDMETHODIMP GetContainer(IMarkupContainer**);
 43 
 44     STDMETHODIMP Left(
 45         BOOL                    fMove,
 46         MARKUP_CONTEXT_TYPE*    pContext,
 47         IHTMLElement**          ppElement,
 48         long*                   pcch,
 49         OLECHAR*                pchText);
 50 
 51     STDMETHODIMP Right(
 52         BOOL                    fMove,
 53         MARKUP_CONTEXT_TYPE*    pContext,
 54         IHTMLElement**          ppElement,
 55         long*                   pcch,
 56         OLECHAR*                pchText);
 57 
 58     STDMETHODIMP MoveUnit(MOVEUNIT_ACTION muAction);
 59 
 60     STDMETHODIMP CurrentScope(IHTMLElement** ppElemCurrent);
 61 
 62     STDMETHODIMP FindText( 
 63         OLECHAR*            pchFindText, 
 64         DWORD               dwFlags,
 65         IMarkupPointer*     pIEndMatch=NULL,
 66         IMarkupPointer*     pIEndSearch=NULL);
 67 
 68     STDMETHODIMP IsLeftOf           (IMarkupPointer* pPointer,     BOOL* pfResult);
 69     STDMETHODIMP IsLeftOfOrEqualTo  (IMarkupPointer* pPointer,     BOOL* pfResult);
 70     STDMETHODIMP IsRightOf          (IMarkupPointer* pPointer,     BOOL* pfResult);
 71     STDMETHODIMP IsRightOfOrEqualTo (IMarkupPointer* pPointer,     BOOL* pfResult);
 72     STDMETHODIMP IsEqualTo          (IMarkupPointer* pPointerThat, BOOL* pfAreEqual);
 73 
 74     HRESULT FindTextIdentity(long textID, CMarkupPointer* pPointerOtherEnd);
 75     HRESULT SetTextIdentity(CMarkupPointer* pPointerOtherEnd, long* plNewTextID);
 76 
 77     HRESULT IsInsideURL(IMarkupPointer* pRight, BOOL* pfResult);
 78 
 79     ///////////////////////////////////////////////
 80     // CMarkupPointer methodse
 81     HRESULT Left(
 82         BOOL                    fMove,
 83         MARKUP_CONTEXT_TYPE*    pContext,
 84         CTreeNode**             ppNode,
 85         long*                   pcch,
 86         OLECHAR*                pchText,
 87         long*                   plTextID)
 88     {
 89         return There(TRUE, fMove, pContext, ppNode, pcch, pchText, plTextID, 0);
 90     }
 91 
 92     HRESULT Right(
 93         BOOL                    fMove,
 94         MARKUP_CONTEXT_TYPE*    pContext,
 95         CTreeNode**             ppNode,
 96         long*                   pcch,
 97         OLECHAR*                pchText,
 98         long*                   plTextID)
 99     {
100         return There(FALSE, fMove, pContext, ppNode, pcch, pchText, plTextID, 0);
101     }
102 
103     int  Gravity() const { return _fRightGravity; }
104     BOOL Cling() const { return _fCling; }
105     BOOL KeepMarkupAlive() const { return _fKeepMarkupAlive; }
106     void SetKeepMarkupAlive(BOOL fKeepAlive);
107     BOOL AlwaysEmbed() const { return _fAlwaysEmbed; }
108     void SetAlwaysEmbed(BOOL fAlwaysEmbed);
109 
110     HRESULT MoveAdjacentToElement(CElement* pElement, ELEMENT_ADJACENCY adj);
111     HRESULT MoveToPointer(CMarkupPointer* pPointer);
112     HRESULT MoveToContainer(CMarkup* pContainer, BOOL fAtStart, DWORD dwFlags=0);
113 
114     HRESULT MoveToGap(CTreePosGap* ptpg, CMarkup* pMarkup, BOOL fForceEmbedding=FALSE);
115 
116     HRESULT MoveToReference(CTreePos* ptp, long ich, CMarkup* pMarkup, long cpNew);
117 
118     HRESULT MoveToOrphan(CTreePos*);
119 
120     CTreeNode* CurrentScope(DWORD dwFlags=0);
121 
122     BOOL FindText(
123         TCHAR*          pstr, 
124         DWORD           dwFlags,
125         CMarkupPointer* pEndMatch,
126         CMarkupPointer* pEndSearch);
127 
128     BOOL IsEqualTo          (CMarkupPointer* pPointerThat);
129     BOOL IsLeftOf           (CMarkupPointer* pPointerThat);
130     BOOL IsLeftOfOrEqualTo  (CMarkupPointer* pPointerThat);
131     BOOL IsRightOf          (CMarkupPointer* pPointerThat);
132     BOOL IsRightOfOrEqualTo (CMarkupPointer* pPointerThat);
133 
134     HRESULT MoveToCp(long cp, CMarkup* pMarkup);
135 
136     HRESULT QueryBreaks(DWORD* pdwBreaks);
137 
138     // public helpers
139 
140     // called from CTreePos when it goes away
141     void OnPositionReleased();
142 
143     CDocument* Doc() const { return _pDoc; }
144 
145     CTreeNode* Branch() { return _pMarkup?_ptp->GetInterNode():NULL; }
146 
147     BOOL IsPositioned() const { return _pMarkup!=NULL; }
148 
149     CMarkup* Markup() const { return _pMarkup; }
150 
151     void SetMarkup(CMarkup* pMarkup);
152 
153     // Get the embedded treepos.  Be careful, pointers are not always
154     // embedded.
155     CTreePos* GetEmbeddedTreePos()
156     {
157         Assert(_fEmbedded);
158         return _fEmbedded?_ptpEmbeddedPointer:NULL;
159     }
160 
161     // GetNormalizedReference returns a ptp/ich pair which is
162     // immediately after REAL content.  Not real content is
163     // pointers and empty text runs.
164     CTreePos* GetNormalizedReference(long& ich) const;
165 
166     // Returns the cp for this pointer.  -1 if unpositioned;
167     long GetCp();
168 
169     // "There" does the work of both Left and Right
170     HRESULT There(
171         BOOL                    fLeft,
172         BOOL                    fMove,
173         MARKUP_CONTEXT_TYPE*    pContext,
174         CTreeNode**             ppNode, // Not AddRefed
175         long*                   pcch,
176         OLECHAR*                pchText,
177         long*                   plTextID,
178         DWORD*                  dwFlags);
179 
180     HRESULT There(
181         BOOL                    fLeft,
182         BOOL                    fMove,
183         MARKUP_CONTEXT_TYPE*    pContext,
184         IHTMLElement**          ppElement,
185         long*                   pcch,
186         OLECHAR*                pchText,
187         DWORD*                  dwFlags);
188 
189 private:
190     HRESULT UnEmbed(CTreePos** pptp, long* pich);
191 
192     HRESULT Embed(CMarkup* pMarkup, CTreePos* ptp, long ich, long cpNew);
193 
194     // representation
195     static const CBase::CLASSDESC s_classdesc; // classDesc (for CBase)
196 
197     CDocument* _pDoc; // The doc that owns me
198 
199     // The _pMarkup member points the markup I'm positioned in,
200     // when I'm positioned.  If it is NULL, then I'm not positioned
201     // in any markup, and thus the members which indicate where
202     // are unused.
203     CMarkup* _pMarkup;
204 
205     // Each markup has a list of markup pointers which are in the markup, but
206     // do not have a pointer pos.
207     CMarkupPointer* _pmpNext;
208     CMarkupPointer* _pmpPrev;
209 
210     void AddMeToList();
211     void RemoveMeFromList();
212 
213     // The members _fRightGravity and _fCling always indicate the state of
214     // gravity and cling, even when we are embedded, when the pointer pos
215     // has redundant indicators of this.  They are redundant because we want
216     // gravity and cling with out CMarkupPointer.
217     //
218     // The _fEmbedded member is used when _pMarkup is non-NULL to indicate
219     // if our position is indicated by an embedded pointer pos or a reference
220     // to a non-pointer pos / offset pair.
221     unsigned _fRightGravity    : 1; // When unpositioned, gravity is stored here
222     unsigned _fCling           : 1; // When unpositioned, cling is stored here
223     unsigned _fEmbedded        : 1; // Do I have have a pointer pos in the splay tree?
224     unsigned _fKeepMarkupAlive : 1; // Keep addref on markup
225     unsigned _fAlwaysEmbed     : 1; // Always embed this pointer
226 
227     // The _cpCache member records the cp this pointer is currently at.  If
228     // the contents version of the markup matches that stored here, then
229     // _cpCache is up to date.
230     long _cpCache;
231     long _verCp;
232 
233     long GetCpSlow() const;
234     BOOL CpIsCached() const;
235 
236     void Validate() const {}
237 
238     union
239     {
240         CTreePos*       _ptp;                   // Quick access to ptp if embedded or not
241 
242         CTreePos*       _ptpEmbeddedPointer;    // When embeded, this points to Pointer pos
243 
244         struct                                  // When not embedded, this says where I am
245         {
246             CTreePos*   _ptpRef;                // I live just after this (non-pointer) pos
247             long       _ichRef;                 // If text pos, this many chars into it
248         };
249     };
250 
251     NO_COPY(CMarkupPointer);
252 };
class CMarkupPointer

 

相關文章