Поиск:

Ответ в темуСоздание новой темы Создание опроса
> построение дерева в mfc, отображения дерева в процессе рисования 
V
    Опции темы
Svoin
Дата 5.7.2006, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 5.7.2006

Репутация: нет
Всего: нет



Народ, передо мной стоит задача нарисовать дерево по xml файлу. Я это сделал - дерево рисуестя, все как надо. НО, как всегда это "но", если я возьму большой xml файл ( более 2МБ ), то прога просто зависает и памяти ест столько!!.  Можно ли в mfc нарисовать чать дерева, отобразить его для пользователя, освободить память и рисовать дальше (в памяти), ну естесственно потом все это повторять. Т.е. чтоб пользователь мог видеть процесс работы проги.

Еще было бы круто сделать второй поток. который позволили бы юзеру просматривать уже нарисованное дерево. Или это совсем сьест память?


ЗЫ. Всем спасибо за ответ )
 
PM MAIL   Вверх
Coocky
Дата 5.7.2006, 10:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: 25
Всего: 62



Svoin,   что ты подразумевашь под деревом?(просто здесь люди по всякому вопросы задают smile ) Случайно не элемент CTreeCtrl? 


--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
Svoin
Дата 5.7.2006, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 5.7.2006

Репутация: нет
Всего: нет



Да smile

Сорри что не пояснил 
PM MAIL   Вверх
Coocky
Дата 5.7.2006, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: 25
Всего: 62



Цитата(Svoin @  5.7.2006,  10:40 Найти цитируемый пост)
то прога просто зависает и памяти ест столько!!.  


Цитата(Svoin @  5.7.2006,  10:40 Найти цитируемый пост)
Я это сделал 

Можно поинтересоваться-каким способом ты заполняешь(создаеш) ветки? smile 

Цитата(Svoin @  5.7.2006,  10:40 Найти цитируемый пост)
Можно ли в mfc нарисовать чать дерева, отобразить его для пользователя, освободить память и рисовать дальше (в памяти), ну естесственно потом все это повторять

А проводник как работает в Windows smile ?
 Вообше-где ты память выделяешь?
Короче вылаживай часть кода..
  

Это сообщение отредактировал(а) Coocky - 5.7.2006, 11:03


--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
Svoin
Дата 5.7.2006, 11:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 5.7.2006

Репутация: нет
Всего: нет



В общем, я юзаю написанную когда- то SAX parsing, который читает теги xml'я и создает статус типа: старт тэг, текст, коммент, энд тэг... и т.д. Все это делает парсинг.

Я создал класс который вылавливает этот статус и там рисует дерево, что то в этом духе:

Код

в h файле 2 переменные
private:
    CTreeCtrl & m_Leaf;  // сюда мы пеердаем наш обьект дерева, с помощью которого все и рисуем
    HTREEITEM Parent;   // а это радитель узлов


cpp файл
CDrawTree::CDrawTree(CTreeCtrl & m_Tr)
:m_Leaf(m_Tr)
{
    Parent = NULL;
}

.......


int CDrawTree::StartTag(CString name)
{
    if (Parent == NULL)
               Parent = m_Leaf.InsertItem(name,1,1);
    else
              Parent = m_Leaf.InsertItem(name,1,1, Parent);
    return 0;
}

// тут рисуем атрибуты которые указаны в теге хмл файла
int CDrawTree::DrawAttribute(CString name, CString value)
{
    HTREEITEM _parent = m_Leaf.InsertItem(name,4,4, Parent);
    if ( value.Trim(" ").GetLength() == 0)
        m_Leaf.InsertItem("[space]",5,5,_parent);
    else
        m_Leaf.InsertItem(value,2,2,_parent);
    return 0;
}

// тут текст между тегом
void CDrawTree::DrawText(CString value)
{
    if(value != "")
    {
        if (value.Trim(" ").GetLength() == 0)
            m_Leaf.InsertItem("[space]",5,5,Parent);
        else
            m_Leaf.InsertItem(value,2,2,Parent);
    }
        

}

int CDrawTree::EndTag(CString name)
{
    if (Parent != NULL)
    {
        Parent = m_Leaf.GetParentItem(Parent);
    }
    return 0;
}



А это процесс вызова методов:

