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

Вниз

Использовать компоненты, но не использовать 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;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.035 c
15-1178042973
Kolan
2007-05-01 22:09
2007.05.27
Поставил винду, не могу зайти в DocumentsAndSettings старой


15-1177418638
ALLON
2007-04-24 16:43
2007.05.27
работа Delphi в ограниченом юзере


15-1177505791
palva
2007-04-25 16:56
2007.05.27
Геометрическая задача


15-1178102375
Megabyte
2007-05-02 14:39
2007.05.27
Интеграция MS Project и программ на .NET


2-1178724280
Veronika-n
2007-05-09 19:24
2007.05.27
Работа с DBGrid