Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.036 c
15-1177586869
homm
2007-04-26 15:27
2007.05.27
«Архитектура вразрез» © В. Кладов


2-1178391133
ctudent
2007-05-05 22:52
2007.05.27
Порт


15-1177683530
Juice
2007-04-27 18:18
2007.05.27
ERwin vs Sybase PowerDesigner


15-1177485845
Steep
2007-04-25 11:24
2007.05.27
Java


2-1178597615
FIL-23
2007-05-08 08:13
2007.05.27
Нужна формула в игре





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский