Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2003.04.14;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.007 c
1-44124
shoo
2003-04-02 16:40
2003.04.14
Выполнение кода после появления формы


7-44467
Serghei
2003-02-18 16:17
2003.04.14
Двунаправленная построчная печать!!!!


3-43990
denary
2003-03-18 01:41
2003.04.14
анализировать код нажатой клавиши


4-44518
Xi2
2003-02-12 20:02
2003.04.14
---|Ветка была без названия|---


1-44096
caesar
2003-04-02 16:58
2003.04.14
stack overflow





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский