Переключение на Главную Страницу Страницы: [1]  ОтправитьПечать
Очень популярная тема (более 25 ответов) Создание элемента на форме (число прочтений - 23512 )
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Создание элемента на форме
03. Января 2008 :: 14:08
Печать  
Дошел до этапа создания собственного элемента на форме. Смотрю как сделано в 1С++ в ActiveX. Метод CAXCtrlContainer::CreateContainer:

Код
Выбрать все
	CWnd* pOldWnd = pDoc->GetFieldWnd(pGetField);
	CWnd* pParent = pOldWnd->GetParent();

	CRect rect;
	pOldWnd->GetWindowRect(rect);
	pParent->ScreenToClient(rect);
	int id = pOldWnd->GetDlgCtrlID();
	delete pOldWnd;

 


Смущает меня последняя строка: "delete pOldWnd;" Не происходит ли в результате выполнения такого кода двойное удаление памяти? Ведь указатель-то из 1С никуда не девается и при удалении формы 1С (если там не наделано ликов) должна сама вызвать delete. Сейчас сделал по другому: что-то вроде pOldWnd->DestroyWindow (). При этом добиваемся чего хотим:
- в диалоге появляется контрол с ИД как у старого.
- объект 1С не удаляется - при закрытии произойдет корректное удаление живого объекта.

Интересно, есть ли у такого решения подводные камни? Интересуют также комментарии авторов решения с delete.
  
Наверх
 
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #1 - 03. Января 2008 :: 15:10
Печать  
Ни одного тебя смущала такая конструкция.
  
Наверх
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #2 - 17. Января 2008 :: 10:23
Печать  
Кстати, замена delete на DestroyWindow дает еще одну небезынтересную фенечку. Свои элементы управления в этом случае можно создавать не только на надписи или кнопке, но и на других элементах управления. Создание элемента работает, в принципе, на всем, кроме ТЗ. А вот при использовании delete 1С вылетает уже на простом поле ввода.
  
Наверх
 
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #3 - 17. Января 2008 :: 10:38
Печать  
Может быть попробовать выложить сборку без delete для всестороннего тестирования?
  
Наверх
www  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #4 - 17. Января 2008 :: 10:41
Печать  
А чего пробовать?
ИМХО Ужас прав, нужно заменять delete в ночной сборке
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #5 - 17. Января 2008 :: 10:44
Печать  
Олег, а какие элементы хочешь помещать на форму?
Поделись планами Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #6 - 17. Января 2008 :: 10:44
Печать  
artbear писал(а) 17. Января 2008 :: 10:41:
А чего пробовать?
ИМХО Ужас прав, нужно заменять delete в ночной сборке

Кто у нас этим участком "заведует"?
  
Наверх
www  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #7 - 17. Января 2008 :: 10:47
Печать  
По идее автор Степан, но его что-то последнее время практически не видно и не слышно Печаль
Также в рефакторинге и правке ошибок участвовали Саша Орефков и я - трое нас было Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #8 - 17. Января 2008 :: 10:49
Печать  
artbear писал(а) 17. Января 2008 :: 10:44:
Олег, а какие элементы хочешь помещать на форму?
Поделись планами Улыбка

Да я уже все, что хотел - поместил Улыбка Это "ТабличныйДокумент.ЭлементУправления". Больше вроде нечего (пока). Это я так, работу над ошибками делаю, проверяю продукт на корректность. Чтобы быть насчет него совершенно спокойным.
  
Наверх
 
IP записан
 
Arta
1c++ power user
Отсутствует



Сообщений: 2537
Местоположение: Нижний Новгород
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #9 - 17. Января 2008 :: 11:25
Печать  
Олег, а может заодно, как бы между прочим Улыбка реализуешь это?
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #10 - 17. Января 2008 :: 11:34
Печать  
Arta писал(а) 17. Января 2008 :: 11:25:
Олег, а может заодно, как бы между прочим Улыбка реализуешь это?

Фигасе, "между прочим" Улыбка ХЗ. Можно попробовать покопать вот в этом направлении:

Цитата:
CWnd::FromHandle
Returns a pointer to a CWnd object when given a handle to a window. If a CWnd object is not attached to the handle, a temporary CWnd object is created and attached.

Вот если эта хреновина возвращает действительный CWnd, которому соответствует HWND (а не временную хрень какую-нибудь), то из этого CWnd уже можно сконструировать нормальный контекст.
  
Наверх
 
IP записан
 
Arta
1c++ power user
Отсутствует



Сообщений: 2537
Местоположение: Нижний Новгород
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #11 - 17. Января 2008 :: 11:47
Печать  
Благодарствую, мил человек Улыбка
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #12 - 17. Января 2008 :: 11:51
Печать  
spock писал(а) 17. Января 2008 :: 11:50:
Попробуй так (как вариант):
Код
Выбрать все
CWnd::Detach() 


А это здесь при чем? Проблема как раз обратная - из HWND получить правильный CWnd.
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #13 - 17. Января 2008 :: 16:35
Печать  
Arta писал(а) 17. Января 2008 :: 11:25:
Олег, а может заодно, как бы между прочим Улыбка реализуешь это?


Для хохмы реализовал нечто подобное для Йокселя. В объект "ТабличныйДокумент" добавлен метод "ПолучитьЭлементУправленияИзЭлементаФормы", который возвращает объект типа "ТабличныйДокумент.ЭлементУправления", если на заданном элементе управления создан элемент табличного документа. Если на заданном элементе нет табличного документа, то метод выкидывает ошибку.

Модифицированную ВК прикладываю. Следом пойдет тестовая обработка.

В тестовой обработке создается элемент управления с табличным документом. По кнопке "Кнопка" срабатывает процедура следующего вида:

Код
Выбрать все
Процедура Тест ()
	Т = СоздатьОбъект ("ТабличныйДокумент");
	Элемент = Т.ПолучитьЭлементУправленияИзЭлементаФормы (Форма, "ТабличныйДокумент");
	Сообщить (ТипЗначенияСтр (Элемент));
	Сообщить ("" + Элемент.Документ.ВысотаТаблицы ());

	Элемент = Т.ПолучитьЭлементУправленияИзЭлементаФормы (Форма, "ВыбФайл");
КонецПроцедуры
 



На последней строке будет выдано исключение, как и планировалось.
  

SpreadSheet_001.rar ( 803 KB | Загрузки )
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #14 - 17. Января 2008 :: 16:39
Печать  
Тестовая обработка.
  

Control.ert ( 8 KB | Загрузки )
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #15 - 17. Января 2008 :: 16:43
Печать  
Исходники этого дела находятся здесь: http://yoksel.cvs.sourceforge.net/yoksel/SpreadSheet/SheetController.cpp?revisio...

Все оказалось проще. GetFieldWnd объекта CGetDoc7 сразу возвращает нормальный CWnd * моего элемента управления.

Дальше все элементарно. Убеждаемся, что это CWnd именно моего элемента управления. Кастим CWnd * к указателю на мой элемент. Получаем из этого указателя смартпойнтер. На основе смартпойнтера автоматически создается контекстная обертка.

Насколько это реально/проще/сложнее для реализации в 1С++ не в курсе. Улыбка
  
Наверх
 
IP записан
 
Arta
1c++ power user
Отсутствует



Сообщений: 2537
Местоположение: Нижний Новгород
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #16 - 17. Января 2008 :: 16:45
Печать  
Артур боялся что останется ссылка на объект, в то время как он уже умер. Как следствие 1С склеит ласты.

Такое не предусматривал?
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #17 - 17. Января 2008 :: 16:48
Печать  
Arta писал(а) 17. Января 2008 :: 16:45:
Артур боялся что останется ссылка на объект, в то время как он уже умер. Как следствие 1С склеит ласты.

Такое не предусматривал?

Насколько я понимаю, в моем случае такое не произойдет. Если будет убит последний объект типа "ТабличныйДокумент.ЭлементУправления", то автоматом будет убито окно с элементом управления. В этом случае при запросе CWnd будет выдаваться NULL.
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #18 - 17. Января 2008 :: 16:53
Печать  
Хотя есть другая проблема. Если создать элемент управления не на основе кнопки или надписи, то при очистке переменной типа "ТабличныйДокумент.ЭлементУправления" 1С вылетит Улыбка Но если использовать кнопку или надпись, то все нормально. Вроде бы.
  
Наверх
 
IP записан
 
Arta
1c++ power user
Отсутствует



Сообщений: 2537
Местоположение: Нижний Новгород
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #19 - 17. Января 2008 :: 16:54
Печать  
Ты не понял.


1. Элемент = Т.ПолучитьЭлементУправленияИзЭлементаФормы (Форма, "ТабличныйДокумент");
2. Закрываем форму с Объектом, оставляя при этом ссылку на него в переменной
3. Обращаемся к свойству или методу переменной Элемент. Что я получу?

Проще попробовать Улыбка

  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #20 - 17. Января 2008 :: 16:55
Печать  
Arta писал(а) 17. Января 2008 :: 16:54:
Ты не понял.


1. Элемент = Т.ПолучитьЭлементУправленияИзЭлементаФормы (Форма, "ТабличныйДокумент");
2. Закрываем форму с Объектом, оставляя при этом ссылку на него в переменной
3. Обращаемся к свойству или методу переменной Элемент. Что я получу?

