ActiveX событие закрытия родительского окна

Создание, использование компонентов ActiveX
vpaull
Начинающий
Начинающий
 
Сообщения: 7
Зарегистрирован: 26.03.2013 (Вт) 20:23

ActiveX событие закрытия родительского окна

Сообщение vpaull » 26.03.2013 (Вт) 20:40

Написал ActiveX контрол на vb.net(VS2008 .net 2.0) для 1С-ины. Контрол базируется на UserControl. Все работает, всё хорошо, но во внутренних объектах контрола используются ссылки самой 1С-ины (они там определяются как COM Object). Проблема в следующем - если перед закрытием я вручную(вызовом функции вручную) прибиваю ссылки и собираю мусор - то при закрытии 1С-ка завершает процесс нормально. Я прописывал эту функцию в метод dispose, но он не отрабатывает(проверял отладчиком)! То есть - в Dispose прописана прочистка ссылок, закрываю 1С-ину - процесс остаётся висеть, Dispose не вызывался.
Me.Parent = nothing всегда

Как выход из положения вижу следующие варианты(если они и возможны - то я не знаю как):
1) Как-то определить событие закрытия родительского окна через какую-нибудь стандартную функцию элемента управления
2) Через winAPI получить HWND 1С-ного окна и получать по таймеру его состояние, при наступлении состояния "процесс есть, окна нет" вызывать dispose
3) Читать очередь сообщений windows(но тут вообще для меня пока темный лес)

Подскажите неучу, пожалуйста!

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 27.03.2013 (Ср) 11:08

А смотреть что приходит в WndProc твоего контрола не пробовал? Есть подоздение, что там должно быть что-то свидетельствующее о закрытии окна.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 27.03.2013 (Ср) 11:13

vpaull писал(а):Me.Parent = nothing всегда

Стоп. А как используется контрол - как контрол или нет? Если нет, то почему он UserControl?

vpaull
Начинающий
Начинающий
 
Сообщения: 7
Зарегистрирован: 26.03.2013 (Вт) 20:23

Re: ActiveX событие закрытия родительского окна

Сообщение vpaull » 27.03.2013 (Ср) 12:24

Контрол наследуется от UserControl и используется как ActiveX

Решил пока таким образом: Повесил таймер, который раз в секунду делает:
Код: Выделить всё
............
Private Declare Function IsWindowVisible Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long
.............

Private Sub TimerClosing_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerClosing.Tick
        Dim Sign As String = Microsoft.VisualBasic.Right(Hex(IsWindowVisible(GetParent(Me.Handle))), 1)
        If Sign = "0" Then
            TimerClosing.Enabled = False
            Очистить()
            Dispose()
        End If
End Sub



Работает!!!

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 27.03.2013 (Ср) 14:59

vpaull писал(а):
Код: Выделить всё
        Dim Sign As String = Microsoft.VisualBasic.Right(Hex(IsWindowVisible(GetParent(Me.Handle))), 1)
        If Sign = "0" Then

Ничего уродливее не придумал?

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 27.03.2013 (Ср) 15:02

vpaull писал(а):
Код: Выделить всё
Private Declare Function IsWindowVisible Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long

Да, это тоже неверно. Совсем неверно. И работоспособно только на x64.

vpaull
Начинающий
Начинающий
 
Сообщения: 7
Зарегистрирован: 26.03.2013 (Вт) 20:23

Re: ActiveX событие закрытия родительского окна

Сообщение vpaull » 27.03.2013 (Ср) 16:57

Qwertiy писал(а):
vpaull писал(а):
Код: Выделить всё
Private Declare Function IsWindowVisible Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long

Да, это тоже неверно. Совсем неверно. И работоспособно только на x64.


На x32 как раз и работает...

Qwertiy писал(а):
vpaull писал(а):
Код: Выделить всё
        Dim Sign As String = Microsoft.VisualBasic.Right(Hex(IsWindowVisible(GetParent(Me.Handle))), 1)
        If Sign = "0" Then

Ничего уродливее не придумал?

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

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 28.03.2013 (Чт) 11:59

vpaull писал(а):На x32 как раз и работает...

Не должно. Должно падать с повреждением целостности стека. Хотя.. Если там через регистры передаются параметры, то может и не падать.
Эти функции принимают 32-битный Integer, а не 64-битный Long. Возможно, надо вообще написать IntPtr.
Надо аккуратнее с копипастом объявлений из VB6 быть.

vpaull писал(а):А как можно по-красивее сделать?

То, что у тебя записано на самом деле пишется так:
Код: Выделить всё
If IsWindowVisible(GetParent(Me.Handle)) = 0 Then
но есть подозрения, что тут всё-таки должно быть просто
Код: Выделить всё
If GetParent(Me.Handle) = 0 Then

vpaull
Начинающий
Начинающий
 
Сообщения: 7
Зарегистрирован: 26.03.2013 (Вт) 20:23

Re: ActiveX событие закрытия родительского окна

Сообщение vpaull » 29.03.2013 (Пт) 7:35

Qwertiy писал(а):Есть подозрения, что тут всё-таки должно быть просто

Код: Выделить всё
If GetParent(Me.Handle) = 0 Then

Так не работает. GetParent вполне себе возвращает hWnd окна, но оно не видимо.

За ЛикБез спасибо(без иронии).

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 29.03.2013 (Пт) 7:44

Проверка на видимость вообще-то не является корректной для данной цели. Окно может быть невидимо по разным причинам. Даже если исходить из того, что 1С сам так не сделает. Например, менеджеры рабочих столов типа Dexpot управляют как раз видимостью окна.

Всё-таки, что не так с обработкой закрытия окна контрола?

vpaull
Начинающий
Начинающий
 
Сообщения: 7
Зарегистрирован: 26.03.2013 (Вт) 20:23

Re: ActiveX событие закрытия родительского окна

Сообщение vpaull » 29.03.2013 (Пт) 9:12

Qwertiy писал(а):Всё-таки, что не так с обработкой закрытия окна контрола?

Событие на Dispose не отрабатывет - поэтому не освобождаются COM ссылки на объекты 1С - поэтому окно скрывается, а процесс висит, вручную из 1С вызывать Dispose не всегда удобно в случаях, когда из 1С-ки выгоняет администратор базы(например для обновления) или если будет писать под этот контрол другой программист, который тупо забьет на выполнение функции Очистить() в событии ПередЗакрытием на форме, да и оно должно(исходя из логики) само прочищаться при уничтожении контрола.

vpaull
Начинающий
Начинающий
 
Сообщения: 7
Зарегистрирован: 26.03.2013 (Вт) 20:23

Re: ActiveX событие закрытия родительского окна

Сообщение vpaull » 29.03.2013 (Пт) 9:12

Qwertiy писал(а):Всё-таки, что не так с обработкой закрытия окна контрола?

Событие на Dispose не отрабатывет - поэтому не освобождаются COM ссылки на объекты 1С - поэтому окно скрывается, а процесс висит, вручную из 1С вызывать Dispose не всегда удобно в случаях, когда из 1С-ки выгоняет администратор базы(например для обновления) или если будет писать под этот контрол другой программист, который тупо забьет на выполнение функции Очистить() в событии ПередЗакрытием на форме, да и оно должно(исходя из логики) само прочищаться при уничтожении контрола.

vpaull
Начинающий
Начинающий
 
Сообщения: 7
Зарегистрирован: 26.03.2013 (Вт) 20:23

Re: ActiveX событие закрытия родительского окна

Сообщение vpaull » 29.03.2013 (Пт) 9:12

Qwertiy писал(а):Всё-таки, что не так с обработкой закрытия окна контрола?

Событие на Dispose не отрабатывет - поэтому не освобождаются COM ссылки на объекты 1С - поэтому окно скрывается, а процесс висит, вручную из 1С вызывать Dispose не всегда удобно в случаях, когда из 1С-ки выгоняет администратор базы(например для обновления) или если будет писать под этот контрол другой программист, который тупо забьет на выполнение функции Очистить() в событии ПередЗакрытием на форме, да и оно должно(исходя из логики) само прочищаться при уничтожении контрола.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 29.03.2013 (Пт) 11:06

vpaull писал(а):Событие на Dispose не отрабатывет

Я имел в виду определять некое событие в
Код: Выделить всё
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)

А ещё, скорее всего, можно использовать класс NativeWindow для работы с родительским окном отслеживания его закрытия.


Вернуться в Компоненты

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 23

    TopList