Форум: "Начинающим";
Текущий архив: 2007.05.27;
Скачать: [xml.tar.bz2];
ВнизИспользовать компоненты, но не использовать Forms.pas Найти похожие ветки
← →
DevilDevil © (2007-05-05 22:16) [0]Мне интересно, есть ли в Delphi такая возможность. Есть что-то типа DataModule, на который можно брасать и настраивать компоненты, но при этом не использовать модуль Forms (не создавать и не запускать Application, ...). TComponent - это не TControl, поэтому форма ему не нужна. TDataModule - это потомок формы. Делать по аналогии с KOL достаточно сложно; нет ли более простого способа?
← →
Loginov Dmitry © (2007-05-05 22:36) [1]> TDataModule - это потомок формы
Кто сказал?
← →
DevilDevil © (2007-05-06 09:38) [2]хм... согласен, не потомок.
Тогда зачем создаются строки ?Application.Initialize;
Application.CreateForm(TDataModule1, DataModule1);
Application.Run;
Хочешь сказать, я могу тупо написать:DataModule1 := TDataModule1.Create(NIL);
DataModule1.Run(); // <-- Моё
DataModule1.Free;
и всё будет корректно работать?
← →
Leonid Troyanovsky © (2007-05-06 10:15) [3]
> DevilDevil © (06.05.07 09:38) [2]
> Тогда зачем создаются строки ?
Если звезды зажигаются, значит это кому-нибудь надо.
> Хочешь сказать, я могу тупо написать:
Нет. Надо писать остро.
> и всё будет корректно работать?
Что есть "корректно"?
--
Regards, LVT.
← →
Зюзя (2007-05-06 10:27) [4]Как минимум, надо все это в try-finally-end.
А вообще, естественно, работать будет.
Интересно, почему ты решил что нет?
Но только запомни: если ты отходишь от модели Win32 приложения, реализованной разработчиками Borland, то все грабли, которые ты встретишь на этом пути - твои личные проблемы.
То есть, делай что хочешь. Но потом не жалуйся.
← →
DevilDevil © (2007-05-06 11:57) [5]> Зюзя (06.05.07 10:27) [4]
Спасибо. Так?try
DataModule1 := TDataModule1.Create(NIL);
DataModule1.Run(); // <-- Моё
finally
DataModule1.Free;
end;
1) Т.е. если в коде будет raise, то сообщения об ошибке не будет?
2) А Какие там могут быть грабли?
← →
Loginov Dmitry © (2007-05-06 12:06) [6]Че дурью маешься? Нафик нужно такое приложение без объекта Application? Че с ним делать-то?
← →
DevilDevil © (2007-05-06 13:05) [7]> Loginov Dmitry © (06.05.07 12:06) [6]
Движок. Планирую лет так через надцать.
← →
jack128 © (2007-05-06 13:16) [8]Loginov Dmitry © (06.05.07 12:06) [6]
Нафик нужно такое приложение без объекта Application?
Ты не поверишь, но на дельфи иногда пишут приложения без GUI, соответственно и без Forms.Application
← →
Зюзя (2007-05-06 13:37) [9]Вот так:
DataModule1 := TDataModule1.Create(NIL);
try
DataModule1.Run(); // <-- Моё
finally
DataModule1.Free;
end;
1) Т.е. если в коде будет raise, то сообщения об ошибке не будет?
Будет. Не путай try-finally-end с try-except-end.
2) А Какие там могут быть грабли?
Какие угодно. Кто ж тебя знает, что у тебя там в DataModule реализовано, и как ты этим пользуешься.
Вот, например, Application инициализируется в модуле Controls, так что, если этот модуль у тебя в проекте подключен, то и Application у тебя будет, независимо от того, используешь ли ты его, или нет.
То есть, граблей может быть много. Но, ты же сам понимаешь, что про все возможные грабли и способы их обхода тебе никто не расскажет. Так что, если так уж очень хочется, будь готов к неожиданностям. (Я не пугаю, я просто предупреждаю). "Ищущий да обрящет" (С)
← →
Юрий Зотов © (2007-05-06 13:37) [10]> DevilDevil © (06.05.07 11:57) [5]
И Create должно стоять ПЕРЕД try.
← →
Loginov Dmitry © (2007-05-06 14:58) [11]> Ты не поверишь, но на дельфи иногда пишут приложения без
> GUI, соответственно и без Forms.Application
охотно верю
← →
DevilDevil © (2007-05-06 15:17) [12]> И Create должно стоять ПЕРЕД try.
А если raise произойдёт в TDataModule1.OnCreate() ?
> Будет. Не путай try-finally-end с try-except-end.
Хм... Я скорее всего что-то путаю...
raise только генерирует "сообщение об ошибке". А само сообщение выскакиваетtry
raise
except
on E : Exception do ... ; // <-- ЗДЕСЬ
end;
В Application.Run try..except есть, поэтому сообщения об ошибках raise мы видим. А как быть в "моём" случае?
← →
Loginov Dmitry © (2007-05-06 15:29) [13]> А как быть в "моём" случае?
А что особенного в твоем случае?
Что, Дельфи под рукой нету проверить?
← →
DevilDevil © (2007-05-06 17:21) [14]сейчас я спрашиваю, как корректно связать Finally и Except, не упуская возможности отловить ошибку в OnCreate. Недопонимаю, поэтому и спрашиваю :)
← →
Плохиш © (2007-05-06 17:41) [15]
> DevilDevil © (06.05.07 17:21) [14]
Ты уже давно здесь мелькаешь, но так до сих пор не соизволил хоть что-нибуть прочитать...
PS. Странно, что ветка всё ещё не в начинающих...
← →
DrPass © (2007-05-06 20:30) [16]
> сейчас я спрашиваю, как корректно связать Finally и Except
Конструктор должен вызываться перед блоком try..finally ***.Free; end (т.к. при исключении в конструкторе объект не будет создан, и делать free в секции finally отнюдь не кошерно), но может быть внутри блока try...except, ести тебе так хочется. Что тут непонятного?
← →
Leonid Troyanovsky © (2007-05-06 21:13) [17]
> DrPass © (06.05.07 20:30) [16]
> не будет создан, и делать free в секции finally отнюдь не
> кошерно), но может быть внутри блока try...except, ести
Разница лишь в том, что try..except допускает существование
жизни после смерти. Путем reraise.
--
Regards, LVT.
← →
DevilDevil © (2007-05-06 23:38) [18]ТАК ПРАВИЛЬНО:
try
DataModule1 := TDataModule1.Create(NIL);
except
on E : Exception do ... ; // показать ошибку
try
DataModule1.Free;
except
end;
Halt;
end;
TRY
try
DataModule1.Run(); // <-- Моё
except
on E : Exception do ... ; // показать ошибку
end;
FINALLY
try
DataModule1.Free;
except
end;
END;
← →
DevilDevil © (2007-05-06 23:39) [19]Т.е так:
try
DataModule1 := TDataModule1.Create(NIL);
except
on E : Exception do ... ; // показать ошибку
Halt;
end;
TRY
try
DataModule1.Run(); // <-- Моё
except
on E : Exception do ... ; // показать ошибку
end;
FINALLY
try
DataModule1.Free;
except
end;
END;
← →
Loginov Dmitry © (2007-05-06 23:44) [20]правильно так:
DataModule1 := TDataModule1.Create(NIL);
try
// Твое
finally
DataModule1.Free;
end;
← →
Юрий Зотов © (2007-05-07 00:41) [21]> DevilDevil © (06.05.07 15:17) [12]
> А если raise произойдёт в TDataModule1.OnCreate() ?
То произойдет следующее:
- объект создан не будет;
- переменная DataModule1 не получит верного значения;
- исключение будет передано в Ваш код;
- если Create стоит ВНУТРИ try, то исполнение перейдет в секцию finally, а там Free даст ВТОРОЕ исключение;
- если Create стоит ПЕРЕД try, то ВЕСЬ блок try-finally будет обойден и второго исключения не возникнет.
Золотое правило механики:
захватываем_какой-то_ресурс;
try
...
finally
освобождаем этот ресурс;
end;
Но ни в коем случае не так:
try
захватываем_какой-то_ресурс;
...
finally
освобождаем этот ресурс;
end;
Потому что если при захвате ресурса возникло исключение, то захвачен он не будет - значит, и освобождать нечего.
← →
DrPass © (2007-05-07 02:05) [22]
> Leonid Troyanovsky © (06.05.07 21:13) [17]
> Разница лишь в том, что try..except допускает существование
> жизни после смерти. Путем reraise.
Хм. А какое отношение эта мудрая мысль имеет к рассматриваемой проблеме?
← →
Loginov Dmitry © (2007-05-07 07:45) [23]> Но ни в коем случае не так:
>
> try
> захватываем_какой-то_ресурс;
> ...
> finally
> освобождаем этот ресурс;
> end;
И так иногда приходится делать. Но в этом случае нужно заранее позаботится о том, чтобы программа в блоке finally не пыталась освободить незанятый ресурс. Для этого перед try пишут следующее:
какой-то_ресурс := nil;
[это я к автору, ес-но :))]
← →
Юрий Зотов © (2007-05-07 09:23) [24]> Loginov Dmitry © (07.05.07 07:45) [23]
Можно привести реальный пример, когда без этого действительно не обойтись?
← →
Kedge © (2007-05-07 09:38) [25]> [24] Юрий Зотов © (07.05.07 09:23)
> Можно привести реальный пример, когда без этого действительно не обойтись?
Когда надо захватить мого ресурсов ?
Типа:
for i := 0 to ResCount - 1 do Resource[i] := nil;
try
for i := 0 to ResCount - 1 do Resource[i] := TResource.Create;
.............
finally
for i := 0 to ResCount - 1 do FreeAndNil(Resource[i]);
end;
← →
Loginov Dmitry © (2007-05-07 10:21) [26]> Можно привести реальный пример, когда без этого действительно
> не обойтись?
Пример:
FS1 := nil;
FS2 := nil;
FS3 := nil;
try
FS1 := TFileStream.Create(...);
FS2 := TFileStream.Create(...);
FS3 := TFileStream.Create(...);
{.......................}
finally
FS1.Free;
FS2.Free;
FS3.Free;
end;
Это иногда бывает компактнее, чем куча вложенных try...finally
Однако реально всегда можно обойтись вложенными try...finally. Но зачем?
← →
Leonid Troyanovsky © (2007-05-07 10:25) [27]
> DrPass © (07.05.07 02:05) [22]
> > Разница лишь в том, что try..except допускает существование
> > жизни после смерти. Путем reraise.
> Хм. А какое отношение эта мудрая мысль имеет к рассматриваемой
> проблеме?
Это к "но может быть внутри блока try...except".
Т.е., также не может.
Исключения в конструкторах оставляются обработчикам
более высокого уровня. Здесь уже это разжевали.
Хотя, похоже, не все усвоили. См., например, [25]
--
Regards, LVT.
← →
Leonid Troyanovsky © (2007-05-07 10:33) [28]
> Loginov Dmitry © (07.05.07 10:21) [26]
> Пример:
Ты ООПрограммист или где?
Создай объект с тремя полями.
Конструктор создает, деструктор разрушает.
--
Regards, LVT.
← →
Kedge © (2007-05-07 10:48) [29][27] Leonid Troyanovsky © (07.05.07 10:25)
>Хотя, похоже, не все усвоили. См., например, [25].
Не могу понять, что в этом примере "не так".
Или, после Resource[i] := TResource.Create,
в случае возникновения исключения в конструкотре, Resource[i] может стать не nil ?
← →
Leonid Troyanovsky © (2007-05-07 11:54) [30]
> Kedge © (07.05.07 10:48) [29]
> Не могу понять, что в этом примере "не так".
Похоже на ошибку проектирования.
Куча ссылок на объекты, с риском потери с ними связи
при выходе из области видимости.
Если мы удерживаем к-л. ссылку, должны быть
предприняты определенные усилия по поддержанию
их валидности от момента создания, до разрушения.
Одних nil явно недостаточно, должно быть предусмотрена
обработка возникших исключений в обработчике следующего
уровня, а значит, этот обработчик должен иметь доступ
к ссылкам на созданные (несозданные) объекты.
Иными словами, приведенный в примере массив не
может быть локальной переменной, а полем (списком полей,
массивом свойств и т.п.) более глобального объекта.
Ну, и, лучше, когда этот глобальный объект озаботится
поддержанием валидности удерживаемых ссылок.
--
Regards, LVT.
← →
Ega23 © (2007-05-07 17:14) [31]
> Плохиш © (06.05.07 17:41) [15]
>
> Ты уже давно здесь мелькаешь, но так до сих пор не соизволил
> хоть что-нибуть прочитать...
Он Флёнова читал.
← →
DevilDevil © (2007-05-07 18:37) [32]Я конечно извиняюсь... но по моему корректнее всё таки [19]. Я не прав?
← →
Loginov Dmitry © (2007-05-07 20:48) [33]И только Фленова, похоже.
← →
DevilDevil © (2007-05-08 13:35) [34]*пт, что здесь может быть неправильно, может кто либо скажет?
try
DataModule1 := TDataModule1.Create(NIL);
except
on E : Exception do ... ; // показать ошибку
Halt;
end;
TRY
try
DataModule1.Run(); // <-- Моё
except
on E : Exception do ... ; // показать ошибку
end;
FINALLY
try
DataModule1.Free;
except
on E : Exception do ... ; // показать ошибку
end;
END;
1) в случае, если произошла ошибка, её надо показать
2) ошбка может произойти в каждой из трёх строк
3) если ошибка произошла в конструкторе, то нужно показать и выйти из программы
4) если ошибки в конструкторе не произошло, то в любом случае должен быть вызван деструктор. Причём, если в деструкторе произошла ошибка, её нужно показать
Вопрос: если в Run произойдёт ошибка, то до Free() произойдёт?
← →
DevilDevil © (2007-05-08 13:36) [35]*то Free() произойдёт?
← →
Reindeer Moss Eater © (2007-05-08 13:41) [36]А просто проверить нельзя, если уж доку читать не хочется?
← →
Loginov Dmitry © (2007-05-08 14:13) [37]> 1) в случае, если произошла ошибка, её надо показать
Она и так будет показана. Причем то что будет показано достаточно информативно.
> 2) ошбка может произойти в каждой из трёх строк
Это уже особенности реализации методов OnCreate и OnDestroy датамодуля. Можно сделать, чтобы ошибки не возникало. Редкий случай возникновения ошибки можно оставить на совесть механизма обработки исключений. Он должен предупредить пользователя об ошибке и удалить все ненужные объекты.
> 3) если ошибка произошла в конструкторе, то нужно показать
> и выйти из программы
Вот в конструкторе-то ее и нужно ловить. Иначе, если в OnCreate произойдет ошибка, то она будет погашена (так для форм сделано, во всяком случае), и твой try..except здесь ничего сделать не сможет.
> 4) если ошибки в конструкторе не произошло, то в любом случае
> должен быть вызван деструктор. Причём, если в деструкторе
> произошла ошибка, её нужно показать
Оставь это на совесть механизма обработки исключений.
> Вопрос: если в Run произойдёт ошибка, то до Free() произойдёт?
мдя...
В результате все сводится к этому:
DataModule1 := TDataModule1.Create(NIL);
try
DataModule1.Run();
finally
DataModule1.Free;
end;
Если нужно отформатировать текст сообщения об ошибке, то можно весь оператор try..finally заключить в try..except (но оригинальный текст сообщения об ошибке не стоит менять, пусть он написан хоть на китайском).
← →
Ega23 © (2007-05-08 14:26) [38]
SomeObject := TSomeObject.Create;
try
try
SomeObject.DoSomething;
except
DoSomethingOnException;
end;
finally
SomeObject.Free;
end;
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.05.27;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.044 c