Image znika przy odświeżaniu :/ HELP!

0

Witam serdecznie

Mój problem polega na znikaniu obiektu Image z Formy przy odświeżaniu nową zawartością, przy czym istnieje on tylko przy mniejszych interwałąch, przy większych wszystko działa stabilnie:

bmp = new Graphics::TBitmap;
bmp->Height = Form1->Image1->Height;
bmp->Width = Form1->Image1->Width;

// Thread:

int __fastcall DisplayImage(Pointer Parameter)
{
        do
        {
        /* Draw anything on bmp */
        Form1->Image1->Canvas->Draw(0,0,bmp);
        Sleep(100);
        }
        while(1);

return True;
}

(...)


void __fastcall TForm1::FormCreate(TObject *Sender)
{
DoubleBuffered = true;
}

No i nie mam zielonego pojęcia o co chodzi, jak po chwili działania programu na ekranie pozostaje tylko pusta forma..

0
Form1->DoubleBuffered = true;
0

No niestety wciąż wystepuje ten uciążliwy efekt.

Project raised exception class EInvalidOperation with message:
'Canvas does not allow drawing'

[???]

0

Spróbuj do przechowywania Image'a użyć TImageList.

0

A nie prościej dać to 'mazanie' w timer'a, a nie w wątek???

0
0x666 napisał(a)

A nie prościej dać to 'mazanie' w timer'a, a nie w wątek???

Timery wieszają system. Na timerze to można sobie zrobić aplikacją pt. "Zegar do gotowania jajek" ;)

0
DevilHimself napisał(a)

Timery wieszają system. Na timerze to można sobie zrobić aplikacją pt. "Zegar do gotowania jajek" ;)

Taaa.... :D

0

Wydaje mi sie ze problem dotyczy wszelkich animacji 2D, natomiast to czy stosowany jest wątek czy timer (ktory jest blee) nie ma chyba zadnego wplywu na te sytuacje. Wielkosc obrazka wyswietlanego w formie nie ma znaczenia i znikaja nawet obrazki o kilkunastu pixelach kwadratowych :[

0

[...] natomiast to czy stosowany jest wątek czy timer (ktory jest blee) nie ma chyba zadnego wplywu na te sytuacje.

Nie byłbym tego taki pewny. Jeżeli używasz wątku to musisz zsynchronizować go z głównym procesem. Poczytaj o funkcjach TCanvas::Lock i TCanvas::Unlock. Osobiście nigdy ich nie używałem, ale może coś tam dadzą ;)

0

Właśnie to jest główny proces w aplikacji, natomiast zastosowanie Lock i Unlock nic nie zmienia, sprawdzałęm to już dużo wcześniej ale może jeszcze poczytam na ten temat.

0

Właśnie to jest główny proces w aplikacji [...]

// Thread: <--- TO PO CO TO???

int __fastcall DisplayImage(Pointer Parameter)
...

Jeszcze raz. DisplayImage jest wywoływana w oddzielnym wątku czy w głównym procesie [???] Bo jeżeli to drugie to pętla:

do
{
   /* Draw anything on bmp */
   Form1->Image1->Canvas->Draw(0,0,bmp);
   Sleep(100);
}while(1);

jest raczej "wątpliwa" ;) Próbowałeś może (na próbę) dać:

Form1->Canvas->Draw(0,0,bmp);

[???]

0
do
{
   /* Draw anything on bmp */
   Form1->Image1->Canvas->Draw(0,0,bmp);
   Sleep(100);
}while(1);

Gdzie jest warunek zakończenia pętli [???]

0

No dobrze, problem leży jednak po stronie wątku, bo przy timerze wszystko idzie gladko. Zeby przerwac wykonanie petli wystarczy przeciez zawiesic watek. A co do watku to jest on wywolywany w nst sposob:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
hThread = BeginThread (NULL, 0, DisplayImage, NULL, 0, ThreadID);
}

Jest to jedyny watek w aplikacji. Wyczytalem natomiast na innych forach ze pojawial sie podobny problem, przy czym znikal on w zaleznosci ktorego Delphi uzywala ta osoba [???]

0

No dobrze, problem leży jednak po stronie wątku, bo przy timerze wszystko idzie gladko.

Heh mówiłem, że timer w większości przypadków wystarczy ;)

Zeby przerwac wykonanie petli wystarczy przeciez zawiesic watek.

Niby tak, ale nie jest to dobre rozwiązanie.

Wyczytalem natomiast na innych forach ze pojawial sie podobny problem, przy czym znikal on w zaleznosci ktorego Delphi uzywala ta osoba

Prawdopodobnie kod był tak sobie napisany. Ogólnie, wątki wykorzystuj do operacji, które nie mają bezpośredniego wpływu na GUI aplikacji.

0
0x666 napisał(a)

Zeby przerwac wykonanie petli wystarczy przeciez zawiesic watek.

Niby tak, ale nie jest to dobre rozwiązanie.

To jest LAMERSKIE rozwiązanie. A nie lepiej wsadzić tam w ten "wątek" jakiś rejestr typu bool (oczywiście zabezpieczony przed wielodostępem) i jechać w while dopóki rejestr bedzie na true ?. Bardzo elegancko można wtedy zakończyć wątek np. przez:
Running = false;

0

Jak będę czyścił podłogę w kiblu to nie będę tego robił świeżym ręcznikiem.. Program służy rozwiązaniu konkretnego problemu, póki co wisi mi metoda wychodzenia z pętli, której zresztą w przyszłości tam nie będzie. Dziękuję.

A co do programu myślę że przetestuję opcję, kiedy w wątku zmieniany jest obraz img, a jego wyświetlanie zawarte będzie w timerze. Za każdym wywołaniem timera na ekran wskoczy wtedy kilkanaście odświeżeń obrazka. Timer mimo własnych ustawień i tak zachowuje się znacznie wolniej ze względu na rodzaj wykonywanej operacji.

0
swistaque napisał(a)

Jak będę czyścił podłogę w kiblu to nie będę tego robił świeżym ręcznikiem.. Program służy rozwiązaniu konkretnego problemu, póki co wisi mi metoda wychodzenia z pętli, której zresztą w przyszłości tam nie będzie. Dziękuję.

Proszę bardzo, jednak z takim podejściem to obawiam się że ciągle będziesz czyścił podłoge w kiblu. ;P

Odnośnie Timerów: przy wejściu do procedury obsługi timera ustawiaj Enabled na false.

.....Timer1Timer(TObject *Sender)
{
  Timer1->Enabled = false;
  ...
  ...
  ...
  Timer1->Enabled = true;
};
0

Mimo wszystko przemecze jeszcze temat wątków. Otóż dając dwa identyczne Image i instrukcję wewnątrz wątku:

        Form1->Image1->Canvas->Draw(0,0,bmp);
        Form1->Image2->Canvas->Draw(0,0,bmp);

oraz dodatkowo wstawiając do wykonywanego wątku licznik wyświetlany w Labeli efekty są następujące:

Znika najpierw jeden Image, kiedy na drugim jeszcze wyświetla się właściwa zawartość, a po jakimś czasie, kiedy zniknie również drugi Image, licznik wciąż działa, czyli wątek wykonuje się prawidłowo :-/ Należy również wspomnieć, że znikanie Image'ów bardzo ładnie jest wspomagane przez machanie po nich kursorem [???]

0

Ostatecznie udało mi się wykminić STABILNĄ wersję:


        if(bmp->Canvas->TryLock() == false)
        {
        bmp->Canvas->Lock();
        Form1->Image1->Canvas->Lock();

        Form1->Image1->Canvas->Draw(0,0,bmp);

        bmp->Canvas->Unlock();
        Form1->Image1->Canvas->Unlock();
        }

I wszystko to musi być bo inaczej znowu albo się wiesza wyświetlanie albo znika Image. Dziękuję wszystkim za próby pomocy ;)

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