SomewhereSomeho_ |
Отправлено: 17.12.2004, 12:40 |
|
Не зарегистрирован
|
Всем , доброе время суток. Сделал класс с помощью которого можно HTML-документ представить ввиде дерева, передаешь ему указатель на ком интерфэйс этого документа из TCppWebBrowser и он создает в памяти древовидную структуру из тагов этого документа.
Привожу код, если кому не в лом будет посмотреть — прошу помочь и сказать почему не освобождается память из под объекта.
CODE |
//==============================================================================
//Данный класс является базовым классом для представления ХТМЛ тага.
//Конструктор:
// THtmlTag(IHTMLDocument2* pDoc) — Конструктор для создания базового элемента ROOT
// THtmlTag(IHTMLElement *pElem,THtmlTag *ParentTag) — Конструктор для создания любых других элементов
//Свойства:
// Name — Название тага
// Text — Текст который содержит таг
// TagInterface — Указатель на СОМ-интерфэйс этого тага в ИнтернетЭксплорере
// ChildTagsCount — Количество дочерних тагов
// Parent — Указатель на объект этого же класса, являющийся родителем для этого объекта
// ChildTags — Массив указателей на дочерние объекты.
//Методы:
// Free — Удаляет объект и все его дочерние объекты из памяти.
// ToTreeView — воспроизводит древовидную структуру всех дочерних объектов и выводит ее в дерево.
//Примечания:
// Каждому объекту класса ставится в соответствие таг в ХТМЛ документе, для парсинга документа
// используется внутренний парсер интернет-эксплорера (ИЕ), структура документа представляет собой
// древовидную структуру. Соответственно, т.к. у каждого тага есть область действия и все таги,
// что лежат в этой области действия считаются дочерними для этого тага, эта структура и отражена
// в объектах данного класса. Для более подробного представления структуры ХТМЛ документа см. материалы
// по DOM (Data Object Model) MS DHTML. Для доступа к механизмам парсинга ИЕ используются
// интерфэйсы СОМ-объектов которые предоставляет ИЕ. Указателем на такой элемент в классе явлется
// член свойство объекта TagInterface.
//==============================================================================
//------------------------------------------------------------------------------
class THtmlTag
{
private:
//-------------------------Закрытые свойства объека-------------------------//
//-------------------------Закрытые методы объека---------------------------//
// Описания даны в файле реализации
void __fastcall ToTreeViewRecursion(THtmlTag *Tag,TTreeView * HtmlTree, TTreeNode *TreeNode, bool DisplayName, bool DisplayText,bool DisplayLink, AnsiString Delimeter);
//--------------------------------------------------------------------------//
public:
//------------------------- Открытые свойства объека------------------------//
AnsiString Name; //Название тага
AnsiString Text; //Текст который содержит таг
TStringList *Links; //Ссылки которые содержит таг
IHTMLElement *TagInterface; //Указатель на СОМ-интерфэйс этого тага в ИнтернетЭксплорере
long ChildTagsCount; //Количество дочерних тагов
THtmlTag *Parent; //Указатель на объект этого же класса, являющийся родителем для этого объекта
THtmlTag **ChildTags; //Массив указателей на дочерние объекты.
//------------------------- Открытые методы объека--------------------------//
// Описания даны в файле реализации
__fastcall THtmlTag(IHTMLDocument2* pDoc);
__fastcall THtmlTag(IHTMLElement *pElem,THtmlTag *ParentTag);
void __fastcall Free();
void __fastcall ToTreeView(TTreeView *TreeView,bool DisplayName, bool DisplayText,bool DisplayLink, AnsiString Delimeter);
//--------------------------------------------------------------------------//
};
//-------------И самое главное метод Free()--------------
//---------------------------------------------------------------------------
void __fastcall THtmlTag::Free()
{
try
{
for (int i = 0; i < this->ChildTagsCount; i++)
this->ChildTags[i]->Free();
if (this->TagInterface!=NULL)
this->TagInterface->Release();
Links->Free();
delete[] ChildTags;
delete this;
}
catch(...)
{;}
}
//---------------------------------------------------------------------------
// Тип:
// Конструктор
// Принадлежность:
// Класс THtmlTag
// Доступ:
// Открытый
// Что делает:
// Конструктор класса, для создания объекта класса на основе интерфэйса СОМ
// объекта интернет-эксплорера IHTMLElement.
// Параметры:
// 1) IHTMLElement *pElem — Указатель на СОМ- интерфэйс
// 2) THtmlTag *ParentTag - Указатель на родительский объект этого же класса
// если элемент создается как первый элемент а не как чей-то потомок передается значение NULL
// Возвращаемое значение:
// Указатель на созданный объект.
__fastcall THtmlTag::THtmlTag(IHTMLElement *pElem,THtmlTag *ParentTag)
{
Name = "UNKNOWNTAG";
Text = "";
Parent = ParentTag;
TagInterface = pElem;
Links = new TStringList();
AnsiString Link;
BSTR wsName, wsText;
Variant vLink;
vLink.Empty();
WideString wsAttributeName = "href";
pElem->get_tagName(&wsName);
pElem->get_innerText(&wsText);
pElem->getAttribute(wsAttributeName.c_bstr(),0,vLink);
if(wsName)
{
Name = wsName;
}
if(wsText)
{
Text = wsText;
}
try
{
Link = VarToStr(vLink);
Links->Add(Link);
}
catch(...)
{;}
SysFreeString(wsName);
SysFreeString(wsText);
//------
IDispatch *IDispChildren, *IDispChild;
IHTMLElementCollection * ICollChildren;
IHTMLElement *ChildElement;
TagInterface->get_children(&IDispChildren);
IDispChildren->QueryInterface(IID_IHTMLElementCollection,(void**) &ICollChildren );
if(SUCCEEDED(ICollChildren->get_length(&ChildTagsCount)))
{
ChildTags = (THtmlTag **)malloc(sizeof(THtmlTag)*ChildTagsCount);
for(long j = 0; j <ChildTagsCount; j++)
{
ICollChildren->item(TVariant(j), TVariant(0), &IDispChild);
if(SUCCEEDED(IDispChild->QueryInterface(IID_IHTMLElement, (void**) &ChildElement)))
{
if (ChildElement==NULL)
continue;
ChildTags[j] = new THtmlTag(ChildElement, this);
}
}
}
IDispChildren->Release();
ICollChildren->Release();
//------
}
//---------------------------------------------------------------------------
// Тип:
// Конструктор
// Принадлежность:
// Класс THtmlTag
// Доступ:
// Открытый
// Что делает:
// Конструктор класса, для создания объекта класса на основе интерфэйса СОМ
// объекта интернет-эксплорера IHTMLDocument2.
// Параметры:
// 1) IHTMLDocument2* pDoc — Указатель на СОМ- интерфэйс
// Возвращаемое значение:
// Указатель на созданный объект.
// Примечание:
// Данным конструктором создается объект ROOT который не соответствует никакому тагу
// в документе но является корнем древовидной структуры объектов. Самый старший таг в документе
// <HTML> таг, но если вдруг в документе есть еще таги того же уровня (например коментарии в начале страницы)
// то чтобы не упускать их из поля зрения все они помещаются как дочерние в объект ROOТ.
__fastcall THtmlTag::THtmlTag(IHTMLDocument2* pDoc)
{
Name = "ROOT";
Text = "";
Parent = NULL;
TagInterface = NULL;
Links = new TStringList();
IHTMLElementCollection * pElemColl;
if(SUCCEEDED(pDoc->get_all(&pElemColl)))
{
long Count;
IHTMLElement *pElem, *pParentElem;
TList *List = new TList();
IDispatch *pmDisp;
if(SUCCEEDED(pElemColl->get_length(&Count)))
for(long i = 0; i < Count; i++)
{
pElemColl->item(TVariant(i), TVariant(0), &pmDisp);
if(SUCCEEDED(pmDisp->QueryInterface(IID_IHTMLElement, (void**) &pElem)))
{
pElem->get_parentElement(&pParentElem);
if (pParentElem==NULL)
List->Add(pElem);
}
}
ChildTagsCount = List->Count;
ChildTags = (THtmlTag **)malloc(sizeof(THtmlTag)*ChildTagsCount);
for(long i = 0; i < ChildTagsCount; i++)
{
ChildTags[i] = new THtmlTag(((IHTMLElement *)List->Items[i]), this);
}
List->Free();
pParentElem->Release();
pmDisp->Release();
pElemColl->Release();
}
}
| |
|
Bond |
Отправлено: 05.01.2005, 11:22 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 142
|
привет. я начал разбираться с кодом, но на это нужно много времени.
а его нету вкратце:
1. деструктор вызывается в момент освобождения памяти, которую занимает экземпляр класса, а ты в деструкторе класса просиш экземпляр удалить себя же — неверно. я не пробовал, не знаю что получиться. смотри
2. в деструкторе узла дерева необходимо улалять все вложенные елементы, а у них в свою очередь будут вызываться их деструкторы и так по цепочке
3. в деструкторе корня дерева удаляй его вложенные элементы
|
|
|