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

Вниз

Создание Child окно в MDI приложении   Найти похожие ветки 

 
Piter ©   (2004-06-22 14:40) [0]

Вот в DMClient"е встретил такую организацию создания Child форм:

LockWindowUpdate(Handle);
 try
   Result := TDMCChildForm.Create(Self);
 finally
   LockWindowUpdate(0);
 end;


вопрос - нафига вызывать LockWindowUpdate?


 
Игорь Шевченко ©   (2004-06-22 14:57) [1]


> нафига вызывать LockWindowUpdate?


Типа круто ?

Или сделать незаметным процесс распахивания MDIChild-окна.


 
Piter ©   (2004-06-22 19:45) [2]

Понятно.... просто тут такая ситуация...

Я уже писал о проблеме в моей программе. Это MDI приложение и при создании Child форм в качестве владельца указывается MainForm.
Программа глючила, периодически вылетало AV.

В fido7.ru.delphi посоветовал один человек в качестве владельца указывать не MainForm, а Application. Мол у него в серьезном проекте тоже такое было - при MainForm глючило, при Application нет. В тестовых примерах такое не проявляется типа...
была маленькая дисскусия по этому поводу (типа "А какая нафиг разница?"). Но я переделал программа, поставив владельцем Application - и глюки и вправду исчезли... мистика какая-то.

После чего я полез в исходники DMClient"а посмотреть как там с этим дела обстоят. Как видно, в качестве владельца тоже указывается MainForm и судя по всему приложение не глючит. Я и подумал - может оно не глючит в связи с этим LockWindowUpdate? Хотя вряд ли...
С другой стороны Nikkie писал, что иногда в его клиенте проскакивает AV, правда очень редко. Может, это опять же из-за этого?

В общем, занимаюсь тут ритуальными поясками с бубном...


 
Игорь Шевченко ©   (2004-06-22 21:52) [3]


> Это MDI приложение и при создании Child форм в качестве
> владельца указывается MainForm.
> Программа глючила, периодически вылетало AV.


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

Я, правда, не совсем вижу принципиальную разницу, кого указывать именно в качестве владельца.


 
Piter ©   (2004-06-22 21:58) [4]

Игорь Шевченко (22.06.04 21:52) [3]
Если бы ты нашел точный момент, когда происходит AV, или привел бы кусок кода, в котором гарантировано происходит эта ситуация


я сам был бы рад.. увы, это AV вылетает в непредсказуемые моменты :(

Игорь Шевченко (22.06.04 21:52) [3]
Я, правда, не совсем вижу принципиальную разницу, кого указывать именно в качестве владельца


и я не вижу. И с fido7.ru.delphi не видят. однако же...

надо попробовать написать тестовую программу... сейчас займусь...


 
nikkie.   (2004-06-22 22:00) [5]

>Или сделать незаметным процесс распахивания MDIChild-окна.
именно

>В fido7.ru.delphi посоветовал один человек в качестве владельца указывать не MainForm, а Application
имхо, пляски с бубном

Я и подумал - может оно не глючит в связи с этим LockWindowUpdate?
нет, не зависит

С другой стороны Nikkie писал, что иногда в его клиенте проскакивает AV, правда очень редко.
это было не из-за этого. давно исправлено.


 
Piter ©   (2004-06-22 22:08) [6]

nikkie.   (22.06.04 22:00) [5]
имхо, пляски с бубном


Имхо, тоже. Однако, глюки прекратились! Вопрос - почему...

P.S. Ничего кроме этого не правил...


 
Piter ©   (2004-06-22 22:09) [7]

nikkie.   (22.06.04 22:00) [5]

с другой стороны у тебя MainForm указана и все нормально...
У тебя не наблюдается AV никогда?


 
Игорь Шевченко ©   (2004-06-22 22:29) [8]


> >Или сделать незаметным процесс распахивания MDIChild-окна.
> именно


Угадал :) Но время на его распахивание все равно требуется, не так ли ?


 
nikkie ©   (2004-06-22 23:02) [9]

>Однако, глюки прекратились! Вопрос - почему...
где-то в другом месте ты накрутил.

>У тебя не наблюдается AV никогда?
никогда не говори никогда :)
не наблюдается.

>Но время на его распахивание все равно требуется, не так ли ?
да. но все же приятнее...


 
Игорь Шевченко ©   (2004-06-22 23:33) [10]


> да. но все же приятнее...


Это уже на вкус и цвет - лично мне не мешает процесс максимизации MDI-Child окна, может, потому что я слишком редко его наблюдаю ? :))


 
Piter ©   (2004-06-23 00:42) [11]

nikkie (22.06.04 23:02) [9]
где-то в другом месте ты накрутил


ну ладно. Думай как хочешь - но я тебе говорю - нет. Я недели две, три вообще не правил клиента... после совета из ФИДО - исправил две строчки. После этого глюки прекратились... я же знаю, что я правил и когда.


 
nikkie ©   (2004-06-23 00:51) [12]

ты бы чем языком трепать написал бы тестовую программку и убедился что ни тот, ни другой вариант к AV не приводит. значит, ошибка вызвана другим кодом. в твоих словах я не сомневаюсь. я просто знаю, что можно написать такой код, который будет выдавать AV, но этот AV будет исчезать при компиляции дебаг вместо релиз-версии, при добавлении-удалении пары строчек кода, замене MainForm на Application, наконец.


 
Piter ©   (2004-06-23 01:13) [13]

nikkie (23.06.04 00:51) [12]
я просто знаю, что можно написать такой код, который будет выдавать AV, но этот AV будет исчезать при компиляции дебаг вместо релиз-версии, при добавлении-удалении пары строчек кода, замене MainForm на Application, наконец


хорошо... ты же понимаешь, что я не писал специально чего-нибудь эдакого, чтобы глючило с MainForm... какой же код нужно написать, чтобы было так? Чтобы с MainForm глючило, а с Application нет?


 
Piter ©   (2004-06-23 01:18) [14]

Хотя я вас обманул. Мне предложили два усовершенствования, первое я уже сказал. А второе - это создавать не через конструктор форму, а через Application.CreateForm. Вот. Только эти два изменения я и сделал. Больше ничего.


 
nikkie ©   (2004-06-23 01:22) [15]

>ты же понимаешь, что я не писал специально чего-нибудь эдакого...
>какой же код нужно написать, чтобы было так?
специально такое не напишешь :))


 
Piter ©   (2004-06-23 01:42) [16]

блин... чего то меня самого немного глючит... в общем, добился сейчас постоянного повторения глюка - буду копать...


 
Piter ©   (2004-06-23 02:56) [17]

Nikkie, в общем, ошибка в EmbeddedNS, в процедуре TEmbeddedNSHandler.DoExecute
Вызов GetData приводит к мгновенной ошибке... причем, если в "нормальном" исполнении вызов GetData приводит к вызову унаследованного TMyHandler.GetData [TMyHandler = class(TEmbeddedNSHandler)], то здесь сразу ошибка... как будто нету никакого наследованного обработчика...

Вот что в дебаггере:

при нормальной работе:

EmbeddedNS.pas.407: GetData
mov eax, [ebp-$04]

mov edx, [eax]

call dword ptr [edx+$08]

......

MyHand.pas.27: begin
push ebx

mov ebx, eax

MyHand.pas.28: BeginReportData(CFSTR_MIME_HTML, "html");
mov ecx, $004dc480

и так далее...


При "ненормальной работе"

EmbeddedNS.pas.407: GetData
mov eax, [ebp-$04]

mov edx, [eax]

call dword ptr [edx+$08]

......

переходит к комманде по адресу 000000BC...


А там никакой комманды и нету - одни знаки вопроса. После чего, естественно
"Project mforum.exe raiser exception class EAccessViolation with message "Access violation at address 000000BC". Read of address 000000BC. Process stopped...."


 
Piter ©   (2004-06-23 11:20) [18]

nikkie?


 
nikkie ©   (2004-06-23 11:25) [19]

EmbeddedNS версии 1.01?
будет твой код - можно о чем-то говорить... а пока что могу только сказать, что у тебя ошибка.


 
Piter ©   (2004-06-23 11:54) [20]

nikkie (23.06.04 11:25) [19]
EmbeddedNS версии 1.01?


не знаю:
(******************************************************************************)
(*  EmbeddedNS.pas                                                            *)
(*    Implementation of EmbeddedNS component                                  *)
(*    Author:   Nikolai Adrianov                                              *)
(*    Created:  10/08/2003                                                    *)
(******************************************************************************)


nikkie (23.06.04 11:25) [19]
будет твой код - можно о чем-то говорить... а пока что могу только сказать, что у тебя ошибка


хм... какой код ты хочешь? Я тебе привел код, в том числе в ассемблере...


 
Piter ©   (2004-06-23 12:04) [21]

И вообще, nikkie, чего ты обижаешься...


 
nikkie ©   (2004-06-23 12:08) [22]

[23] Piter ©   (26.05.04 22:51)
...
P.S. Кстати, Nikkie, ты не правил EmbeddedNS в последнее время? А то может ты исправил глюк там какой...

[26] nikkie ©   (26.05.04 23:24)
...
>ты не правил EmbeddedNS в последнее время?
первое и последнее (пока) изменение
(*  v1.01  03/04/2004 NA                                                      *)
(*        A problem with thread creation is fixed.                            *)
(*        The problem sometimes resulted in AV.                               *)


 
Piter ©   (2004-06-23 12:17) [23]

nikkie (23.06.04 12:08) [22]

а где взять последнюю версию EmbeddedNS?


 
nikkie ©   (2004-06-23 12:19) [24]

там же, где и первую.
http://dmclient.nm.ru/downloads.htm


 
Piter ©   (2004-06-23 12:32) [25]

Нет, не в этом дело :(

Опять же, ошибка происходит при вызове GetData... в общем, как я писал... код я приводил


 
nikkie ©   (2004-06-23 12:46) [26]

глядя на этот код я могу только предположить такие варианты:
1. ты умудрился создать экземпляр абстрактного класса. но это вряд ли, поскольку тогда ошибка вылетала бы постоянно.
2. скорее всего в FHandler у тебя мусор оказывается. почему - я не знаю. ты привел 2 строчки моего кода, с которым я проблем не наблюдаю. если пришлешь мне проект, я могу посмотреть.


 
miwa ©   (2004-06-23 12:48) [27]

Немного не в тему, но все же. Piter, ты все время о своем клиенте рассказываешь. Сссылку хоть бы раз привел. А еще лучше - забросил бы инфу на сайт.


 
nikkie ©   (2004-06-23 13:05) [28]

сейчас посмотрел код еще раз - есть потенциальная проблема в EmbeddedNS.
может случиться, что TEmbeddedNSHandler уже разрушился (не знаю, может такое может случиться, если навигация прерывается), а тред еще работает.
попробуй заменить код
constructor TEmbeddedNSWorkerThread.Create(Handler: TEmbeddedNSHandler);
begin
 FHandler := Handler;
 FreeOnTerminate := True;
 inherited Create(True);
end;

procedure TEmbeddedNSWorkerThread.Execute;
begin
 FHandler.DoExecute;
end;

на
constructor TEmbeddedNSWorkerThread.Create(Handler: TEmbeddedNSHandler);
begin
 FHandler := Handler;
 FHandler._AddRef;
 FreeOnTerminate := True;
 inherited Create(True);
end;

procedure TEmbeddedNSWorkerThread.Execute;
begin
 FHandler.DoExecute;
 FHandler._Release;
end;


 
Piter ©   (2004-06-23 13:57) [29]

Так, попробую по другому:

Ошибка происходит в этой процедуре:

procedure TEmbeddedNSHandler.DoExecute;
var
 FileName, FileExt, MimeType: String;
begin
 if FBindFlags and BINDF_FWD_BACK <> 0 then begin
   if LockCacheFile(FUrl, FileName, FileExt, MimeType) then begin
      try
        ReportCacheFile(PChar(FileName), PChar(FileExt),
          PWideChar(WideString(MimeType)));
      finally
        UnlockCacheFile(FUrl);
      end;
      Exit;
   end;
 end;
 GetData; //  <-- ЗДЕСЬ проявляется ошибка
end;


При вызове GetData происходит переход по черт знает какому адресу и вылетает AV. Но значение полей перед вызовом "фатального" GetData не совсем обычно.
Вот типичный пример значения полей, когда GetData обрабатывается нормально:

FUrl:   "mgfm://LoadPage/?n=-1&page=0"
FProtocolSink:   Pointer($186448) as IInternetProtocolSink
FTerminated:   False
FFirstDataNotification:   True
FReadStream:   nil
FWriteStream:   nil
FWaitingData:   False
FThread:   ($CF4EB8)
FBindFlags:   1048771
FBindInfo:   (84, nil, (0, 0, nil, 0, 0, 0, nil, nil, nil), 0, 0, nil, 0, 524288, 0, 1251, (0, nil, False), (0, 0, 0, (0, 0, 0, 0, 0, 0, 0, 0)), nil, 0)


Вызов TEmbeddedNSHandler.DoExecute происходит при создании нового экземпляра EmbeddedWB. Тут все нормально.

А вот значения полей перед тем как GetData вызовет ошибку:

FUrl:   ""
FProtocolSink:   nil
FTerminated:   True
FFirstDataNotification:   True
FReadStream:   nil
FWriteStream:   nil
FWaitingData:   False
FThread:   ($CF4A90)
FBindFlags:   1048771
FBindInfo:   (84, nil, (0, 0, nil, 0, 0, 0, nil, nil, nil), 0, 0, nil, 0, 524288, 0, 1251, (0, nil, False), (0, 0, 0, (0, 0, 0, 0, 0, 0, 0, 0)), nil, 0)


Как видно, значение FProtocolSink равняется nil. Да и вообще, FTerminated равняется True. Все это происходит при закрытии окна (удалении экземпляра TEmbeddedWB).

В итоге вот что получается:

1) при создании экземпляра EmbeddedWB вызывается процедура TEmbeddedNSHandler.DoExecute, которая отрабатывает совершенно нормально (вызов GetData в ней приводит к вызову обработчика потомка TMyHandler).

2) при "нормальном" удалении экземпляра EmbeddedWB процедура TEmbeddedNSHandler.DoExecute вообще не вызывается... все работает нормально.

3) при "ненормальном удалении" экземпляра EmbeddedWB процедура TEmbeddedNSHandler.DoExecute ВЫПОЛНЯЕТСЯ. И когда в ней доходит до GetData - все рушится. Никакого вызова метода потомка не происходит...


 
Piter ©   (2004-06-23 13:58) [30]

nikkie (23.06.04 13:05) [28]

ок, сейчас попробую


 
Piter ©   (2004-06-23 13:59) [31]

miwa (23.06.04 12:48) [27]

сейчас, решу некоторые проблемы и выложу beta4


 
nikkie ©   (2004-06-23 14:01) [32]

Как видно, значение FProtocolSink равняется nil. Да и вообще, FTerminated равняется True. Все это происходит при закрытии окна (удалении экземпляра TEmbeddedWB).
вот это стоило сказать сразу. я тоже поймал такой момент, правда для этого приходится предпринимать специальные усилия в дебаге. проблема понятна, я ее исправлю. странно мне только - вроде в [17] все описано иначе.


 
Piter ©   (2004-06-23 14:01) [33]

nikkie (23.06.04 13:05) [28]

ДА! Отработало безупречно...


 
Piter ©   (2004-06-23 14:04) [34]

nikkie (23.06.04 14:01) [32]
вроде в [17] все описано иначе


почему? Тоже самое, только немного с другого бока... ассемблерные комманды ведь именно такие... я просто не догадался значения полей привести...


 
Piter ©   (2004-06-23 14:05) [35]

nikkie (23.06.04 14:01) [32]

ну что, я изменяю EmbeddedNS так, как сказано в nikkie ©   (23.06.04 13:05) [28] и считаем, что это версия 1.02?


 
Piter ©   (2004-06-23 14:10) [36]

провел тест. Было открыто, закрыто около 1000 окон (соответственно, создано, удалено столько же экземпляров EmbeddedWB). Все нормально, ничего не сыпится, хотя раньше и до 50 не дошло бы...


 
nikkie ©   (2004-06-23 14:18) [37]

>почему? Тоже самое, только немного с другого бока...
потому что в [17] AV возникает вовсе не на строке FProtocolSink.ReportProgress. и проблема не в том, что FProtocolSink равен nil.

кроме того, внеся изменения [28], я научился ловить AV описанный в [29]. так что это разные проблемы.

>ну что, я изменяю EmbeddedNS
изменяй пока

>и считаем, что это версия 1.02?
нет, я потом выложу новую версию сам.


 
Piter ©   (2004-06-23 14:55) [38]

nikkie (23.06.04 14:18) [37]
потому что в [17] AV возникает вовсе не на строке FProtocolSink.ReportProgress


Правильно! Только вот в Piter ©   (23.06.04 13:57) [29] ошибка возникает тоже не в FProtocolSink.ReportProgress!

Ошибка всегда возникает при вызове GetData! Просто в [29] я тебе привел значение полей перед тем, как GetData вызовет ощибку!


 
Piter ©   (2004-06-23 17:24) [39]

nikkie (23.06.04 14:18) [37]
нет, я потом выложу новую версию сам


А куда ты выложишь новую версию и как можно узнать, что ты ее выложил?


 
nikkie ©   (2004-06-23 17:34) [40]

для начала почту проверить. я тебе ее на newmail отослал.



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

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

Наверх




Память: 0.58 MB
Время: 0.03 c
3-1087217688
vlad_ri
2004-06-14 16:54
2004.07.11
список баз данных на MS SQL сервере


1-1088062295
Heretic
2004-06-24 11:31
2004.07.11
Дочерние окна


9-1080245106
GunmeN
2004-03-25 23:05
2004.07.11
Дым войны


3-1086945837
Xmen
2004-06-11 13:23
2004.07.11
Oracle


1-1088102299
georg
2004-06-24 22:38
2004.07.11
1С: бухгалтерия, или вопрос немного не в тему