На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Обязательно выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

Этот раздел предназначен для вопросов, посвященных разработке компонентов, а также для тестирования собственных бесплатных компонентов с открытым исходным кодом.

Здесь запрещается:
1. Размещать ссылки на какие-либо коммерческие компоненты, реализующие требуемую функциональность.
2. Обсуждать и тестировать коммерческие компоненты или компоненты с закрытым кодом.
3. Давать ссылки на сайты с исходным кодом компонентов. Все тестируемые исходные коды должы быть размещены на сайте ИСХОДНИКИ.RU.
Модераторы: Rouse_, DimaBr
  
> Заставить компонент выполнить метод , сразу после CREATE
    Привет... Обрисую проблему...
    Создаю невизуальный компонент.. Унаследовался от TComponent... Скажем, у него есть простое свойство Active и метод Execute... В Execute написано примерно следующее

    ExpandedWrap disabled
      begin
        if FActive then
          begin
              {операторы}
          end;


    так вот... Мне надо чтобы компонент сам, без помощи владельца выполнил Execute после своего создания... Создался и выполнил тут же... Внимание, проблема... если на форме выставить Active=true в Инспекторе объектов и запустить приложение - при подходе к if - FActive имеет значение false, и соответсвенно действия не выполняются...
    Пробовал переопределить AfterConstraction - то же самое, пробовал загнать это дело последним оператором в конструктор - тоже самое, пробовал... ну вообщем много всякой гадости... даже ComponentState проверял...
    Может, кто чего подскажет?
      ExpandedWrap disabled
        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;
      Сообщение отредактировано: s-mike -
        Нет, я так и знал, что в этом дело... просто не хотел ковырять, у меня там свойств типа Active вагон и маленькая тележка, не хотел везде Set прописывать, да видно придется... :wall:
          Цитата Maverick @
          у меня там свойств типа Active вагон и маленькая тележка, не хотел везде Set прописывать

          Но что-то общее среди них есть? Если бы компонент был визуальный, то можно было бы использовать метод CreateWnd. Ну а тут, не зная о назначении и функциональности компонента, трудно сказать о том, как лучше поступить.
            ExpandedWrap disabled
              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;
              Смотря чего он должен делать, в большинстве своем можо напороться на HandleAllocated
                Set понатыкал.... все работает...

                Добавлено
                Вот... Второй в жизни компонент, потому строго не судите... Основная процедура из FAQ форума... Компонент занимается обновлением текущей версии программы... Можно проверять в периоде наличие новых версий... Пока работает только для обновлений из локальной сети... Кидаете, делаете активным, настраивате путь к серверу обновлений, период поиска обновлений, настраиваете степень информирования пользователя - все остальное он делает сам... Сделано для обучения и тренировки... Принимаю замечания, подсказки для доработки... Вагон свойств убрал, было много лишнего...

                ExpandedWrap disabled
                   
                  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.
                Сообщение отредактировано: Maverick -
                  Цитата Maverick @
                  {$R CMPUPDPRG.DCR}

                  Ты зачем иконку с компонентом в EXE'шник тянешь??
                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                  0 пользователей:


                  Рейтинг@Mail.ru
                  [ Script execution time: 0,0313 ]   [ 17 queries used ]   [ Generated: 18.04.24, 08:19 GMT ]