Проще попробовать Улыбка


Ничего плохого ты не получишь. Объект будет существовать до тех пор, пока на него есть хотя бы одна ссылка.
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #21 - 17. Января 2008 :: 16:56
Печать  
Хотяяя... Там могут быть операции с HWND, который уже дохлый. Надо будет попробовать, что будет.
  
Наверх
 
IP записан
 
Arta
1c++ power user
Отсутствует



Сообщений: 2537
Местоположение: Нижний Новгород
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #22 - 17. Января 2008 :: 16:56
Печать  
Хмм.
и при этом форма уже закрыта?

Ладно, я все равно профан, пошел тестить...
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #23 - 17. Января 2008 :: 17:00
Печать  
Arta писал(а) 17. Января 2008 :: 16:56:
Хмм.
и при этом форма уже закрыта?

Конечно! Объект при этом не обязательно должен быть убитым. Сейчас проверил так.

В глобальник запихнул переменную гТест.

Процедуру поменял так:
Код
Выбрать все
Процедура Тест ()
	Т = СоздатьОбъект ("ТабличныйДокумент");
	Элемент = Т.ПолучитьЭлементУправленияИзЭлементаФормы (Форма, "ТабличныйДокумент");
	Сообщить (ТипЗначенияСтр (Элемент));
	Сообщить ("" + Элемент.Документ.ВысотаТаблицы ());
	гТест = Элемент;

	Элемент = Т.ПолучитьЭлементУправленияИзЭлементаФормы (Форма, "ВыбФайл");
КонецПроцедуры
 


Т.е. элемент записывается в гТест.

Далее закрываю форму. И запускаю такой код:

Код
Выбрать все
Процедура Тест2 ()
	Сообщить (гТест.Документ.ВысотаТаблицы ());
	Т = СоздатьОбъект ("ТабличныйДокумент");
	гТест.Документ = Т;
КонецПроцедуры
 



Все работает так, как и ожидалось.
  
Наверх
 
IP записан
 
Arta
1c++ power user
Отсутствует



Сообщений: 2537
Местоположение: Нижний Новгород
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #24 - 17. Января 2008 :: 17:04
Печать  
Т.е. ответственность за ссылки остается за разработчиком?
Опа... То что надо!!!  Смех


Сейчас на рабочей базе проверю, и отпишусь!
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #25 - 17. Января 2008 :: 17:08
Печать  
Arta писал(а) 17. Января 2008 :: 17:04:
Т.е. ответственность за ссылки остается за разработчиком?

Ну да, как и везде в 1С Улыбка Типа, если создал ТЗ мегов эдак на 200 и запихнул в ГМ, то сам себе мохнатый Буратино.
  
Наверх
 
IP записан
 
Arta
1c++ power user
Отсутствует



Сообщений: 2537
Местоположение: Нижний Новгород
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #26 - 17. Января 2008 :: 17:09
Печать  
Черт, работает метод же только ТабличнымДокументом... А я сперва раскатил губу, что с любым объектом на форме Улыбка

Пошел дальше смотреть Улыбка
  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #27 - 18. Января 2008 :: 05:31
Печать  
Артем, плиз, добавь в баг багзиллы описалово на решение Олега.
Освобожусь, постараюсь разобраться и поправить Улыбка
ЗЫ возможно, kms поучаствует для ТП, побеседуй с ним Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #28 - 23. Января 2008 :: 14:18
Печать  
Кстати, из-за delete на элементах Йокселя нельзя создавать активиксы. Потому что ActiveX тупо вызовет delete для CWnd Йокселя. Соответственно, если на объект Йокселя где-то остались ссылки, то при их использовании будет ##па - т.к. объект уже будет удален. А если эти ссылки не использовать, то будет двойное удаление одной и той же памяти.

В общем, фигня этот delete. ИМХО, лучше всего использовать принцип - "не ты создал, не тебе удалять".
  
Наверх
 
IP записан
 
orefkov
1c++ developer
1c++ moderator
Отсутствует


I Love YaBB 2!

Сообщений: 896
Зарегистрирован: 20. Мая 2006
Re: Создание элемента на форме
Ответ #29 - 21. Февраля 2008 :: 09:12
Печать  
Вот как раз если не делать delete, а DestroyWindow, и будут утечки памяти.
Поясню.
DestroyWindow не делает ничего, кроме как вызова этой же апишной функции, которая разрушает окно, но НЕ УНИЧТОЖАЕТ объект CWnd.
А по поводу двойного удаления - в данном случае 1С НЕ ХРАНИТ указатели на CWnd контролов, а когда нужно, дергает GetDlgItem с нужным ID, и по полученному HWND делает CWnd::FromHandlePermanent, чтобы получить CWnd*. Это и позволяет создав окно с тем же идшником, подменить атрибут формы, и как показала практика, 1С при убитии формы, удаляет именно объект CWnd нового, нами созданного окошка.
  
