Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > проблема при создании компонентов одного типа


Автор: Демидрол 16.9.2008, 14:24
доброго всем времени суток.
Столкнулся с такой проблемой:ранее создал компонент "бегущая строка" на основе TLabel.
Все было хорошо,просто отлично до тех пор,пока не додумался на форму поместить два таких компонента:если один работает,то почему бы и двум одновременно тоже.Но нет,не тут-то было.
Проблема состоит в следующем:при запуске программы обе строки начинают почему-то бежать со скоростью,выше заданной,причем если задать у обоих разные скорости,то бежать они будут с наибольшей.Причем,если задать в них строки разной длины,то как только пробегает короткая строка и начинает выбегать с другой стороны,то длинная,так и не убежав,пропадает и начинает вместе с короткой выбегать с другой стороны.Но если хотя бы одну из них остановить,вызвав метод остановки,то другая начнет вести себя совершенно нормально.
Помогите,пожалуйста, решить эту проблему, потому как я в диком замешательстве. smile 

Вот код:
TRunningLabel.cpp
Код

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include "TRunningLabel.h"
#pragma package(smart_init)

//------------------------------------------------------------------------------
#define DEFAULT_TIMER_INTERVAL 35

//------------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//

static inline void ValidCtrCheck(TRunningLabel *)
{
        new TRunningLabel(NULL);
}
//------------------------------------------------------------------------------
__fastcall TRunningLabel::TRunningLabel(TComponent* Owner)
        : TLabel(Owner)
{
     FTimer = new TTimer(NULL);
     FTimer->OnTimer = TimerFired;
     FTimer->Enabled = false;
     FTimer->Interval = DEFAULT_TIMER_INTERVAL;
     PS = 2;
     Stop = true;
     Scroll = true;
     AutoSize = false;
}

//------------------------------------------------------------------------------
namespace Trunninglabel
{
        void __fastcall PACKAGE Register()
        {
                 TComponentClass classes[1] = {__classid(TRunningLabel)};
                 RegisterComponents("MyComponents", classes, 0);
        }
}

//------------------------------------------------------------------------------
void __fastcall TRunningLabel::StartCreep()
{
     FOrigCaption = Caption;
     if ( Caption != NULL ) {
        FTimer->Enabled = true;
        TimerFired( this );
     }
     Stop = false;
}

//------------------------------------------------------------------------------
void __fastcall TRunningLabel::StopCreep()
{
     FTimer->Enabled = false;
     Stop = true;
     TimerFired(this);
}

//------------------------------------------------------------------------------
void __fastcall TRunningLabel::ClearCanvas (System::TObject* Sender)
{
     TRect  FillRect;

     Canvas->Brush->Color = Color;

     FillRect.Left   = 0;
     FillRect.Top    = 0;
     FillRect.Right  = Width;
     FillRect.Bottom = Canvas->TextHeight(FOrigCaption);
     Canvas->FillRect( FillRect );
}

//------------------------------------------------------------------------------
void __fastcall TRunningLabel::TimerFired (System::TObject* Sender)
{
     static int Xcoord;
     if ( Stop ) { Xcoord= 0; }

     //if ( GetTextWidth( Sender, FOrigCaption ) >= Width )
     //{
        ClearCanvas( NULL);//Sender );
        Canvas->TextOutA( Xcoord, 0, FOrigCaption  );

        Xcoord -= PS;

        if ( -Xcoord >= GetTextWidth( Sender, FOrigCaption ) )
        {
           Xcoord = Width;
        }
      //}
}

//------------------------------------------------------------------------------
int __fastcall TRunningLabel::GetTextWidth (System::TObject* Sender, AnsiString Text)
{
     return ( Canvas->TextExtent( Text ).cx );
}

//------------------------------------------------------------------------------
int __fastcall  TRunningLabel::GetTimerSpeed()
{
     return FTimer->Interval;
}

//------------------------------------------------------------------------------
void __fastcall  TRunningLabel::SetTimerSpeed( int Value )
{
     FTimer->Interval = Value;
}

//------------------------------------------------------------------------------
AnsiString __fastcall TRunningLabel::GetCaption()
{
     return TLabel::Caption;
}

//------------------------------------------------------------------------------
void __fastcall TRunningLabel::SetCaption( AnsiString ACaption )
{
     TLabel::Caption = ACaption;
}

//------------------------------------------------------------------------------
int __fastcall TRunningLabel::GetPixelSpeed ()
{
     return PS;
}

//------------------------------------------------------------------------------
void __fastcall TRunningLabel::SetPixelSpeed ( int Value )
{
     PS = Value;
}

//------------------------------------------------------------------------------
bool __fastcall TRunningLabel::GetExtendText()
{
    if ( Canvas->TextWidth( FOrigCaption ) > Width ) {
       return true;
    }
    else {
       return false;
    }
}

//------------------------------------------------------------------------------
bool __fastcall TRunningLabel::GetScrollingText()
{
     return Scroll;
}

//------------------------------------------------------------------------------
void __fastcall TRunningLabel::SetScrollingText ( bool Value )
{
     Scroll = Value;
     if ( Value ) {
        StartCreep();
     }
     else {
        StopCreep();
     }

}

//------------------------------------------------------------------------------




TRunningLabel.h
Код

//---------------------------------------------------------------------------

#ifndef TRunningLabelH
#define TRunningLabelH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
//---------------------------------------------------------------------------
class PACKAGE TRunningLabel : public TLabel
{
private:
     TTimer* FTimer;
     TRect  FillRect;
     AnsiString FOrigCaption, FCaption;
     int PS;
     bool Stop;
     bool Scroll;

protected:
     int        __fastcall GetTextWidth (System::TObject* Sender, AnsiString Text);
     int        __fastcall GetTimerSpeed();
     int        __fastcall GetPixelSpeed();
     AnsiString __fastcall GetCaption();
     bool       __fastcall GetExtendText();
     bool       __fastcall GetScrollingText();
     void       __fastcall SetTimerSpeed( int Value );
     void       __fastcall SetPixelSpeed ( int Value );
     void       __fastcall SetCaption( AnsiString ACaption );
     void       __fastcall SetScrollingText (bool Value);


public:
     __fastcall TRunningLabel(TComponent* Owner);
     __fastcall ~TRunningLabel() { delete FTimer; }
     void __fastcall TimerFired( System::TObject* Sender );
     void __fastcall ClearCanvas(System::TObject* Sender);
     void __fastcall StartCreep();
     void __fastcall StopCreep();

__published:
     __property int        TimerSpeed = { read = GetTimerSpeed, write = SetTimerSpeed };///interval
     __property int        PixelSpeed = { read = GetPixelSpeed, write = SetPixelSpeed, default = 2};
     __property AnsiString Caption = { read = GetCaption, write = SetCaption };
     __property bool       ScrollingText = { read = GetScrollingText, write = SetScrollingText };
     __property bool       ExtendText = { read = GetExtendText };

};
//---------------------------------------------------------------------------
#endif


Автор: Vyacheslav 16.9.2008, 19:27
Настораживает вот это
Код

void __fastcall TRunningLabel::TimerFired (System::TObject* Sender)
{
     static int Xcoord;


Вы отдаете себе отчет, что переменная Xcoord - общая для всех экземпляров?

Автор: Демидрол 17.9.2008, 08:02
мммммм... smile 
и как же тогда быть?
в этом методе нужна переменная,которая сохраняет свое значение при выходе из функции и при повторном вызове этой функции необходимо использовать сохраненное значение .А если сделать ее не static, то как же тогда выйти из этой ситуации?

Автор: orthrus 17.9.2008, 08:32
Запиши ее тогда в описании класса
Код

class PACKAGE TRunningLabel : public TLabel
{
private:
     TTimer* FTimer;
     TRect  FillRect;
     AnsiString FOrigCaption, FCaption;
     int PS;
     bool Stop;
     bool Scroll;
     int Xcoord; // <<-- вот эта переменная
  ...

а из метода TimerFired удали ее

Автор: Демидрол 17.9.2008, 09:24
я так и сделал....Спасибо БОЛЬШОЕ!!!
впредь буду осмотрительнее!!!
еще раз БОЛЬШОЕ спасибо!!!!  smile  smile  smile  smile  smile  smile  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)