Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[13.58.39.23] |
|
Сообщ.
#1
,
|
|
|
Привет... Обрисую проблему...
Создаю невизуальный компонент.. Унаследовался от TComponent... Скажем, у него есть простое свойство Active и метод Execute... В Execute написано примерно следующее begin if FActive then begin {операторы} end; так вот... Мне надо чтобы компонент сам, без помощи владельца выполнил Execute после своего создания... Создался и выполнил тут же... Внимание, проблема... если на форме выставить Active=true в Инспекторе объектов и запустить приложение - при подходе к if - FActive имеет значение false, и соответсвенно действия не выполняются... Пробовал переопределить AfterConstraction - то же самое, пробовал загнать это дело последним оператором в конструктор - тоже самое, пробовал... ну вообщем много всякой гадости... даже ComponentState проверял... Может, кто чего подскажет? |
Сообщ.
#2
,
|
|
|
type TMyComponent = class(TComponent) private FActive: Boolean; procedure SetActive(Value: Boolean); public property Active read FActive write SetActive; end; ... procedure SetActive(Value: Boolean); begin if FActive <> Value then begin FActive := Value; if FActive then // а дальше можно выполнять те действия, которые нужно при назначении нового значения свойству FActive end; end; |
Сообщ.
#3
,
|
|
|
Нет, я так и знал, что в этом дело... просто не хотел ковырять, у меня там свойств типа Active вагон и маленькая тележка, не хотел везде Set прописывать, да видно придется...
|
Сообщ.
#4
,
|
|
|
Цитата Maverick @ у меня там свойств типа Active вагон и маленькая тележка, не хотел везде Set прописывать Но что-то общее среди них есть? Если бы компонент был визуальный, то можно было бы использовать метод CreateWnd. Ну а тут, не зная о назначении и функциональности компонента, трудно сказать о том, как лучше поступить. |
Сообщ.
#5
,
|
|
|
type TMyComponent = class(TComponent) private FActive: Boolean; protected procedure loaded; override; public property Active read FActive write FActive; end; procedure TMyComponent.Loaded; begin inherited; if FActive then DoSamething; end; |
Сообщ.
#6
,
|
|
|
Смотря чего он должен делать, в большинстве своем можо напороться на HandleAllocated
|
Сообщ.
#7
,
|
|
|
Set понатыкал.... все работает...
Добавлено Вот... Второй в жизни компонент, потому строго не судите... Основная процедура из FAQ форума... Компонент занимается обновлением текущей версии программы... Можно проверять в периоде наличие новых версий... Пока работает только для обновлений из локальной сети... Кидаете, делаете активным, настраивате путь к серверу обновлений, период поиска обновлений, настраиваете степень информирования пользователя - все остальное он делает сам... Сделано для обучения и тренировки... Принимаю замечания, подсказки для доработки... Вагон свойств убрал, было много лишнего... unit cmpUpdPrg; interface uses Windows, Messages, SysUtils, Classes, Dialogs, Forms, ShellAPI, ExtCtrls, IniFiles; type TUpdInforUsrCase = (UserConfirm, UserInform, UserDown); //тип для способа информирования пользователя... TUpdatePrgEvent = procedure(Sender: TObject) of object; TUpdAutoTimeEvent = procedure(Sender: TObject) of object; TPeriodHour = 0..8;//тип для периода... TUpdPrg = class(TComponent) private { Private declarations } FPathToSource: String; //путь для обновления программы FActive: Boolean; //выполнять обновления? FRestart: Boolean; //рестартить приложение принудительно? FUpdInforUsrCase: TUpdInforUsrCase; //предпреждать, что программа была изменена? FTimer: TTimer; FPeriodHour: TPeriodHour; //период в часах... //================================ //СОБЫТИЯ FOnBeforeUpdatePrg: TUpdatePrgEvent; //поле для события обновления... FOnAfterUpdatePrg: TUpdatePrgEvent; //поле для события обновления... FOnUpdAutoTime: TUpdAutoTimeEvent; //================================ procedure BatCreate(); //создать управляющий батник... procedure BatExec(); //запустить управляющий батник... function VerifyNewVersion(): boolean; //проверить новую версию... //================================ procedure SetPeriodHour(Value: TPeriodHour); procedure SetActive(Value: Boolean); procedure SetRestart(Value: Boolean); procedure SetPathToSource(Value: String); procedure SetUpdInforUsrCase(Value: TUpdInforUsrCase); procedure FTimerTimer(Sender: TObject); //================================ protected { Protected declarations } procedure DispBeforeUpdatePrg; dynamic; procedure DispAfterUpdatePrg; dynamic; procedure DispUpdAutoTime; dynamic; public { Public declarations } constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure UpdExec; published { Published declarations } property PathToSource: String read FPathToSource write SetPathToSource; property Active: Boolean read FActive write SetActive; property UpdInforUsrCase: TUpdInforUsrCase read FUpdInforUsrCase write SetUpdInforUsrCase; property Restart: Boolean read FRestart write SetRestart; property PeriodHour: TPeriodHour read FPeriodHour write SetPeriodHour; //СОБЫТИЯ property OnBeforeUpdatePrg: TUpdatePrgEvent read FOnBeforeUpdatePrg write FOnBeforeUpdatePrg; property OnAfterUpdatePrg: TUpdatePrgEvent read FOnAfterUpdatePrg write FOnAfterUpdatePrg; property OnUpdAutoTime: TUpdAutoTimeEvent read FOnUpdAutoTime write FOnUpdAutoTime; end; implementation uses UnUnited; {$R CMPUPDPRG.DCR} //====КОНСТРУКТОР И ДЕСТРУТКОР================================================== constructor TUpdPrg.Create(AOwner: TComponent); begin //конструктор inherited Create(AOwner); if not (csDesigning in ComponentState) then begin FTimer := TTimer.Create(Self); FTimer.OnTimer := FTimerTimer; //FTimerTimer(FTimer); end; end; destructor TUpdPrg.Destroy(); begin //деструктор FTimer.Free; inherited Destroy; end; //============================================================================== procedure TUpdPrg.FTimerTimer(Sender: TObject); begin //событие по таймеру... UpdExec; //обновить прогу (или совершитьпопытку, по крайней мере...) if FActive then {-+-} DispUpdAutoTime; //вызвать событие по таймеру... end; function TUpdPrg.VerifyNewVersion(): boolean; var source_version, destination_version : string; begin //проверить новую версию... source_version := FileVersion( FPathToSource); //версия источника destination_version := FileVersion(ParamStr(0)); //версия обновляемой проги //ShowMessage(source_version + '|'+ destination_version); VerifyNewVersion := (source_version > destination_version); end; //===================================================================== //-----------ПЕРИОД---------------------------------------------------- procedure TUpdPrg.SetPeriodHour(Value: TPeriodHour); begin //прописать период обновления... FPeriodHour := Value; //присвоить значение в поле класса if not (csDesigning in ComponentState) then begin FTimer.Interval := FPeriodHour * 60 * 60 * 1000; FTimer.Enabled := true; FTimerTimer(FTimer); end; // SetPeriodHourInIni; //прописать в ини-файл end; //--------------------------------------------------------------------- procedure TUpdPrg.SetActive(Value: Boolean); begin FActive := Value; end; procedure TUpdPrg.SetRestart(Value: Boolean); begin FRestart := Value; end; procedure TUpdPrg.SetPathToSource(Value: String); begin FPathToSource := Value; end; procedure TUpdPrg.SetUpdInforUsrCase(Value: TUpdInforUsrCase); begin FUpdInforUsrCase := Value; end; //==ОСНОВНЫЕ ПРОЦЕДУРЫ========================================================== procedure TUpdPrg.UpdExec; var user_confirm : boolean; dialog_type: longint; begin //произвести обновление... dialog_type := 0; user_confirm := true; if not (csDesigning in ComponentState) then begin if FActive then if VerifyNewVersion then begin FTimer.Enabled := false; //выключить таймер обновления case FUpdInforUsrCase of //форма диалога с юзером (ок-отмена или просто ок) UserConfirm: dialog_type := MB_OKCANCEL or MB_ICONINFORMATION; UserInform: dialog_type := MB_OK or MB_ICONINFORMATION; end; if dialog_type<>0 then if Application.MessageBox('Обнаружена новая версия. Обновить?', 'Подтверждение', dialog_type)= IDCANCEL then user_confirm := false; if user_confirm then begin {-+-} DispBeforeUpdatePrg; //вызвать событие начала обновления... BatCreate; //создать бат-файл... Application.ProcessMessages; BatExec; //запустили батник... Application.ProcessMessages; {-+-} DispAfterUpdatePrg; //вызвать событие конца обновления... if FRestart then //закрыть... begin Application.Terminate; end; end; FTimer.Enabled := true; //выключить таймер обновления end; end; end; procedure TUpdPrg.BatCreate(); var sl: TStringList; begin //создать бат-файл sl:=TStringList.Create; try sl.Add(':start'); sl.Add('del "'+ParamStr(0)+'" '); sl.Add('if Exist "'+ParamStr(0)+'" goto start'); sl.Add('copy "' + FPathToSource + '" "' +ParamStr(0)+'"'); sl.Add('del $$tmp$$.bat'); sl.SaveToFile('$$tmp$$.bat'); finally sl.Free; end; //ShowMessage('Батник готов!'); end; procedure TUpdPrg.BatExec; begin //запуск батника // WinExec('$$tmp$$.bat',SW_SHOW); //запустить в невидимом режиме... if ShellExecute(Application.Handle, 'open', '$$tmp$$.bat', nil, nil, SW_HIDE) < 32 then begin ShowMessage('Не могу запустить команду обновления...') end; end; //====ДИСПЕТЧЕРИЗАЦИЯ СОБЫТИЙ=================================================== procedure TUpdPrg.DispBeforeUpdatePrg; begin //процедура диспетчеризации if Assigned(FOnBeforeUpdatePrg) then FOnBeforeUpdatePrg(Self); end; procedure TUpdPrg.DispAfterUpdatePrg; begin //процедура диспетчеризации if Assigned(FOnAfterUpdatePrg) then FOnAfterUpdatePrg(Self); end; procedure TUpdPrg.DispUpdAutoTime; begin //процедура диспетчеризации if Assigned(FOnUpdAutoTime) then FOnUpdAutoTime(Self); end; //============================================================================== end. |
Сообщ.
#8
,
|
|
|
Цитата Maverick @ {$R CMPUPDPRG.DCR} Ты зачем иконку с компонентом в EXE'шник тянешь?? |