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

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

ru
Offline Offline
Сообщений: 13


« : 16-09-2009 04:46 » 

наверное, вопросы к Джону )

в общем, вопросы такие

1) имеется диалог D с уже положенным на него в редакторе контролом K.
  Если делаем GetDlgItem(K_ID)->DestroyWindow(), а потом заменим на свой контрол K2 через K2.Create, как потом система обходится с экземпляром контрола K- он автоматически освободится ? То есть убили его и забыли ? (я полагаю, что просто m_hWnd подменяется, то есть, с точки зрения диалога как бы ничего и не произошло)

2) если изначально на диалоге нет контрола K , создаём через new, крепим к диалогу через Create, то нужно ли потом вызывать для контрола DestroyWindow или достаточно его delete ?
« Последнее редактирование: 16-09-2009 04:49 от Алексей1153++ » Записан

Джон
просто
Администратор

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

« Ответ #1 : 16-09-2009 09:35 » 

Нууу наверное ко мне. Ага

Эмммм тут надо уточнить. Значит так, если ты в редакторе ресурсов "положил" кнопочку на диалог, то это ещё не контрол.
Ты просто в удобной форме отредактировал отредактировал .rc-файл. Те записал все необходимые данные для создания контрола в будущем, всё подготовил.  Теперь диалог запущен. У тебя есть две возможности: 1. Воспользовавашись какой-нить ф-ей DDX, создать объект с использованием этих ресурсов, но твоего собственного типа 2. Вааабще ничего не делать, а просто  вызвать GetDlgItem. В этом случае ты получаешь указатель на временный объект созданный MFC и хранящийся во внутреннем списке, к которому ты доступ не имеешь. Более того, как только родительское окно разрушено (но сам объект ещё существует!) GetDlgItem вернёт тебе NULL (в дебуге получишь ещё и ASSERT). Это можно легко проверить, вызвав dlg.GetDlgItem после dlg.DoModal. Я так глубоко не копал, но очень может быть, что и Destroy для контролов тоже уже будут вызваны, во всяком случае это логично и скорей всего так и есть - родительское окно передаёт своим контролам WM_DESTROY. Перехвати его в твоём контроле. Да и так можно проверить очень просто - ::IsWindow(хэндл твоего контрола). Тут кстати сразу ответ на второй вопрос - лучше (чище) всего в этом случае проверить хэндл и в случае необходимости разрушить. А вдруг кто-нить забудет разрушают детёнка. В самом общем случае это ведь не обязательно. А самому проверить и разрушить - одна строчка кода.

Но возвращаясь к 1. Из выше сказанного я не совсем понял вот это

"потом заменим на свой контрол K2 через K2.Create"

покажи код, как ты себе это представляешь?
« Последнее редактирование: 16-09-2009 09:37 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #2 : 16-09-2009 09:48 » 

не, Джон, по первой части - это всё понятно, но вопрос не о том. А о том, что я подменяю контрол на другой, производный от CWnd и забываю про это - то есть дальше всё вроде автоматом происходит (имеется в виду разрушение и удаление окна). Это был вопрос по статике.

Второй вопрос по динамике. Отличие лишь в том, что контрол - не член класса диалога. Сделал так (вроде всё работает Улыбаюсь )

Пример (названия взяты из кода, поэтому не спрашивать, почему они такие Улыбаюсь )

на диалоге положен статик с ID== TESTDEV_1_1_A_6 . Это заготовка

Код:
class C_TESTDEV_1 : public CDialog
{
CEdit* mp_TESTDEV_1_1_A_6;
};

C_TESTDEV_1::C_TESTDEV_1(CWnd* pParent /*=NULL*/): CDialog(C_TESTDEV_1::IDD, pParent)
{
//{{AFX_DATA_INIT(C_TESTDEV_1)
//}}AFX_DATA_INIT

mp_TESTDEV_1_1_A_6=0;
}

