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

Вниз

Сенсация! Код initialization может не выполнятся!   Найти похожие ветки 

 
MikProg ©   (2006-07-11 21:37) [0]

Написана прога. С целью сериализации в секции initialization семи унитов регистрируется описанные в них классы через registerclass. Фенька в следующем: у меня программа работает, у клиента нет. Вставленные в секцию инициализации отладочные строки для записи в файл пишут лог в порядке инициализации модулей. В логе запуска на моей машине (XP и Win2k) отметился каждый из 7 модулей. В логе запуска того же экзешника у клиента (Win2k) отметились тольк 3 из 7 модулей !!! Это полный трындец! Я понимаю что могу грубо регистрировать классы где нибудь в одном месте, но это есть покушение на устои! Кто нибудь может объяснить?


 
Мефисто   (2006-07-11 21:40) [1]

Код в студию, и возможно объясним...


 
Суслик ©   (2006-07-11 22:13) [2]

runtime пакеты используешь?


 
MikProg ©   (2006-07-11 22:19) [3]

unit RenderParameters;

initialization

 LogRecord("RenderParameters start");
 RegisterClasses([TSurfacePoint,TSurface,TBaseRenderParams,TRenderParams]);
 LogRecord("RenderParameters end");

finalization

end.

unit IGGProjectsCollection;

initialization

 LogRecord("IGGProjectsCollection start");
 RegisterClass(TFrameProjectMember);
 RegisterClass(TFrameProject);
 RegisterClass(TProjectsCollection);
 LogRecord("IGGProjectsCollection end");

finalization

end.

unit IGGPaintBoxImaged;

initialization

 LogRecord("IGGPaintBoxImaged start");
 RegisterClass(TFrameImaged);
 LogRecord("IGGPaintBoxImaged end");

finalization
 
end.

unit IGGPaintBoxImage;

initialization

 LogRecord("IGGPaintBoxImage start");
 RegisterClass(TFrameImage);
 TFrameImage.LayerClassesRegistrator(TFrameImage);
 LogRecord("IGGPaintBoxImage start");

finalization

end.

unit IGGPaintBoxShape;

initialization

 LogRecord("IGGPaintBoxShape start");
 RegisterClasses([TFramePoly,TFrameFigure,TFrameGeom,TFramePie]);

 TFramePoly.LayerClassesRegistrator(TFramePoly);
 TFrameFigure.LayerClassesRegistrator(TFrameFigure);
 TFrameGeom.LayerClassesRegistrator(TFrameGeom);
 TFramePie.LayerClassesRegistrator(TFramePie);
 LogRecord("IGGPaintBoxShape end");

finalization

end.

unit IGGPaintBoxText;

initialization

 LogRecord("IGGPaintBoxText start");
 RegisterClass(TFrameText);
 TFrameText.LayerClassesRegistrator(TFrameText);
 LogRecord("IGGPaintBoxText end");

finalization

end.

unit IGGPaintBoxDrowing;

initialization

 LogRecord("IGGPaintBoxDrowing start");
 RegisterClass(TFrameDrowing);
 TFrameDrowing.LayerClassesRegistrator(TFrameDrowing);
 LogRecord("IGGPaintBoxDrowing end");

finalization

end.

Все происходят от базового класса, который определяет  
LayerClassesRegistrator

unit LayerBase;

interface

uses
 windows, classes, unit3;

type

 TLayerBase = class;
 TLayerBaseClass = class of TLayerBase;

 TLayerItem = class (TCollectionItem)
 end;

 TLayerBase = class (TComponent)
 private
   FLayerID: cardinal;
 protected
   procedure AssignTo(Dest: TPersistent); override;
 public
   constructor Create(AOwner: TComponent); override;
   class function CreateFrom(Sample: TLayerBase): TLayerBase; virtual;
   class procedure LayerClassesRegistrator(LayerClass: TLayerBaseClass);
   class function LayerClassesCount: integer;
   class function LayerClassesItems(index: integer): TLayerBaseClass; overload;
   class function LayerClassesItems(ClassName: String): TLayerBaseClass; overload;
   property LayerID: cardinal read FLayerID;
 end;

implementation

var
 LayerClasses: array of TLayerBaseClass;
 LayerIDs: cardinal;

class procedure TLayerBase.LayerClassesRegistrator(
 LayerClass: TLayerBaseClass);
begin
 SetLength(LayerClasses,high(LayerClasses)+2);
 LayerClasses[high(LayerClasses)]:=LayerClass;
end;

class function TLayerBase.LayerClassesCount: integer;
begin
 Result:=high(LayerClasses)+1;
end;

initialization

 LayerClasses:=nil;
 LayerIDs:=0;

finalization

end.

в Dpr все выглядит вот так

uses
 Classes,
 Forms,
 Unit1 in "Ani\Unit1.pas" {Form1},
 IGG2AniEdit in "Ani\IGG2AniEdit.pas" {IGG2AniEditFrame: TFrame},
 IGGPaintBoxText in "Modules\IGGPaintBoxText.pas",
 IGGPaintBoxDrowing in "Modules\IGGPaintBoxDrowing.pas",
 IGGPaintBoxImage in "Modules\IGGPaintBoxImage.pas",
 IGGPaintBoxImaged in "Modules\IGGPaintBoxImaged.pas",
 IGGPaintBoxShape in "Modules\IGGPaintBoxShape.pas",
 GIFImage in "Utils\GIFImage.pas",
 RenderParameters in "Modules\RenderParameters.pas",
 IGGPaintBoxControls in "Modules\IGGPaintBoxControls.pas",
 IGGProjectsCollection in "Modules\IGGProjectsCollection.pas",
 Unit3 in "Unit3.pas";

{$R *.res}

begin
 Application.Initialize;
 RegisterClass(TFrameText);
 RegisterClass(TFrameDrowing);
 RegisterClasses([TFramePoly,TFrameFigure,TFrameGeom,TFramePie]);
 RegisterClasses([TSurfacePoint,TSurface,TBaseRenderParams,TRenderParams]);
 Application.CreateForm(TForm1, Form1);
 CheckRegisteredClassList;
 Application.Run;
end.


registerclass сюда всунут позже, чтобы хоть как то работало.

У меня в логе
11.07.2006 16:27:00 : Initializing parameters
11.07.2006 16:27:00 : RenderParameters start
11.07.2006 16:27:00 : RenderParameters end
11.07.2006 16:27:00 : IGGProjectsCollection start
11.07.2006 16:27:00 : IGGProjectsCollection end
11.07.2006 16:27:00 : IGGPaintBoxImaged start
11.07.2006 16:27:00 : IGGPaintBoxImaged end
11.07.2006 16:27:00 : IGGPaintBoxImage start
11.07.2006 16:27:00 : IGGPaintBoxImage start
11.07.2006 16:27:00 : IGGPaintBoxControls start
11.07.2006 16:27:00 : IGGPaintBoxControls end
11.07.2006 16:27:00 : IGGPaintBoxShape start
11.07.2006 16:27:00 : IGGPaintBoxShape end
11.07.2006 16:27:00 : IGGPaintBoxText start
11.07.2006 16:27:00 : IGGPaintBoxText end
11.07.2006 16:27:00 : IGGPaintBoxDrowing start
11.07.2006 16:27:00 : IGGPaintBoxDrowing end

У клиента в логе (на американской винде 2000)
7/11/2006 4:50:08 PM : Initializing parameters
7/11/2006 4:50:08 PM : RenderParameters start
7/11/2006 4:50:08 PM : RenderParameters end
7/11/2006 4:50:08 PM : IGGProjectsCollection start
7/11/2006 4:50:08 PM : IGGProjectsCollection end
7/11/2006 4:50:08 PM : IGGPaintBoxImaged start
7/11/2006 4:50:08 PM : IGGPaintBoxImaged end
7/11/2006 4:50:08 PM : IGGPaintBoxImage start
7/11/2006 4:50:08 PM : IGGPaintBoxImage start
7/11/2006 4:50:08 PM : IGGPaintBoxControls start
7/11/2006 4:50:08 PM : IGGPaintBoxControls end


 
MikProg ©   (2006-07-11 22:44) [4]

скомпилировано все в одном


 
Суслик ©   (2006-07-11 22:46) [5]

Чисто формальный вопрос
А где LayerBase в списке модулей?

(просто не понимаю)


 
MikProg ©   (2006-07-11 22:58) [6]

