Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как правильно передвать между окнами MFC сложный тип  (Прочитано 33873 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Boriska
Помогающий

us
Offline Offline

« : 07-11-2013 15:31 » 

Привет народ. Имею к класс
Код: (C++)
class CBox public CDescription,public CGeometric,public CNodes
В классе CNodes объявлены три указателя на вектора. Весктора содержат указатели на классы

Код: (C++)
BOX_NODE_COORDINATES_PNTS_VECTOR                *m_p_boxDestinNodesVector;
BOX_NODE_COORDINATES_PNTS_VECTOR                *m_p_boxDeltasNodesVector;
BOX_PLACES_PNTS_VECTOR                  *m_p_placesVector;

Сделал диалог главное окно.  В классе окна переменную
Код: (C++)
CBox m_activeBox;
Заполняю переменную и для теста вывожу
Код: (C++)
char buff[500];
        unsigned int indx;

        unsigned int size = (*m_activeBox.m_p_placesVector).size();
        for(indx = 0; indx < size; indx++){
                sprintf_s(buff,sizeof(buff),"MnD=%d MxD=%d Row = %d Colm = %d  XPos = %d  YPos = %d PosRow = %d PosColm = %d",
                        m_activeBox.GetMnD(),
                        m_activeBox.GetMxD(),
                        (*m_activeBox.m_p_placesVector)[indx]->Row(),
                        (*m_activeBox.m_p_placesVector)[indx]->Colm(),
                        (*m_activeBox.m_p_boxDestinNodesVector)[indx]->XPos(),
                        (*m_activeBox.m_p_boxDestinNodesVector)[indx]->YPos(),
                        (*m_activeBox.m_p_boxDestinNodesVector)[indx]->Row(),
                        (*m_activeBox.m_p_boxDestinNodesVector)[indx]->Colm()
                        );
                MessageBox(buff,"");   
        }
Все нормально. На окне кнопка вхожу в другой диалог там мне надо сделать пару манипуляций с m_activeBox и сохранить.
В этот диалог передаю указатель на главный диалог и через него пытаюсь сохранить
Код: (C++)
void CColorTuneDlg::OnBnClickedRightFrontBtn()
{
        if(m_pCD->CheckCurrentUserPermitoins() != SUFFICIENT_PERMISSIONS)return;

//      m_pCD->m_activeBox.SetRx(m_HorizFront.GetPos());
//      m_pCD->//m_pf_TransferBoxBottleParams(&(m_pCD->m_activeBox));
//      m_pCD->m_activeBox.UpdateBox(m_pCD->m_pLocDb);
        m_pCD->UpdateDestinNodes(m_pCD->m_activeBox);

m_pCD - указатель на главный диалог.
Код: (C++)
void CTestDlg::UpdateDestinNodes(CBox & box)
{
        char buff[500];
        CBottleBox b;
        b = box;
        unsigned int indx;
        unsigned int size = (*b.m_p_boxDestinNodesVector).size();

        for(indx = 0; indx < size; indx++)
        {
                sprintf_s(buff,sizeof(buff),"UPDATE Nodes SET Xpos = %d, Ypos = %d WHERE Row = %d AND Col = %d AND boxId = %d",
                        (*m_activeBox.m_p_boxDestinNodesVector)[indx]->XPos(),
                        (*m_activeBox.m_p_boxDestinNodesVector)[indx]->YPos(),
                        (*m_activeBox.m_p_boxDestinNodesVector)[indx]->Row(),
                        (*m_activeBox.m_p_boxDestinNodesVector)[indx]->Colm(),
                        m_activeBox.GetBoxId());
                m_pLocDb->ExecuteSQL(buff);
        }      
}

и тут обнаруживается что переменная size содержит жуть большое число. Ну соотвественно и все другие данные в вектрах съезжают и крах.
В то же время если вызвать эту функцию в диалоге где определена переменная m_activeBox там все ОК.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 07-11-2013 16:14 » 

Правильнее вынести модель в отдельные классы и передавать их объекты, а не сами окна.

А так сейчас подтянутся специалисты в MFC и скажу, что тут не так. Я бы в отладчике проверил все указатели в тех точках, где они устанавливаются, и нет ли попыток раннего или позднего к ним обращения, когда там уже неактуальные значения.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Boriska
Помогающий

us
Offline Offline

« Ответ #2 : 07-11-2013 18:09 » 

Я окна не передаю. У меня в классе диалога главного окна определена переменная. А в другие окна я передаю указатель на класс этого окна и таким образом из классов диалогов других окон добираюсь до главного. Я же написал. И функция которая сохраняет данные тоже находится в классе диалога главного окна. Так вот если ее вызывать внутри своего класса тогда все ОК а если по указателю из другого окна то баг.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 07-11-2013 19:22 » 

Цитата: lkote
У меня в классе диалога главного окна определена переменная. А в другие окна я передаю указатель на класс этого окна и таким образом из классов диалогов других окон добираюсь до главного.
"Передать указатель на объект окна" - это и есть коротко "передать окно".
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Boriska
Помогающий

us
Offline Offline

« Ответ #4 : 08-11-2013 07:12 » 

А как это делать правильно?
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #5 : 08-11-2013 08:44 » 

Нууу как Димка уже сказал: отделить данные от окон. Т.е. твоя CBox m_activeBox; не должна быть членом CTestDlg, а общедоступным объектом, указатель на который получают обработчики/манипуляторы.
А так ты сам себя запутал, ведь в UpdateDestinNodes(CBox & box) box и есть m_activeBox.

А непосредственно по проблеме, похоже что у тебя что-то не проинициаллизировано. Не совсем понятно КОГДА ты заполняешь переменную для теста, и КОГДА жмёшь кнопку вызова диалога CColorTuneDlg.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Boriska
Помогающий

us
Offline Offline

« Ответ #6 : 08-11-2013 09:54 » 

Да вот странное дело. Создал тестовый проект. Симитировал эту ситуацию и вроде все работает.
Создал в рабочем проекте другую переменную и не поверите с нее все вывожу в другом окне.
Значит где то я лезу в мою переменную. Погляжу.

Кстати насчет отделения мух от котлет. Это вы делаете глобальные переменные а в окнах храните только указатели на них?
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 08-11-2013 12:32 » 

lkote, не обязательно глобальные, их можно передавать через параметры методов и хранить в членах классов.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #8 : 08-11-2013 14:08 » 

... и не обязательно хранить в окнах указатели. Можно сделать глобальный доступ. Например, в MFC класс производный от CWinApp напрашивается сам собой. Если добавить в него метод типа:

CBox * GetActiveBox() { return например &m_activeBox; }

то тогда везде в программе можно будет пользоваться theApp.GetActiveBox();
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Boriska
Помогающий

us
Offline Offline

« Ответ #9 : 09-11-2013 11:21 » 

Народ а подскажите еще. Вот у меня sql размазан по коду. По идее это не красиво. На С# пробовал
там это можно в xml файлах. Так сказать все подготовлено для этого. С++ программистов вокруг практически
нет чтоб спросить. Как в этом случае правильно поступать, где можно набраться техники?
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 09-11-2013 14:24 » 

Во-первых, SQL и XML - вещи разные. SQL - язык запросов к базе данных, а XML - язык разметки для описания структурированных данных.

Во-вторых, чтобы SQL не был размазан по всему коду, его следует сосредоточить в одном модуле, обслуживающем всё взаимодействие программы с базой данных.

В случае .NET последних версий речь может идти об использовании LINQ - интегрированном в язык подъязыке запросов, который позволяет единообразно работать с любыми источниками данных (реляционные базы данных, XML, плоские файлы, внутренние массивы программы и т.п.).
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines