Zacinajacy sie scroll w watku

0

Witajcie. Planuje zrobic pasek tekstu cos w stylu "newsow", ktory bedzie przewijal sie w poziomie od prawej do lewej strony. Probujac go zrobic natknolem na dwa dosc wnerwiajace problemy. Zeby calosc zrobic dosc szybko najpierw do wyswietlania kolejnych tektow uzylem konponentu Label ale ten pomimo ustawienia wlasciwosci DoubleBuffered formy na True caly czas migal podczas przewijania wiec zrezygnowalem z niego i uzylem komponentu StaticText. Ten juz nie miga :) ale jest kolejny problem. Podczas przwijania tzn co 10 ms pozycja tekstu zmienia sie o 1 piksel tekst nie przesuwa sie plynnie tylko czasami skacze. Dodam ze czas 10 ms odlicza Timer a zmiana dokonuje sie w obsludze jego przerwania. Probowalem tez zrobic to z wykorzystaniem watku ale z nim jest jeszcze gorzej a chyba powinno byc lepiej. Chcialbym wiec zapytac co jest nie tak i jak ten problem rozwiazac.
Ponizej zamieszczam prosty kod na ktorym testuje ten temat.
Bede wdzieczny za kade info.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Buttons, StdCtrls;

type
  TForm1 = class(TForm)
    SpeedButton1: TSpeedButton;
    SpeedButton2: TSpeedButton;
    Text1: TStaticText;
    procedure FormCreate(Sender: TObject);
    procedure SpeedButton1Click(Sender: TObject);
    procedure SpeedButton2Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TWatek = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;

var
  Form1: TForm1;
  Watek: TWatek;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
Watek:=TWatek.Create(true);
Watek.Priority := tpNormal;
Text1.Left:=Form1.Width;
end;

procedure TWatek.Execute;
begin
 while not Terminated Do
 begin
 if (Form1.Text1.Width+Form1.Text1.Left)<0 then Form1.Text1.Left:=Form1.Width else Form1.Text1.Left:=Form1.Text1.Left-1;
 sleep(10);
 end;
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
Watek.Resume;
end;

procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
Watek.Suspend;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
Watek.Terminate;
Watek.Free;
end;

end.
</delphi>
0

Odwołując się do Form1 używaj Synchronize. Zamiast Sleep'a możesz użyć eventów (WaitFor)

0

sleep nie gwarantuje odczekania dokładnie podanego czasu, zwłaszcza, jeśli akurat w danym momencie inny proces intensywnie korzysta z procesora. poza tym sto klatek na sekundę to lekkie przegięcie, przesuwaj o np. 4 piksele i czekaj 25ms. i tak jak napisał b0bik, nigdy nie modyfikuj właściwości komponentów wizualnych bezpośrednio z poziomu wątku, zawsze używaj synchronize.

0

Oki wstawilem w klasie Thread metode gdzie bedzie odbywac sie synchronizacja

TWatek = class(TThread)
  private
    procedure SetProprties;
  protected
    procedure Execute; override;
  end;

W procedurze Execute watku wstawiam Synchronize(SetProprties);
oraz dopisuje do programu procedure

procedure TWatek.SetProprties;
begin
 if (Form2.Text1.Width+Form2.Text1.Left)<0 then Form2.Text1.Left:=Form2.Width else Form2.Text1.Left:=Form2.Text1.Left-1;
end;

To wszystko niewiele zmienia tzn nadal tekst scrolluje sie ze skokami. Sytuacja troche poprawia sie kiedy nadam wyzszy priorytet watkowi np tpHighest ale jezeli w tym samym czasie uruchomie inny program napisany w Delphi gdzie jest np uzyty komponent DSPack ktorym odtwarzam jakies krotkie filmiki to podczas ladowania kolejnego filmiku scrollowany napis na ulamek sekundy zatrzymuje sie po czym w zaleznosci od tego jak bardzo skompresowany jest filmik, tekst albo scrolluje sie z skokami albo w miare plynnie.
Zastanawia mnie to dlaczego tak sie dzieje bo przeciez taki scrollowany tekst tak malo obciaza procka ze ten bez najmniejszych problemow powinien sobie z nim poradzic i dodatkowo spokojnie obslugiwac inne aplikacje.
Rozwiazanie z zwiekszeniem skoku do 4 piksli i zwiekszeniem parametru sleep do 25 powoduje przesuwanie tekstu z skokami wiec to tez odpada.</delphi>

0

to nie kwestia stopnia skomplikowania Twojego kodu, tylko ogólnego zajęcia całego procesora (a raczej rdzenia, który obsługuje Twój proces) przez wszystkie programy. rdzeń obciążony na 100% - Twój wątek (potrzebujący od cholery przełączeń kontekstu na sekundę) ma kłopoty.

</delphi> ;]

0

Sorki ze dlugo sie nie odzywalem ale w odpowiedzi na na twoja odpowiedz.
Max obciazenie procka w najbardziej ciezkich momentach jest na poziomie 50% wiec sporo jeszcze zostaje.
na pewno jest jakies rozwiazanie tego problemu ale mam jeszcze za mala wiedze z Delphi zeby cos z tym zrobic.

1 użytkowników online, w tym zalogowanych: 0, gości: 1