void Roundtrip::writeToken()
{
    switch (parser.getEventType())
    {
                          ... 

    case XmlPullParser::START_TAG :
        {
            drawing.StartTag(parser.getName());            
            for (int i = 0; i < parser.getAttributeCount(); i++) 
            {
                drawing.DrawAttribute( parser.getAttributeName(i),  parser.getAttributeValue(i));
            }
        }
        break;
    case XmlPullParser::END_TAG :
        drawing.EndTag(parser.getText());
        break;
    case XmlPullParser::TEXT :
        drawing.DrawText(parser.getText());
        break;

                                                      ...


    default :
        throw new XmlPullParserException("unrecognized event: ","",0,0);
    }
}

void Roundtrip::roundTrip()
{     
    while (parser.getEventType() != XmlPullParser::END_DOCUMENT) // получаем статус
    {
        writeToken();        
        parser.nextToken();  //читаем файл далее        
    }
    writeToken();
}




Хотелось бы, например,  при статусе EndTag добавить код для отображения дерева пользователю в диалоговом окне

Добавлено @ 11:15 
как то много получилось, надеюсь понятно будет  

Это сообщение отредактировал(а) Svoin - 5.7.2006, 11:42
PM MAIL   Вверх
Coocky
Дата 5.7.2006, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: 25
Всего: 62



Цитата(Svoin @  5.7.2006,  11:15 Найти цитируемый пост)
как то много получилось, надеюсь понятно будет 

Для понятности есть тег Код на форуме (справа в верху)
Сейчас я переведу сам
Код

private:
    CTreeCtrl & m_Leaf;  // сюда мы пеердаем наш обьект дерева, с помощью которого все и рисуем
    HTREEITEM Parent;   // а это радитель узлов


cpp файл
CDrawTree::CDrawTree(CTreeCtrl & m_Tr)
:m_Leaf(m_Tr)
{
    Parent = NULL;
}

.......


int CDrawTree::StartTag(CString name)
{
    if (Parent == NULL)
               Parent = m_Leaf.InsertItem(name,1,1);
    else
              Parent = m_Leaf.InsertItem(name,1,1, Parent);
    return 0;
}

// тут рисуем атрибуты которые указаны в теге хмл файла
int CDrawTree::DrawAttribute(CString name, CString value)
{
    HTREEITEM _parent = m_Leaf.InsertItem(name,4,4, Parent);
    if ( value.Trim(" ").GetLength() == 0)
        m_Leaf.InsertItem("[space]",5,5,_parent);
    else
        m_Leaf.InsertItem(value,2,2,_parent);
    return 0;
}

// тут текст между тегом
void CDrawTree::DrawText(CString value)
{
    if(value != "")
    {
        if (value.Trim(" ").GetLength() == 0)
            m_Leaf.InsertItem("[space]",5,5,Parent);
        else
            m_Leaf.InsertItem(value,2,2,Parent);
    }
        

}

int CDrawTree::EndTag(CString name)
{
    if (Parent != NULL)
    {
        Parent = m_Leaf.GetParentItem(Parent);
    }
    return 0;
}



А это процесс вызова методов:

void Roundtrip::writeToken()
{
    switch (parser.getEventType())
    {
                          ... 

    case XmlPullParser::START_TAG :
        {
            drawing.StartTag(parser.getName());            
            for (int i = 0; i < parser.getAttributeCount(); i++) 
            {
                drawing.DrawAttribute( parser.getAttributeName(i),  parser.getAttributeValue(i));
            }
        }
        break;
    case XmlPullParser::END_TAG :
        drawing.EndTag(parser.getText());
        break;
    case XmlPullParser::TEXT :
        drawing.DrawText(parser.getText());
        break;

                                                      ...


    default :
        throw new XmlPullParserException("unrecognized event: ","",0,0);
    }
}

void Roundtrip::roundTrip()
{     
    while (parser.getEventType() != XmlPullParser::END_DOCUMENT) // получаем статус
    {
        writeToken();        
        parser.nextToken();  //читаем файл далее        
    }
    writeToken();
}



Добавлено @ 11:25 
Глянул smile 
Честно сказать -страшновато smile  Наследие консольного программирования.
 вопросы
1. Куда указывает ссылка CTreeCtrl & m_Leaf Стремный фрагмент кода smile  


--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
Svoin
Дата 5.7.2006, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 5.7.2006

Репутация: нет
Всего: нет



Ну естественно все это рисуется в каком то диалоговом окне, в котором и лежит контрол 

В классе этого диалогового окна и происходит инициализация
DDX_Control(pDX, IDC_XML_TREE, m_Tree)     а также  ImageList

там и происходит создание обектов классов для работы с деревом

Код

 try
      {
          std::ifstream ifs;
          ifs.open(fileName);
          XmlPullParser xpp(ifs);

          CDrawTree dr(m_Tree);
          
          Roundtrip rt(xpp,dr);
          rt.roundTrip();
      }



ЗЫ  
Цитата
Честно сказать -страшновато   Наследие консольного программирования.
  Саммому так же  smile , но надо 
PM MAIL   Вверх
Dart
Дата 5.7.2006, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 103
Регистрация: 26.6.2006
Где: Саратов, РФ

Репутация: 2
Всего: 2



Цитата(Svoin @  5.7.2006,  10:40 Найти цитируемый пост)
если я возьму большой xml файл ( более 2МБ ), то прога просто зависает и памяти ест столько!!

Се ля ви smile 
Деревья виртуальными не сделаешь.
Для них необходимо хранение в памяти всей информации.

Создай поток и заполняй свое дерево в потоке. В этом случае юзверь сможет просматривать то, что уже прочитал твой парсер. 
--------------------
ЦитатаЛюблю смотреть, как другие работают
 Дж. К. ДжеромСайт: www.ecosigma.ruПочта: [email protected] 
PM MAIL WWW ICQ   Вверх
Svoin
Дата 5.7.2006, 11:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 5.7.2006

Репутация: нет
Всего: нет



К сожелению mfc знаю мало, это мне тут здуру такой таск подкинули т.к. мой парсинг, так что можно поподробнее о потоках и как это все реализавать? 
PM MAIL   Вверх
Coocky
Дата 5.7.2006, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: 25
Всего: 62



Цитата(Dart @  5.7.2006,  11:37 Найти цитируемый пост)
Создай поток и заполняй свое дерево в потоке

Это спасет только от зависания приложения.
Другое дело-утечка памяти....


Цитата(Svoin @  5.7.2006,  11:41 Найти цитируемый пост)
так что можно поподробнее о потоках и как это все реализавать? 

Можно, но форуме-куча тем про это. Поищи пока, разбирись.
 


--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
Svoin
Дата 5.7.2006, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 5.7.2006

Репутация: нет
Всего: нет



Цитата

Это спасет только от зависания приложения.
Другое дело-утечка памяти....


А это как исправить? вообще реально? 
PM MAIL   Вверх
Coocky
Дата 5.7.2006, 11:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: 25
Всего: 62



Цитата(Svoin @  5.7.2006,  11:49 Найти цитируемый пост)
А это как исправить? вообще реально?  

Ну конечно!
Только если ты не путаешь утечку памяти с реальным использованием памяти самого CTreeCtrl
 


--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
Svoin
Дата 5.7.2006, 12:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 5.7.2006

Репутация: нет
Всего: нет



С трудом понимаю что-нибуть счас. Короче.


Когда парсинг запускаеш в консоле - память минимум, но и вид никакой того что там выводится, поэтому и было сделано это мфсишное приложение. Запускаеш маленький файлик - все кульно - 6Кб берет памяти (смотрю в таск менеджере ).
Запускае большой файл - и полетело... зависон и 70Кб 

По логике это дерево память ест, сам парсинг элементарен, в этом плане, до безобразия 

Это сообщение отредактировал(а) Svoin - 5.7.2006, 12:05
PM MAIL   Вверх
Coocky
Дата 5.7.2006, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: 25
Всего: 62



Цитата(Coocky @  5.7.2006,  11:57 Найти цитируемый пост)
Только если ты не путаешь утечку памяти с реальным использованием памяти самого CTreeCtrl


Цитата(Svoin @  5.7.2006,  12:03 Найти цитируемый пост)
С трудом понимаю что-нибуть счас

Ты пойми, что CTreeTrl- это обьект, и эму тоже нужна память для хранения информации. Если ты напарсил на 70 кБ и сохранил, то там оно и будет.
Вообще для начала найди прмер простенький с деревом(у меня под рукой нет сейчас). В инете их куча.
Посмотри, поюзай. Попробукй вставить свой парсинг . Иначе будем долго потеть.
Вообще утечка памяти в студии определяется одним из простых методов (не самым эффективным).
Нажимаешь  F5, юзаешь прогу, а затем  закрываеш ее.. И смотришь в окне отладчика. Если видишь надпись Detected memory leak! значит есть утечка. Он там еще блоки показывает.
Пока остновись на этом
 


--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
Svoin
Дата 5.7.2006, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 5.7.2006

Репутация: нет
Всего: нет



Так в этом то и сосоял вопрос. Можно ли в процессе рисования отобразить чать дерева, освободить память и рисовать в памяти следующий блок 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.1204 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.