BOOL C_TESTDEV_1::OnInitDialog()
{
CDialog::OnInitDialog();

if(!mp_TESTDEV_1_1_A_6)
{
CWnd* pw=0;
CRect rCtrl;
UINT ID=0;
ID=TESTDEV_1_1_A_6;

if(pw=GetDlgItem(ID))
{
pw->GetWindowRect(&rCtrl);
pw->DestroyWindow();
mp_TESTDEV_1_1_A_6=new CEdit();
if(mp_TESTDEV_1_1_A_6)
{
::MapWindowPoints(0,m_hWnd,(CPoint*)&rCtrl,2);
if(mp_TESTDEV_1_1_A_6->CreateEx(
WS_EX_CLIENTEDGE|WS_EX_NOPARENTNOTIFY,
"Edit","",
WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_EX_CLIENTEDGE,
rCtrl,this,ID,0))
{
mp_TESTDEV_1_1_A_6->SetFont(GetFont(),0);
}
}
}
}


return TRUE;
}

C_TESTDEV_1::~C_TESTDEV_1()
{
if(mp_TESTDEV_1_1_A_6)
{
delete mp_TESTDEV_1_1_A_6;
mp_TESTDEV_1_1_A_6=0;
}
}

утечек и обломов не наблюдается. Это всё корректно ?
Записан

Джон
просто
Администратор

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

« Ответ #3 : 16-09-2009 10:05 » 

Эмммм подмену я так и не увидел. А так это классическая схема, когда делаешь дизайн в редакторе, а потом используешь прямоугльники статиков для своих контролов. Вроде всё правильно. Только я бы ещё в силу сказаного выше добавил бы в деструктор:

Код:
C_TESTDEV_1::~C_TESTDEV_1()
{
if(mp_TESTDEV_1_1_A_6 && ::IsWindow(mp_TESTDEV_1_1_A_6->GetSafeHwnd()))
{
mp_TESTDEV_1_1_A_6->DestroyWindow();
}
delete mp_TESTDEV_1_1_A_6;
mp_TESTDEV_1_1_A_6=NULL;
}

Хотя лучше (грамотней) всего добавить это в OnDestroy диалога.
В остальном всё корректно.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 16-09-2009 10:09 » 

вот вопрос как раз про это и был, так ли нужно
mp_TESTDEV_1_1_A_6->DestroyWindow();
?

или деструктор сам порушит и освободит хендл ?
Записан

Джон
просто
Администратор

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

« Ответ #5 : 16-09-2009 10:45 » 

Не однозначно. Деструктор разрушает объект, но разрушает ли он окно? А что тебя смущает в проверке?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 16-09-2009 10:49 » 

проверка вещь хорошая. Но вот где точно узнать, дестроит ли окно своих контролов или это надо обязательно делать самому.

Ну ладно, сделаю дестрой с проверкой, на всякий случай )
Записан

Джон
просто
Администратор

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

« Ответ #7 : 16-09-2009 12:16 » 

Лёш, это очень просто - просто просмотреть ВЕСЬ используемый код и ФСЁ станет ясно. Ага
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #8 : 12-11-2009 11:54 » 

решил сюда написать, чтобы тему не создавать.


в студии №6:

вот такой код
Код:
	{
CFileDialog dlgOpen(1,0,0,0,0,0);
}

падает и начинает валяться. 1 час разбирался, оказалось, падает во время вызова деструктора мембера CFileDialog

   CString m_strFilter;          // filter string


Уж сначала просто поставил поимку try{}catch(...){} , потому что не было времени больше возюкаться. А потом решил обернуть всё это дело в класс с pimpl ...  И ответ нашёлcя:
Код:
	{
CFileDialog* dlgOpen= new CFileDialog(1,0,0,0,0,0);
delete dlgOpen;
dlgOpen=0;
}

 - созданный динамически объект нормально потом удаляется, без падания! Что это , и почему раньше я не наталкивался на это ? Что то в мире поменялось ? ))) С ума схожу, да ? Чесно скажите


В студии №9 глюк не наблюдается.
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #9 : 12-11-2009 15:08 » new

попробовал дома - не глюкает.
Походу дела у меня разные шестые студии дома и на работе - не первый раз такое )) А ставить и действительно мог с разных дисков
Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines