Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.04.14;
Скачать: CL | DM;

Вниз

Странные события в деструкторе...   Найти похожие ветки 

 
Ihor Osov'yak ©   (2003-03-30 14:48) [0]

Я в общем-то сомневался, куда постить это сообщение: или в основную, или в апи - решил в "потрепаться".

Железная логика, так сказать...

А теперь о проблеме...

Сейчас делаю custom bar для IE, в общем то не столь важно что для IE, я думаю проблема не в ней. Для тех,

кто на знаком с этой технологией - а это очень вероятно - ибо тема специфическая - в двух словах о сем деле.

Это есть инпроц сервер, который среди прочего должен поддерживать IDeskBand. В одном из двух методов
этого интерфейса можно создавать свое окошко. В его качестве можно использовать обычную делфийскую форму, но

саздавать ее нужно хитро - через CreateParented, в качестве parent окошка дается тот хендл, что сообщает IE.

Так вот, в чем траблы. Иногда в деструкторе этой делфийской формы происходит исключение. Причем тогда,

когда эта форма в процессе есть последней (это происходит при закрытии IE). Деструктор вызывается только

раз. То есть всякие варианты с повторным вызовом деструктора исключены.

Да - все исследование делается с помощью записи в лог-файл, иешка запускается самостоятельно, то есть

"искажения отладчиком" также исключены.

После долгих занятий этим самым, удалось определить, что в случае возникновения исключений происходит

повторный вызов деструкторов компонентов, лежащих на этой форме. Это удалось обнаружить, перекрыв

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

фреймом, такого не происходит. Еще. Вызов деструкторов компонентов, лещащих в фрейме - не происходит:

Вот выдержка из лога:


14:40:58 PID=0005C0 TIEBand: start CloseDW, ID=2threadID=000004D4
14:40:58 PID=0005C0 TIEBand: VisualForm assigned...
14:40:58 PID=0005C0 TFormIEBand.BeforeDestruction start
14:40:58 PID=0005C0 TIEBand: ReestrDestroyVisualForm, ID=2 threadID=000004D4
14:40:58 PID=0005C0 TFormIEBand.BeforeDestruction done
14:40:58 PID=0005C0 TFormIEBand.Destroy entering Это старт деструктора формы
14:40:58 PID=0005C0 TMyButton.BeforeDestruction <==============
14:40:58 PID=0005C0 TMyButton.Destroy <============== Деструктор компоненті, лежащей вне фрейма
14:40:58 PID=0005C0 TFrame1.Destroy
14:40:58 PID=0005C0 TFrame1.Destroy Повторный вызов деструктора фрейма
14:40:58 PID=0005C0 TFormIEBand: Except in destructor ************ !!!!!!!!
14:40:59 PID=0005C0 TFormIEBand.Destroy leaving
14:40:59 PID=0005C0 TIEBand: CloseDW done.., ID=2




У кого какие идеи будут для обьяснения этих странных событий в деструкторе?


 
Polevi ©   (2003-03-30 16:10) [1]

где код деструктора


 
Ihor Osov'yak ©   (2003-03-30 16:42) [2]

Сорри, первым делом текст ексепшена:


15:55:16 PID=000578 TFormIEBand: Except in destructor ***: Invalid pointer operation

Собственно деструктор:


destructor TVisualForm.Destroy;
{$IFDEF OnDebug}
var s:string;
{$ENDIF}

begin
{$IFDEF OnDebug}
WrTmLog(2,ClassName+".Destroy entering");
{$ENDIF}
try
inherited;
except
{$IFDEF OnDebug}
on E:Exception do begin
s:=E.Message;

WrTmLog(2,ClassName+": Except in destructor ***: "+s );
MessageBox(0,pchar(s),"!!!!",MB_OK+MB_ICONERROR);
end;
{$ENDIF}

end;
{$IFDEF OnDebug}
WrTmLog(2,ClassName+".Destroy leaving");
{$ENDIF}

end;



Реально я работаю с наследниками от TVisualForm, деструктор там не перекрывается.

Деструктор контрольного компонента:

destructor TMyButton.Destroy;
begin
{$IFDEF OnDebug}
WrTmLog(2,"TMyButton.Destroy <==============" );
{$ENDIF}

inherited;
end;




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


function TBaseIEStrip.CloseDW(dwReserved: DWORD): HResult;
//var h:hwnd;
begin

{$IFDEF OnDebug}
WrLog(2,"");
WrTmLog(2,self.ClassName+": start CloseDW, ID="+IntToStr(ID)+
"threadID="+IntToHex(GetCurrentThreadId,8));
{$ENDIF}


//if BandForm <> nil then BandForm.Destroy;

{$IFDEF OnDebug}
if f_VisualForm <> nil then WrTmLog(2,self.ClassName +": VisualForm assigned...");
{$ENDIF}

InputInCriticalPhase;
if assigned(f_VisualForm) then begin
try
f_VisualForm.Hide;
SetParent(f_VisualForm.Handle,0);

f_VisualForm.Free;
//h:=f_VisualForm.Handle;
f_VisualForm := nil;
//SendMessage(h,WM_Close,0,0);

finally
LeaveCriticalPhase;
end;
end;

Result := S_OK;

{$IFDEF OnDebug}
WrTmLog(2,self.ClassName+": CloseDW done.., ID="+IntToStr(ID));
WrLog(2,"");
{$ENDIF}


end;



Да, еще:

procedure TVisualForm.BeforeDestruction;
begin
{$IFDEF OnDebug}
WrTmLog(2,ClassName+".BeforeDestruction start");
{$ENDIF}

if assigned(fIEStrip) then fIEStrip.ReestrDestroyVisualForm;
inherited;

{$IFDEF OnDebug}
WrTmLog(2,ClassName+".BeforeDestruction done");
{$ENDIF}


end;




procedure TBaseIEStrip.ReestrDestroyVisualForm;
begin
{$IFDEF OnDebug}
WrTmLog(2,self.ClassName+": ReestrDestroyVisualForm, ID="+IntToStr(ID)+" "
+"threadID="+IntToHex(GetCurrentThreadId,8));
{$ENDIF}

InputInCriticalPhase;
f_VisualForm := nil;
LeaveCriticalPhase;
end;


InputInCriticalPhase -> EnterCriticalSection,
LeaveCriticalPhase -> LeaveCriticalSection - это тоже из-за "трасти надо", оно здесь лишнее..


WrTmLog написаны с учетом многопоточной работы..


 
Ihor Osov'yak ©   (2003-03-30 16:50) [3]

Да, в TBaseIEStrip.CloseDW есть маленькая логическая ошибка - это когда f_VisualForm = nil.

Недосмотрел - тогда LeaveCriticalPhasе не вызовется. Но это не важно - я на єту траблу еще не нарывался... Но все равно исправлю..



Страницы: 1 вся ветка

Текущий архив: 2003.04.14;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.017 c
14-44419
Marser
2003-03-25 20:31
2003.04.14
Откуда есть пошли ники земли Русской :-)


7-44471
Borys
2003-02-18 13:23
2003.04.14
Управление службами (сервисами)


1-44248
Num Lock
2003-04-02 10:57
2003.04.14
Оптимизатор убирает нужную строчку?


8-44277
Ibrik
2003-01-11 14:46
2003.04.14
midi


3-44004
sergun
2003-03-25 10:10
2003.04.14
Как получить все значения определенной колонки в таблице