А надо? Там довольно длинная иерархия и в проект включены только модули с классами участвующими в сериализации (в которых имеется registerclass).


 
Суслик ©   (2006-07-11 23:06) [7]


> А надо

Скажу, как думаю - а фиг его знает.
Не секрет, что специфицированность некоторых аспектов Object Pascal недосточна. Бывает, что intialization не выполняется для модулей из runtime пакетов. Хоть закономерность невыполнения указанной секции мне ясна, но  я этого в доке явно не видел. Поэтому надо (имхо, есно) полагаться на подход, который сам борланд использует.


 
sniknik ©   (2006-07-11 23:12) [8]

возможно чудо "живет" в процедуре LogRecord (помню долго тут ктото такоеже чудо рекламировал (запись в несуществующий файл)... а в итоге оказалось пишет в текущую директорию, которая негарантирована, т.е. не всегда та, что надо)


 
MikProg ©   (2006-07-12 08:21) [9]

>который сам борланд использует.

А использован не он? В каких еще местах Борл размещает registerclass?

>возможно чудо "живет" в процедуре LogRecord

Добавлено позже для отладки


 
Сергей М. ©   (2006-07-12 08:41) [10]


> MikProg ©   (12.07.06 08:21) [9]


Судя по сравнению фрагментов приведенных логов, если у клиента в логе отсутствует строчка "IGGPaintBoxShape start" (и все последующие), то "чудо" живет именно в LogRecord().


 
sniknik ©   (2006-07-12 08:59) [11]

> Добавлено позже для отладки
и как это гарантирует от ошибки в ней?

с чего вообще решено, что не отрабатывает initialization? ведь если убрать  лог, то никаких доказательств этого нет, а раз это еще и добавлялось позднее для проверки то получается решение, что виновато, принято раньше. на чем основываясь? нам ничего не приведено.
надо сказать тут можно считать вовсе ничего не приведено, т.к. код оказывается проверкой домыслов (неизвестно на чем основанных. нам неизвестно. автор возможно судит по ошибке "не буду работать! © initialization" ;), то его можно откинуть, он ничего не показывает/не доказывает. плюс еще откидываем эмоции и остается - "у меня программа работает, у клиента нет" (единственный факт/значимая инфа), и для этого факта есть куча обьяснений попроще чем вера в чудо.
... тоже мне нашол "чудо", да такие "чудеса" куча народу считающих себя программистами пишут.


 
ЮЮ ©   (2006-07-12 09:15) [12]

Если программа слетела, а в файле лога нет ожидаемой информации, имхо, вовсе не следует,что она туда не "писалась", она могла просто "потеряться" из-за аварийного закрытия файла протокола = незакрытитию текстового файла


 
MikProg ©   (2006-07-12 10:00) [13]

Что вы как дети, ей богу!

>с чего вообще решено, что не отрабатывает initialization?
Бритву Оккама знаете? Потому что на вкус, запах и цвет выглядит как неотработка ВСЕГО кода initialization в определенных модулях.


procedure Unit3CheckExistance(ClNa: string);
begin
 if cf.GetClass(ClNa)=nil  then
   LogRecord(ClNa+" not exists")
 else
   LogRecord(ClNa+" exists");
end;

procedure CheckRegisteredClassList;
begin
 LogRecord("=== Registered Classes");
 cf:=TClassFinder.Create;
 Unit3CheckExistance("TProjectsCollection");
 Unit3CheckExistance("TFrameText");
 Unit3CheckExistance("TFrameDrowing");
 Unit3CheckExistance("TFrameImage");
 Unit3CheckExistance("TFrameImaged");
 Unit3CheckExistance("TFramePoly");
 Unit3CheckExistance("TFrameFigure");
 Unit3CheckExistance("TFrameGeom");
 Unit3CheckExistance("TFramePie");
 cf.Free;
 LogRecord("=== Registered Classes end");
end;


7/11/2006 5:55:51 PM : TProjectsCollection exists
7/11/2006 5:55:51 PM : TFrameText not exists
7/11/2006 5:55:51 PM : TFrameDrowing not exists
7/11/2006 5:55:51 PM : TFrameImage exists
7/11/2006 5:55:51 PM : TFrameImaged exists
7/11/2006 5:55:51 PM : TFramePoly not exists
7/11/2006 5:55:51 PM : TFrameFigure not exists
7/11/2006 5:55:51 PM : TFrameGeom not exists
7/11/2006 5:55:51 PM : TFramePie not exists

И кто вам сказал, что я ищу ошибку в коде? Я ищу причины приводящие к указанному эффекту и обсусловленные не только кодом, но и средой исполнения и наличием на компе программ третьих лиц.

>да такие "чудеса" куча народу считающих себя программистами пишут.
Поосторожней, пожалуйста. А то я пройдусь по корифействующим ламерам.

>Если программа слетела
Не слетела. Никаких эксепшанов, сообщений и пр. Нормально работает (насколько она это может при недозарегистрированных классах)

>вовсе не следует,что она туда не "писалась"

пусть только попробует! :)

procedure LogRecord(s: string);
var
 f: Text;
 oems: array [0..4096] of Char;
begin
   Assign(f,LogFileName);
   if not FileExists(LogFileName) then
     Rewrite(f)
   else
     Append(f);
   Writeln(f,DateTimeToStr(now)," : ",s);
   Close(f);
end;


 
Сергей М. ©   (2006-07-12 10:15) [14]


> MikProg ©   (12.07.06 10:00) [13]


Инф-ция тебе к размышлению - ф-ции RegisterClass[es], GetClass и иже с ними работают с конкретным экземпляром RTTI, создаваемым конкретным экземпляром RTL.
Если класс A зарегистрирован в экземпляре RTTI1  (RTL1), а класс В - в RTTI2 (RTL2), то обращения RTL1.GetClass(В) и RTL2.GetClass(А) - хоть из штанов выпрыгни - гарантированно вернут nil.


 
evvcom ©   (2006-07-12 10:16) [15]

Таблетка от [12]: использовать функцию Flush в LogRecord().
Кроме того, добавь обработчик Aplication.OnException, в нем ту же LogRecord() с выводом текста ошибки.


 
evvcom ©   (2006-07-12 10:20) [16]

> [15] evvcom ©   (12.07.06 10:16)

Ну раз открываешь и сразу закрываешь, то да, Flush излишен. :)


 
han_malign ©   (2006-07-12 10:21) [17]


> if not FileExists(LogFileName) then
>      Rewrite(f)
>    else
>      Append(f);

- есть еще такая функция - ForceDir(в разных вариациях) называется.
А семейство Assign и т.д. - как раз, с большой вероятностью, может сгенерировать exception при {$I+}. При этом, если SysUtils еще не инициализирован, то никаких VCL исключений ты и не увидишь...


 
han_malign ©   (2006-07-12 10:31) [18]

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


 
REA   (2006-07-12 10:52) [19]

Подтверждаю - когда программировал систему plugin-ов (на bpl) эта секция вызывалась не всегда - пришлось что то где то явно прописывать.
На нескольких компьютерах не проверял, но скорее всего дело не в компьютере а в конфигурации софта.


 
Сергей М. ©   (2006-07-12 11:07) [20]


> REA   (12.07.06 10:52) [19]


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


 
REA   (2006-07-12 11:15) [21]

Видимо для bpl все-таки может. Исключений не было там.


 
Плохиш ©   (2006-07-12 11:26) [22]


> >вовсе не следует,что она туда не "писалась"
>
> пусть только попробует! :)
>
> procedure LogRecord(s: string);

Осталось только выяснить, чему равно LogFileName?


 
sniknik ©   (2006-07-12 11:26) [23]

> И кто вам сказал, что я ищу ошибку в коде? Я ищу причины приводящие к указанному эффекту и обсусловленные ...
а, понятно, значит в своем коде сомнений нет, он "идеален и безупречен"... а поиск идет того "Била Гейтца" на которого можно было бы свалить вину за неработающую программу...
ну тогда ветку надо было начинать в потрепаться, а не в тематическом форуме.

> Поосторожней, пожалуйста. А то я пройдусь по корифействующим ламерам.
интересно было бы послушать... кстати корифеи то как раз легко воспринимают то что могут чегото не знать, могут ошибиться... (потому то и пишут без ошибок, что допускают их возможность у себя, и ищут их, а не там где светлее)
восприятие в штыки резонных в общемто замечаний это как раз черта воинствующих ламеров (врочем, другие разве бывают? если ламер начал задумываться и допускать свою неправоту то он уже юзер... ;)

>>вовсе не следует,что она туда не "писалась"
> пусть только попробует! :)

> procedure LogRecord(s: string);
> var
>  f: Text;
>  oems: array [0..4096] of Char;
> begin
>    Assign(f,LogFileName);
>    if not FileExists(LogFileName) then
>      Rewrite(f)
>    else
>      Append(f);
>    Writeln(f,DateTimeToStr(now)," : ",s);
>    Close(f);
> end;

опять таки, показанное не докаывает ничего... ну кроме того что у человека написавшего это ошибки очень даже возможны.
по пунктам
1. LogFileName оно указывает на конкретную директорию+файл или это просто имя файла? если файл, то вот оно "чудо" и есть (про которое я говорил), если же нет то почему не приведено? ты же вроде понял про что разговор и пытаешся этим кодом показать, что все "в ажуре"? а
2. передача строк в процедуру, судя по всему не только сдесь. мсье ничего не знает о передаче по ссылке, и что оно значит? зачам нужны var, const знаеш?
(только не надо вываливать кучу справочной инфы доказывающей что это тебе известно и раз плюнуть и "только здесь не так т.к. здесь и набивалось, для примера". не используеш значит не знаеш. а если знаеш и не используеш то это еще хуже)
3. ну то что устаревшие конструкции изпользуются (Text, Assign,) со времен паскаля, это ладно, компилится же, но лучше бы пользовался чем нибудь поновее (TextFile, AssignFile).
4. oems: array [0..4096] of Char; это зачем? явно не для того чтобы показать что код не набит сдесь, а скопирован... или он скопирован и "исковеркан" (типа только нужное показать)? ну тогда что он может показать вообще?


 
Сергей М. ©   (2006-07-12 11:30) [24]


> для bpl все-таки может


Нет, не может.


 
GrayFace ©   (2006-07-12 11:40) [25]

Суслик ©   (11.07.06 23:06) [7]
> специфицированность

А это что за зверь? :)

> Поэтому надо (имхо, есно) полагаться на подход, который сам борланд использует.

Че за подход?


 
Игорь Шевченко ©   (2006-07-12 11:49) [26]

sniknik ©   (12.07.06 11:26) [23]


> 2. передача строк в процедуру, судя по всему не только сдесь.
>  мсье ничего не знает о передаче по ссылке, и что оно значит?
>  зачам нужны var, const знаеш?


А эта...в чем принципиальная разница передачи строки в этом случае ?

PS: У некоторых глаголов на конце пишется мягкий знак.


 
sniknik ©   (2006-07-12 12:15) [27]

> А эта...в чем принципиальная разница передачи строки в этом случае ?
приципиально никакой, потому и "обьеденил", разница только в указании неменяемости второго, для твоегоже(программиста) контроля со стороны компилятора.

> PS: У некоторых глаголов на конце пишется мягкий знак.
знаю, но ничего поделать не могу... врожденная неграмотность, или писать быстро или перепроверять каждое слово (в ворде например). никакого удовольствия от общения тогда...


 
Юрий Зотов ©   (2006-07-12 12:26) [28]

> Игорь Шевченко ©   (12.07.06 11:49) [26]

> в чем принципиальная разница передачи строки в этом случае?

Создается копия строки - а зачем, если она не нужна? Впустую тратится время, впустую тратится память.


 
REA   (2006-07-12 12:28) [29]

2Сергей М. ©   (12.07.06 11:30) [24]
Не буду утверждать со стопроцентной уверенностью, но эффект был и не только в отладчике - классы в initialization секции bpl не регистрировались.
Система связей между bpl там достаточно сложная, поэтому эксперимент в чистом виде не поставить (да и времени нет).
Перенес регистрацию в initialization другого модуля (функции которого задействованы явно из другого bpl) - заработало.
Возможно этого не может быть - я лишь констатирую факт.


 
sniknik ©   (2006-07-12 12:39) [30]

Юрий Зотов ©   (12.07.06 12:26) [28]
> Создается копия строки - а зачем, если она не нужна? ...
я вообщето понял так, что Игорь про разницу между var и const.


 
Сергей М. ©   (2006-07-12 12:42) [31]


> REA   (12.07.06 12:28) [29]


> классы в initialization секции bpl не регистрировались