Наверх
 
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Создание элемента на форме
Ответ #30 - 21. Февраля 2008 :: 18:27
Печать  
[b]orefkov[/b], [b]Uzhast[/b]

Знаете, а правда как всегда где-то посередине.

Я совершенно точно могу сказать про CBtnEdit, т.к. занимался последнюю неделю именно этой темой.
Это автоматический объект, с процедурой самоликвидации в CMaskEdit::PostNcDestroy.
[ecx+0x40] - это как раз флаг bAutoDestroy для этих объектов.

Так что освобождение объектов различных типов необходимо делать по-разному.
Для текста и кнопок, видимо, необходимо delete; для самоликвидирующихся объектов в иерархии CMaskEdit достаточно DestroyWindow().

P.S.

[b]orefkov[/b]

На самом деле, Саша, там не чистый FromHandlePermanent, a GetDescendantWindow(nID, FALSE), который может закончиться FromHandle и временным объектом.
Я какое-то время обдумывал, не в этом ли грабли, но оказалось что мои грабли - не в этом.

P.P.S.

Вот такая разгадка.
Пошел за еще одной банкой пива.
  

De quelle planète es-tu?
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #31 - 21. Февраля 2008 :: 19:01
Печать  
Цитата:
Вот как раз если не делать delete, а DestroyWindow, и будут утечки памяти.
Поясню.
DestroyWindow не делает ничего, кроме как вызова этой же апишной функции, которая разрушает окно, но НЕ УНИЧТОЖАЕТ объект CWnd.
А по поводу двойного удаления - в данном случае 1С НЕ ХРАНИТ указатели на CWnd контролов, а когда нужно, дергает GetDlgItem с нужным ID, и по полученному HWND делает CWnd::FromHandlePermanent, чтобы получить CWnd*. Это и позволяет создав окно с тем же идшником, подменить атрибут формы, и как показала практика, 1С при убитии формы, удаляет именно объект CWnd нового, нами созданного окошка.


Очень взвешенное и подробное высказывание. Сказал бы спасибо, но проблема в том, что это высказывание совершенно не соответствует действительности.

По пунктам.

Цитата:
в данном случае 1С НЕ ХРАНИТ указатели на CWnd контролов

1С не хранит указатели на CWnd ТОЛЬКО в том случае, когда 1С не создает нетривиальных объектов CWnd. Во всех других случаях 1С ДОЛЖНА хранить подобные указатели потому, что MFC НЕ КОНТРОЛИРУЕТ время жизни объектов CWnd в случае, когда эти объекты были созданы не самой библиотекой MFC. Это происходит хотя бы потому, что объект CWnd может создаваться как на стеке, так и в хипе. MFC не может самостоятельно определить КАК уничтожать конкретный объект, если не знает, как он был порожден. Я думаю, не нужно пояснять, что нетривиальные объекты CWnd в 1С есть.

Цитата:
а когда нужно, дергает GetDlgItem с нужным ID, и по полученному HWND делает CWnd::FromHandlePermanent, чтобы получить CWnd*

Опять неверно. 1С вызывает CWnd::GetDescendantWindow. Туда она передает ID нужного элемента и в качестве параметра bOnlyPerm передает FALSE (!). Параметр FALSE означает, что будет вызван метод CWnd::FromHandle, а не CWnd::FromHandlePermanent.

Вывод. Если использовать delete pObject, то двойное удаление памяти будет ОБЯЗАТЕЛЬНО. Потому что возможно наличие двух видов объектов CWnd:
- Созданных самой 1С. Второе удаление при этом произойдет при разрушении формы, когда 1С будет подчищать объекты за собой.
- Временные объекты, созданные MFC. В этом случае второе удаление произойдет при первом же виндовом сообщении WM_ENTERIDLE - в этом случае MFC удалит все временные объекты CWnd, которые она удерживает в карте временных объектов.

PS. Когда я задавал исходный вопрос, я ожидал, что мне либо ответит грамотный в этих вопросах человек, либо вообще никто не ответит. Но я не ожидал, что мне будут сливать откровенную дезинформацию...
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #32 - 21. Февраля 2008 :: 19:05
Печать  
Если же вызывать DestroyWindow, то утечек памяти не возникнет:
- Если объект CWnd - объект 1С, то он будет удален средствами 1С либо при разрушении формы, либо в процессе обработки сообщения WM_DESTROY (как раскопал kms).

- Если объект CWnd - временный объект MFC, то он будет удален в обработке ожидания, когда MFC будет подчищать временные объекты.
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #33 - 21. Февраля 2008 :: 19:22
Печать  
[quote author=kms link=1199369336/30#30 date=1203618459][/quote]

Получается, благодаря твоим раскопкам, мое высказывание насчет ХРАНЕНИЯ указателей на объекты CWnd становится НЕ СОВСЕМ верным ;) Но главное, что я хотел сказать сохраняется - СУЩЕСТВУЮТ объекты, ВРЕМЯ ЖИЗНИ, которых контролирует сама 1С.
  
Наверх
 
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Создание элемента на форме
Ответ #34 - 21. Февраля 2008 :: 19:54
Печать  
Э, кто тебе ластик дал? Ну-ка отдай! Подмигивание

Насчет delete (про суслика, которого не видно, но он есть): конечно, 1С сам управляет временем жизни контолов.
Просто в моей задаче, если ты помнишь, мне приходится добавлять и удалять атрибуты на форму.
При этом я выполняю всю работу сам, и если я не сделаю delete там, где требуется delete, шансы, что это сделает кто-то еще равны нулю.

По остальному: в #31 ты еще примерно на середине пути. Подмигивание
Если будет интересно, я тебе могу без эмоций нарисовать, что там по-правде происходит.
  

De quelle planète es-tu?
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #35 - 21. Февраля 2008 :: 19:59
Печать  
kms писал(а) 21. Февраля 2008 :: 19:54:
Э, кто тебе ластик дал? Ну-ка отдай! Подмигивание




kms писал(а) 21. Февраля 2008 :: 19:54:
Насчет delete (про суслика, которого не видно, но он есть): конечно, 1С сам управляет временем жизни контолов.
Просто в моей задаче, если ты помнишь, мне приходится добавлять и удалять атрибуты на форму.
При этом я выполняю всю работу сам, и если я не сделаю delete там, где требуется delete, шансы, что это сделает кто-то еще равны нулю.

По остальному: в #31 ты еще примерно на середине пути. Подмигивание
Если будет интересно, я тебе могу без эмоций нарисовать, что там по-правде происходит.

Где эмоции?! Какие эмоции?! Не вижу никаких эмоций! Улыбка
Интересно, рассказывай.
  
Наверх
 
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Создание элемента на форме
Ответ #36 - 21. Февраля 2008 :: 20:34
Печать  
Ну, схема комбинируется из описаний, данных разными авторами в предыдущих постах Улыбка

Короче, 1С действительно не хранит ссылок на CWnd.
Но тем не менее у нее есть массив CGetField*, а заодно и массив CGetCtrl*.
Впрочем, не суть, достаточно того, что она знает CtrlID этих окон.
При разрушении формы она проходит по списку CtrlID и как раз методом GetDescendantWindow/FromHandle получает CWnd*.
FromHandle может, конечно, возвращать CTempWnd, но как правило не возвращает, ибо существуют перманентные объекты, а у них приоритет.
Ну, дальше уничтожение объектов - дело техники.

В итоге получается такая картина:
Если delete текст или кнопку, а на ее месте создать другое окно - проблем не будет, ибо при разрушении формы FromHandle вернет указатель на другое окно и удалит его.
Если delete CBtnEdit (у которого bAutoDestroy == TRUE) - мы очень красиво разрушаем кучу, как раз методом двойного удаления объекта.
Если DestroyWindow текст или кнопку, то сам объект CWnd остается с нулевым хендлом, FromHandle его не найдет никогда - это memory leak.
Если DestroyWindow CBtnEdit - это одновременно и уничтожение CWnd - все ок.

Здесь есть вопрос, который я сам могу задать, себе же в основном.
Каким образом, при проходе по списку CtrlID, 1С определяет метод, которым надо уничтожать объекты?
Ну, потом разберемся, наверное, для полноты картины.
  

De quelle planète es-tu?
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #37 - 21. Февраля 2008 :: 21:05
Печать  
kms писал(а) 21. Февраля 2008 :: 20:34:
Ну, схема комбинируется из описаний, данных разными авторами в предыдущих постах Улыбка

ИМХО, не совсем правильно она у тебя комбинируется Улыбка

kms писал(а) 21. Февраля 2008 :: 20:34:
Короче, 1С действительно не хранит ссылок на CWnd.

Зуб даешь?

kms писал(а) 21. Февраля 2008 :: 20:34:
Но тем не менее у нее есть массив CGetField*, а заодно и массив CGetCtrl*.
Впрочем, не суть, достаточно того, что она знает CtrlID этих окон.
При разрушении формы она проходит по списку CtrlID и как раз методом GetDescendantWindow/FromHandle получает CWnd*.

Это предположение или факт? Можешь сказать конкретную dll и адрес кода, который делает вышеописанное? Есть сомнения по этому поводу.

kms писал(а) 21. Февраля 2008 :: 20:34:
FromHandle может, конечно, возвращать CTempWnd, но как правило не возвращает, ибо существуют перманентные объекты, а у них приоритет.
Ну, дальше уничтожение объектов - дело техники.

Не очевидно.

kms писал(а) 21. Февраля 2008 :: 20:34:
В итоге получается такая картина:
Если delete текст или кнопку, а на ее месте создать другое окно - проблем не будет, ибо при разрушении формы FromHandle вернет указатель на другое окно и удалит его.

Не подтверждается. Перечитай эту тему внимательней. Мой объект CWnd 1С не удаляет. В частности, указатель на него можно удерживать в глобальном модуле - и спокойно обращаться к методам моего объекта. Удаление объекта происходит именно тогда, когда Я этого хочу.

kms писал(а) 21. Февраля 2008 :: 20:34:
Если delete CBtnEdit (у которого bAutoDestroy == TRUE) - мы очень красиво разрушаем кучу, как раз методом двойного удаления объекта.

Есть мнение, что все нетривиальные CWnd 1С используют механизм автоудаления. Ибо зачем плодить сущности сверх необходимого? Пусть самоудаляются после WM_DESTROY и все. Тогда циклы по CWnd * в деструкторе не нужны вообще.

kms писал(а) 21. Февраля 2008 :: 20:34:
Если DestroyWindow текст или кнопку, то сам объект CWnd остается с нулевым хендлом, FromHandle его не найдет никогда - это memory leak.

Если это временный объект, то он удалится MFC автоматически. Если это объект 1С, то зависит от объекта. Мне кажется, что в случае кнопок и надписей будут использоваться временные объекты MFC. Ибо для 1С не ни малейшего смысла создавать собственные объекты - логика надписи и кнопки тривиальна, тут нет необходимости навешивать дополнительный функционал. В этом случае при вызове delete мы уничтожим временный объект MFC, который потом повторно удалиться - со всеми вытекающими.

kms писал(а) 21. Февраля 2008 :: 20:34:
Если DestroyWindow CBtnEdit - это одновременно и уничтожение CWnd - все ок.

Здесь есть вопрос, который я сам могу задать, себе же в основном.
Каким образом, при проходе по списку CtrlID, 1С определяет метод, которым надо уничтожать объекты?
Ну, потом разберемся, наверное, для полноты картины.

Считаю, (пока не доказано обратное), что:
- либо указатели на некоторые объекты 1С все же хранит
- либо нетривиальные объекты 1С самоуничтожаются
- либо комбинация двух вышеуказанных методов.

В любом случае DestroyWindow - наиболее корректный способ удаления окна. В лучшем случае все будет работать ПОЛНОСТЬЮ корректно. В худшем случае возможен лик (в чем я сомневаюсь), но лучше сделать лик, чем разрушить кучу.
  
Наверх
 
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Создание элемента на форме
Ответ #38 - 21. Февраля 2008 :: 22:05
Печать  
Uzhast писал(а) 21. Февраля 2008 :: 21:05:
ИМХО, не совсем правильно она у тебя комбинируется Улыбка

Оу, определенно, ты делаешь успехи по части дипломатии. Подмигивание

Цитата:
kms писал(а) 21. Февраля 2008 :: 20:34:
Короче, 1С действительно не хранит ссылок на CWnd.

Зуб даешь?

Фиг че. Но ссылок не хранит.

Цитата:
Это предположение или факт? Можешь сказать конкретную dll и адрес кода, который делает вышеописанное? Есть сомнения по этому поводу.

Блин, ну ты дотошный. Это хорошо.
Я тебе сказку рассказал, а ты вот в сказки не веришь.
Короче, нет там такого, это я так ненужные контролы прибивал, да так и осталось в голове Улыбка

Цитата:
Есть мнение, что все нетривиальные CWnd 1С используют механизм автоудаления. Ибо зачем плодить сущности сверх необходимого? Пусть самоудаляются после WM_DESTROY и все. Тогда циклы по CWnd * в деструкторе не нужны вообще.

Точно, так и есть на самом деле.

Цитата:
Если это временный объект, то он удалится MFC автоматически.

Про временные можешь забыть, не видел ни одного.

