Click here to Skip to main content
15,886,069 members
Articles / Programming Languages / C#

The most complete C# Webbrowser wrapper control

Rate me:
Please Sign up or sign in to vote.
4.90/5 (141 votes)
28 May 2007CPOL21 min read 3M   40K   511  
A C# (.NET 2.0) control which creates, hosts, and offers advanced customization such as dragdrop, file downloads, HTTP/S header viewing, and much more.
////////////////////////////////////////////////////////////////////////////////
// ATL/AUX -- COM/ATL Useful Helpers
// AuxNode.h - CNode - generic double linked node to form a circular list.
// Copyright (c) by Andrew Nosenko (andien@geocities.com), 1997-98
// http://www.geocities.com/~andien/atlaux.htm
//
// The main difference from classic STL/MFC list:
// The object CFoo derives from CTypedNode<CFoo> and participates in the list
// as the body [with m_pNext/m_pPrev], not a reference. This way the object can
// remove itself whenever it wants [with Exclude()], having no knowledge about 
// the list root location.
//
// Virtual entry point [Done()] is provided for the list owner to allow to shutdown 
// a node prematurely. CFoo may override Done() to perform its specific shutdown.
//
// The most natural example of use is a list of polymorphic tasks represented by objects
// (e.g, threads). When the task is done, it removes itself from the list. When the whole 
// proceess is down, it forcedly terminates all objects via Done().
//
// The list may consist of COM objects. There is no need for extra [AddRef] reference 
// for object to participate at the list. But the object should remove itself from the 
// list when its task is over (e.g., download) or upon destruction (i.e., when the last 
// strong reference is gone).

/* Change Log:
1.00.0003
  - CNode::DoneAllNodes added
  - CNODE_NO_VTABLE added
1.00.0002
  - CNode::~CNode for debug purpose
1.00.0001
  - IsEmpty() added.
1.00.0000
  - Created based on my old stuff.
*/

#ifndef _NODE_H
#define _NODE_H

#ifndef CNODE_NO_VTABLE
  #ifdef ATL_NO_VTABLE
    #define CNODE_NO_VTABLE ATL_NO_VTABLE 
  #else
    #define CNODE_NO_VTABLE 
  #endif
#endif

/////////////////////////////////////////////////////////////////////////////
// class CNode is the root of all list elements

class CNODE_NO_VTABLE CNode {
protected:
  CNode* m_pNext;
  CNode* m_pPrev;

public:
  CNode() { Init(); }
  ~CNode();

  // virtual 'door' to allow a shutdown
  virtual void Done() {
    Reset(); }
  void Init() {
    m_pNext = m_pPrev = this; }
  void Reset() {
    Exclude(); Init(); }
  void Exclude();

  CNode* GetNext() const { 
    return m_pNext; }
  CNode* GetPrev() const { 
    return m_pPrev; }
  bool IsEmpty() const {
    return m_pNext == this; }

  CNode* Add(CNode* pNode);
  CNode* AddTail(CNode* pNode);
  CNode* Join(CNode* pNode);
  CNode* JoinTail(CNode* pNode);
  int GetCount() const;
  void DoneAllNodes();
  CNode& operator+(CNode& Node) { 
    return *Add(&Node); }
};

class CStubNode: public CNode {
// no CNODE_NO_VTABLE, has properly layed out vtable
};

/////////////////////////////////////////////////////////////////////////////
// class CNode is the type-safe wrapper class of CNode

template<class Derived>
class CNODE_NO_VTABLE CTypedNode: public CNode {
public:
  typedef CTypedNode _Node;
  // add a node
  Derived* Add(Derived* pNode) { 
    return static_cast<Derived*>(CNode::Add(static_cast<CNode*>(pNode))); }
  Derived* AddTail(Derived* pNode) { 
    return static_cast<Derived*>(CNode::AddTail(static_cast<CNode*>(pNode))); }
  // join another whole list
  Derived* Join(Derived* pNode) { 
    return static_cast<Derived*>(CNode::Join(static_cast<CNode*>(pNode))); }
  Derived* JoinTail(Derived* pNode) { 
    return static_cast<Derived*>(CNode::JoinTail(static_cast<CNode*>(pNode))); }
  Derived* GetNext() const { 
    return static_cast<Derived*>(CNode::GetNext()); }
  Derived* GetPrev() const { 
    return static_cast<Derived*>(CNode::GetPrev()); }
  Derived& operator+=(Derived& Node) { 
    return *Add(&Node); }
  bool IsRoot(const Derived* pNode) const { 
    return static_cast<const CNode*>(pNode) == this; }
};

template<class Node>
class CNODE_NO_VTABLE CTypedList: public CTypedNode<Node> {
public:
  ~CTypedList() {
    while ( !IsEmpty() )
      delete static_cast<Node*>(CNode::GetNext());
  }
};

/////////////////////////////////////////////////////////////////////////////
// CNode's inlines

inline CNode::~CNode() {
  _ASSERTE(m_pNext == m_pPrev && (m_pNext == this || m_pNext == (CNode*)0xFEFEABCD));
  // if assertion occurred, you forgot
  // to exclude the object form the list
}

inline CNode* CNode::Add(CNode* pNode) {
  pNode->m_pNext = m_pNext;
  m_pNext = m_pNext->m_pPrev = pNode;
  return pNode->m_pPrev = this;
}

inline CNode* CNode::AddTail(CNode* pNode) {
  pNode->m_pPrev = m_pPrev;
  m_pPrev = m_pPrev->m_pNext = pNode;
  return pNode->m_pNext = this;
}

inline CNode* CNode::Join(CNode* pNode) {
  CNode* p = pNode->m_pPrev;
  m_pNext->m_pPrev = p;
  p->m_pNext = m_pNext;
  m_pNext = pNode;
  return pNode->m_pPrev = this;
}

inline CNode* CNode::JoinTail(CNode* pNode) {
  CNode* p = pNode->m_pPrev;
  m_pPrev->m_pNext = pNode;
  pNode->m_pPrev = m_pPrev;
  m_pPrev = p;
  return p->m_pNext = this;
}

inline void CNode::Exclude() { 
  m_pNext->m_pPrev = m_pPrev;
  m_pPrev->m_pNext = m_pNext;
#ifdef _DEBUG
  m_pNext = m_pPrev = (CNode*)0xFEFEABCD;
#endif
}

inline int CNode::GetCount() const {
  int c = -1;
  const CNode* pNode = this;
  do c++; 
  while ( (pNode = pNode->GetNext()) != this );
  return c;
}

inline void CNode::DoneAllNodes() {
  while ( !IsEmpty() )
    GetNext()->Done();
}

#endif //_NODE_H

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions