Tab Control и сохранение значений
Пишу программу с использованием MFC.
С панели инструментов кнопочкой вызываю диалоговое окно (класс Options, производный от CDialog). Для этого пишу код в МэйнФрэйме:
Options dialog;
if(dialog.DoModal()==IDOK)
{
...
}
Это работает. На вызванном диалоговом окне расположен объект Tab Control на котором создаются три вкладки. На каждую вкладку "накладываются" три созданных диалоговых окна: Page1, Page2, Page3 (т.е. 3 вкладки).
На вкладке (окне) Page 1 размещен Edit. Проблема связана с тем, что при нажатии на ОК диалогового окна Options надо сохранить значение из эдита в любую глобальную переменную. У меня не сохраняет.
переменная m_RazmerX (объявлена в классе CPage1) отвечает за обмен информацией
в файле Page1.cpp есть такая строка
void CPage1::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_RazmerX);
}
в Майнфрейме пишу
Options dialog;
CPage1 P1;
if(dialog.DoModal()==IDOK)
{
RazmImageX=P1.m_RazmerX;
}
Но m_RazmerX не изменяется, т.е. не реагирует на изменения в Эдите
Спасибо
P1.UpdateData(TRUE); ? и потом
RazmImageX=P1.m_RazmerX;
Может сперва
P1.UpdateData(TRUE); ? и потом
RazmImageX=P1.m_RazmerX;
Выдает ошибку и предлагает прервать приложение
Выдает ошибку и предлагает прервать приложение
Неплохо :)
Но во всяком случае UpdateData(FALSE) нужно где-то вызвать в самом диалоговом окне.
Неплохо :)
Но во всяком случае UpdateData(FALSE) нужно где-то вызвать в самом диалоговом окне.
Была такая фигня после долгих мучений я пришел к нескольким выводам:
1. OnDataExchange() вызываеться при создании(разрущении) окна причем как главного так и дочерних.
2. Окно вкладки создаеться при ее выборе а в остальное время оно не существует.
Происходит следующее:
Ты создаешь окно и в зависимости от вкладки по дефолту у тебя существует ОДИН ЭДИТ.
При его разрушении последовательно раздушаються сначала дочерние окна потом главное.
Так вот при разрушении вкладки по обмену данных ты получишь значение. А при разрушении окна ты его потеряешь т.к. твоего контрола не существует.
Выход - обрабатывать смену вкладок диалога.
Неплохо :)
Но во всяком случае UpdateData(FALSE) нужно где-то вызвать в самом диалоговом окне.
Тлько что еще раз взглянул на твой код
Вкладка в любом слушае должна быть данным диалога!!!
Так вот при разрушении вкладки по обмену данных ты получишь значение.
В событии OnDestroy() на вкладки я пытался сохранить значение Эдита в глобальную переменную - таже ерунда.
Кроме того мне нужно чтобы значение из Эдита заносилось в переменную только в том случае, если на диалоговом окне нажата кнопка ОК (код в первом моем сообщении). Скорее всего в каком-то месте не хватает UpdateData (FALSE), но в каком именно...
Да... еще один момент. При вызове диалогового окна в Эдит заносится значение сохраненное в этой самой глобальной переменной (т.е. рассматриваю обратную задачу), т.е. должно заноситься. На самом деле в Эдит заносится число совершенно дикое в ковырнадцатой степени (видимо граничное значение переменной типа float). Это удалось исправить путем присвоения значения этой переменной в конструкторе окна с Эдитом переменной которая связана с Эдитом по DDX. Может быть это кого-то еще натолкнет на мысль как решить эту проблемку. Спасибо.
CPage1 P1;
Ты же работаешь с Options dlg, внутри которой имеетcя свой экземпляр CPage1.
В MainFrm.cpp инициализируется переменная
float RazmImageX=10; с которой и должен происходить обмен данными в Эдите.
В этом же файле есть функция которая вызывает диалог, и в случае нажатия ОК должна присвоить переменной RazmImageX значение из Эдита, который находится в свою очередь на TabConrole.
void CMainFrame::OnOptions()
{
Options dialog;
CPage1 P1;
if(dialog.DoModal()==IDOK)
{
RazmImageX=P1.RazmerX;
}
}
TabConrol находится на диалоговом окне IDD_OPTIONS
Edit расположен на первой вкладке (Класс CPage1)
Управление вкладками написано в Options.cpp.
В конструкторе в Эдит присваивается значение переменной RazmImageX;
CPage1::CPage1(CWnd* pParent /*=NULL*/)
: CDialog(CPage1::IDD, pParent)
{
//{{AFX_DATA_INIT(CPage1)
RazmerX = RazmImageX;//0.0f;
//}}AFX_DATA_INIT
}
Цель: сделать обратное присваивание при нажатие на ОК из эдита в переменную RazmImageX
Помогите пожалуйста разобраться
friend class Options;
B Options вставляешь;
CMainFrm* m_pMainFrame;
void SetFriend( CMainFrm* pMainFrame )
{
m_pMainFrame = pMainFrame;
}
В OnOK в диалоге
....
m_pMainFrame->RazmImageX=P1.RazmerX; //Залезаешь в MainFrm
А в MainFrame дб так
Options.SetFriend( this );// Устанавливаешь доступ
Options.DoModal();
ну и не забудь header
Выкладываю исходник локализованный под данную проблему. Посмотрите плз... попадаю...
Парни, нифига не помогает. Все попробовал.
Выкладываю исходник локализованный под данную проблему. Посмотрите плз... попадаю...
1. Ты создаешь 2 разных объекта CTabPage1
MainFrm.cpp(114): CTabPage1 P1;
Options.cpp(64): CTabPage1* pPage1;
Options.cpp(65): pPage1 = new CTabPage1;
Все изменения происходят в pPage1,
а смотришь ты в Р1.
2. У тебя 2 разных Clobal
отсюда исходят все проблемы
С панели инструментов кнопочкой вызываю диалоговое окно (класс Options, производный от CDialog)
Экий ты у нас оригинал.
{
AfxOleInit();
CWinApp::InitInstance();
CPropertySheet dlg(_T("Control center"));
CClientDlg ConnectTab; // мой диалог 1 от CPropertyPage (А НЕ ОТ CDialog)
CUpdateDialog UpdateTab; // мой диалог 2 от CPropertyPage
dlg.AddPage(&ConnectTab);
dlg.AddPage(&UpdateTab);
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
}
else if (nResponse == IDCANCEL)
{
}
return FALSE;
}
Теперь при переключении между табами будет дважды вызыватся DoDataExchange (которую нужно переопределить). Сначала вызовется DoDataExchange активного таб-диалога, потом таб-диалога на который переключаемя. При завершении CPropertySheet (держателя табов) вызывается DoDataExchange АКТИВНОГО ТАБА. Вот и все.
ПС DoDataExchange - функции класов CClientDlg и CUpdateDialog, т.е. - табов
В каком файле должна быть прописана эта функция?
В Options.cpp (это окно опций, вызываемое по нажатию кнопки и содержащее вкладки)
И еще момент. Все мое описалово по созданию вкладок получается вообще не нужным?
Пока не запустил (ибо новичек в Visual, раньше в Билдере сидел).
Было бы не плохо эту потеху вообще в исходники поместить, потому что создать вкладки можно, а вот с обменом - пранзблемка.
Я конечно наглею, но может быть вы можете поправить выложенный мной последний исходник, а я проанализирую его работу, прокоменнтирую и выложу в исходники на этом сайте с учетом авторских прав (ваших естевстенно).
С уважением Евгений. Спасибо.
Разобратся труда не составит.
Так и вышло. Все заработало. Спасибо огромное!