Цитата:
Мне кажется, что в случае кнопок и надписей будут использоваться временные объекты MFC. Ибо для 1С не ни малейшего смысла создавать собственные объекты - логика надписи и кнопки тривиальна, тут нет необходимости навешивать дополнительный функционал. В этом случае при вызове delete мы уничтожим временный объект MFC, который потом повторно удалиться - со всеми вытекающими.

Не, логика есть, но не подтверждается.

Итак, резюмируя:
Цитата:
Считаю, (пока не доказано обратное), что:
- либо указатели на некоторые объекты 1С все же хранит

НЕТ для статика, кнопки, CBtnEdit

Цитата:
- либо нетривиальные объекты 1С самоуничтожаются

ДА

Цитата:
- либо комбинация двух вышеуказанных методов.

ХЗ, пока не встречалось

Цитата:
В любом случае DestroyWindow - наиболее корректный способ удаления окна. В лучшем случае все будет работать ПОЛНОСТЬЮ корректно. В худшем случае возможен лик (в чем я сомневаюсь), но лучше сделать лик, чем разрушить кучу.

Б"""", если ты такой умный, че ты это в первом посте ВСЮ механику не рассказал? Смех
  

De quelle planète es-tu?
Наверх
 
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Создание элемента на форме
Ответ #39 - 21. Февраля 2008 :: 22:10
Печать  
Uzhast

А терь вопрос знатокам:
Почему для CBtnEdit* delete разрушает HEAP, а для CDrawStatic / CPictureButton7 - нет?

Помучайся немного. Очень довольный
  

De quelle planète es-tu?
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #40 - 21. Февраля 2008 :: 22:17
Печать  
kms писал(а) 21. Февраля 2008 :: 22:05:
Оу, определенно, ты делаешь успехи по части дипломатии. Подмигивание

Стараюсь...

kms писал(а) 21. Февраля 2008 :: 22:05:
Фиг че. Но ссылок не хранит.

Какие гарантии? Улыбка Думаешь, зря я про зуб антиресуюсь? Подмигивание

kms писал(а) 21. Февраля 2008 :: 22:05:
Блин, ну ты дотошный. Это хорошо.
Я тебе сказку рассказал, а ты вот в сказки не веришь.
Короче, нет там такого, это я так ненужные контролы прибивал, да так и осталось в голове Улыбка

Ага, говорил же, что схема сомнительная Улыбка
Но ведь тогда получается, что АБСОЛЮТНО все контролы 1С должны самоудаляться по DestroyWindow? Ведь если цикла удаления нет, объекты временными не являются, то другого варианта нет? Тем более в свете этих твоих слов:

kms писал(а) 21. Февраля 2008 :: 22:05:
Цитата:
Есть мнение, что все нетривиальные CWnd 1С используют механизм автоудаления. Ибо зачем плодить сущности сверх необходимого? Пусть самоудаляются после WM_DESTROY и все. Тогда циклы по CWnd * в деструкторе не нужны вообще.

Точно, так и есть на самом деле.


kms писал(а) 21. Февраля 2008 :: 22:05:
Про временные можешь забыть, не видел ни одного.

А, может, они прячутся?  Смех

kms писал(а) 21. Февраля 2008 :: 22:05:
Цитата:
Мне кажется, что в случае кнопок и надписей будут использоваться временные объекты MFC. Ибо для 1С не ни малейшего смысла создавать собственные объекты - логика надписи и кнопки тривиальна, тут нет необходимости навешивать дополнительный функционал. В этом случае при вызове delete мы уничтожим временный объект MFC, который потом повторно удалиться - со всеми вытекающими.

Не, логика есть, но не подтверждается.

Понятно. Т.е. надписи и кнопки - объекты нетривиальные?

kms писал(а) 21. Февраля 2008 :: 22:05:
Цитата:
- либо нетривиальные объекты 1С самоуничтожаются

ДА

Так что, получается догадка насчет правильности DestroyWindow ты подтверждаешь?

kms писал(а) 21. Февраля 2008 :: 22:05:
Цитата:
В любом случае DestroyWindow - наиболее корректный способ удаления окна. В лучшем случае все будет работать ПОЛНОСТЬЮ корректно. В худшем случае возможен лик (в чем я сомневаюсь), но лучше сделать лик, чем разрушить кучу.

Б"""", если ты такой умный, че ты это в первом посте ВСЮ механику не рассказал? Смех

Б"""", а если ТЫ такой умный, че ты мне весь расклад еще после первого поста не рассказал?  Смех
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #41 - 21. Февраля 2008 :: 22:22
Печать  
kms писал(а) 21. Февраля 2008 :: 22:10:
Uzhast

А терь вопрос знатокам:
Почему для CBtnEdit* delete разрушает HEAP, а для CDrawStatic / CPictureButton7 - нет?

Помучайся немного. Очень довольный

Думаешь, стоит? Улыбка DestroyWindow и вся недолга Улыбка

PS. Они что, в деструкторе ищут себя в таблице хендлов? И если не находят, не удаляются? Хотя, конечно, надо смотреть код... Улыбка
  
Наверх
 
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Создание элемента на форме
Ответ #42 - 21. Февраля 2008 :: 23:00
Печать  
Да, текст и кнопка - нетривиальные.
И DestroyWindow() - самый корректный и безопасный вариант, никаких побочных эффектов типа ликов нет.

Гарантии - это вообще-то в отделе рекламаций, но навскидку есть основания полагать, что приличные гарантии, что общая схема именно такая.
Нетривиальные, самоликвидирующиеся в PostNcDestroy контролы, не требующие явного уничтожения в каком-либо цикле при закрытии формы.
Ну, можем посмотреть на остальные типы, когда время будет.

Uzhast писал(а) 21. Февраля 2008 :: 22:17:
Б"""", а если ТЫ такой умный, че ты мне весь расклад еще после первого поста не рассказал?  Смех

Дык тогда было бы не так весело. Смех
И... должен признаться, DestroyWindow у меня используется с самого начала, но грамотную и достаточную теоретическую базу совместными усилиями подогнали только сейчас.  Улыбка

P.S.
Еще утром му""хался с этой темой.

В PurifyPlus знаешь как забавно выглядит "delete pWnd" для CBtnEdit*?
- error: read/write freed memory
- free location: delete pWnd
- error location: delete pWnd

Язык
  

De quelle planète es-tu?
Наверх
 
IP записан
 
Kemet
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 46
Зарегистрирован: 03. Октября 2007
Re: Создание элемента на форме
Ответ #43 - 22. Февраля 2008 :: 03:15
Печать  
kms писал(а) 21. Февраля 2008 :: 23:00:
В PurifyPlus

А хде это чудо можно ...э... типа посмотреть? )
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #44 - 22. Февраля 2008 :: 04:46
Печать  
Kemet писал(а) 22. Февраля 2008 :: 03:15:
kms писал(а) 21. Февраля 2008 :: 23:00:
В PurifyPlus

А хде это чудо можно ...э... типа посмотреть? )

http://www-306.ibm.com/software/awdtools/purifyplus/
  
Наверх
 
IP записан
 
Arta
1c++ power user
Отсутствует



Сообщений: 2537
Местоположение: Нижний Новгород
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Создание элемента на форме
Ответ #45 - 05. Августа 2008 :: 18:45
Печать  
kms писал(а) 21. Февраля 2008 :: 23:00:
И... должен признаться, DestroyWindow у меня используется с самого начала, но грамотную и достаточную теоретическую базу совместными усилиями подогнали только сейчас.  Улыбка


Миш, так точку поставили в этом вопросе или нет?
В активиксе сейчас delete, ты пользуешь при удалении контрола DestoyWindow.
Вопрос о спонтанной нестабильности работы контролов и утечек для меня так и не снят Печаль

vip тоже ногами топает
Ужасть так и остался при своем мнении
  
Наверх
 
IP записан
 
vip
1c++ power user
Отсутствует



Сообщений: 1570
Зарегистрирован: 19. Мая 2006
Re: Создание элемента на форме
Ответ #46 - 05. Августа 2008 :: 19:01
Печать  
Цитата:
vip тоже ногами топает

Да не топаю я. Много непонятного в этом вопросе.
Пока выяснил только, что величина утечек зависит от самого контрола.
И DestroyWindow с хэндлом созданного контрола эффекта не дает.
И очень похоже, что АктивИкс Степана ни в чем не виноват.
И замечал утечки и без Активикса.
И закономерность никак не пойму. Пока не пойму. Улыбка
  
Наверх
ICQ  
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Создание элемента на форме
Ответ #47 - 05. Августа 2008 :: 21:56
Печать  
Значит смотрите, какой на сегодня расклад.

1. По утечкам USER - я, честно, не в курсе.
Последним шоком для меня было то, что мы раскопали с trad'ом - а именно - потеря USER для множества простых форм 1С.
Мной было обнаружено, что если поместить на форму обычную ТЗ, это помогает избавиться от потерь.
Может быть, какая-то информация еще есть у Димы.
Я с тех пор этой темой не занимался.

2. По разрушению контролов.
По-моему, из этой ветки все вполне ясно.
Проблему можно решать как на стороне 1cpp, так и на стороне других клиентских приложений.
Это вопрос дизайна, не более.
  

De quelle planète es-tu?
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 
ОтправитьПечать