RegisterClass[es], выполнившаяся без исключения, гарантирует регистрацию в конкретном экз-ре RTTI.


 
han_malign ©   (2006-07-12 12:45) [32]

OFFTOP

> Создается копия строки - а зачем, если она не нужна? Впустую тратится время, впустую тратится память.

- вот уж от кого, а от вас(тебя) не ожидал...
{$H+}
Copy on change


 
Юрий Зотов ©   (2006-07-12 12:45) [33]

Кстати, о птичках. Что-то я сам в своих словах (см. [28]) засомневался и поставил маленький эксперимент:

procedure TForm1.FormCreate(Sender: TObject);
begin
 FStr := "Bill Gates"
end;

procedure WithoutVarAndConst(S: string);
begin
//  S := S + ";";
 with Form1 do
   Caption := Format("FStr: %x, S: %x", [Cardinal(Pointer(FStr)), Cardinal(Pointer(S))])
end;

procedure WithVar(var S: string);
begin
 with Form1 do
   Caption := Format("FStr: %x, S: %x", [Cardinal(Pointer(FStr)), Cardinal(Pointer(S))])
end;

procedure WithConst(const S: string);
begin
 with Form1 do
   Caption := Format("FStr: %x, S: %x", [Cardinal(Pointer(FStr)), Cardinal(Pointer(S))])
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 WithoutVarAndConst(FStr)
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 WithVar(FStr)
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
 WithConst(FStr)
end;

Результат - все три процедуры выдают одно и тоже. Хотя ожидалось, что процедура WithoutVarAndConst выдаст адрес копии строки, а не самой строки (как две оставшиеся). Если раскомментировать выделенную строчку, то, естественно, так и происходит - то есть, копия строки, если она нужна, создается уже при работе самой процедуры, но исходным параметром в нее приходит все же оригинал.

Ох, и не дурак же он, этот компилятор.
:о)


 
han_malign ©   (2006-07-12 12:56) [34]


> Кстати, о птичках.

- я пошел дальше и вывел RefCount - он увеличивается в WithoutVarAndConst... :)


 
Юрий Зотов ©   (2006-07-12 13:10) [35]

> han_malign ©   (12.07.06 12:56) [34]

Естественно, раз приходит оригинал.


 
MikProg ©   (2006-07-12 13:41) [36]

Мммда. А никто не хочет узнать что творится в IGGPaintBoxControls?

unit   IGGPaintBoxControls;

initialization

 LogRecord("IGGPaintBoxControls start");
 RegisterClass(TFrameMembers);
 CF_IGGControls:=RegisterClipboardFormat("IGG2Controls");
 LogRecord("IGGPaintBoxControls end");

finalization

end.


 
Сергей М. ©   (2006-07-12 13:43) [37]


> MikProg ©   (12.07.06 13:41) [36]


И что же там "криминального" творится, по-твоему ?


 
Игорь Шевченко ©   (2006-07-12 13:53) [38]


> Ох, и не дурак же он, этот компилятор.


Об том и речь. В изначально приведенном примере строка не модифицируется, отсюда резонный вопрос - какая разница, указывать const или не указывать ?


 
isasa ©   (2006-07-12 14:08) [39]

Юрий Зотов ©   (12.07.06 12:45) [33]
Ох, и не дурак же он, этот компилятор.

Так это, я тут напрягся и вспомнил, что передача параметра по значению еще со времен Турбо-Паскаля - только то, что меньше или равно длине регистра. :)
Остальное, все равно, по ссылке.


 
MikProg ©   (2006-07-12 14:09) [40]


> И что же там "криминального" творится, по-твоему ?

Ничего. Просто никто не удосужился посмотреть код, а рассуждений...



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

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

Наверх




Память: 0.6 MB
Время: 0.03 c
2-1155026404
c10wn
2006-08-08 12:40
2006.08.27
поиск с помощью inputbox


11-1131525779
algambra
2005-11-09 11:42
2006.08.27
В любом месте области формы по клику мышки срабатывает процедура


2-1155060328
Батыр
2006-08-08 22:05
2006.08.27
Proxy


15-1154011493
Vlad
2006-07-27 18:44
2006.08.27
Майкрософт шалит? :-)


1-1152541631
LeXaXaXa
2006-07-10 18:27
2006.08.27
Как перехватить сообщение закрытия окна?