Bitmap über TImage 'laufen' lassen, zu schnell für TTimer???
-
Moin Gemeinde,
wie kann ich das im Titel beschriebene realisieren? Also das mit dem 'laufen lassen' des BMP's ist kein Problem, funzt wunderbar.
Nur soll die Geschwindigkeit einstellbar sein, und hier liegt das Problem.
Geschwindigkeit zwischen 10 und 150 ms! Und das packt der TTimer nicht mehr. Unterhalb 40 ms ist keine Geschwindigkeitsänderung mehr feststellbar
Und das auch mit Sleep bzw. SleepEx.while( spRun ) { Application->ProcessMessages(); spImage->Picture->Bitmap->Canvas->Draw( xOrigin, y, tempBMP ); ::SleepEx( prvSpeed, true ); ... hier noch Tests ob neu gestartet werden muss ...
Image Size ist fest, BMP Size ist ~600 x 20 px. Breite kann aber auch > 2000 px sein.
Das BMP 'läuft' in einem Tel des Images, also z. B. im Bereich Rect 40, 40, 100, 80.
K. A. ob das stimmt, ist aber auch nur zur Verdeutlichung.Mit o. g. Code läuft es auf meinem Arbeitsrechner noch gut( wohlwollend betrachtet ), auf anderen Rechnern nicht.
Also ab ~50 ms und darunter wirds übel.
Was gibts da für Möglichkeiten? Soll nach Möglichkeit einfach - und im BCB Bereich - bleiben.
*edit: Threads probiert, jedoch nicht das erhoffte Ergebnis
*
Fishing for Ideas
Danke schonmal & grüssle
-
Hallo
TTimer ist in der Tat nicht in der Lage, Intervalle unter ca. 30 ms präzise abzuarbeiten. Das liegt an der zugrundeliegendem Windows-Funktionalität, der Builder ist nicht schuldig.
Mit einer korrekten Verwendung von TThread sollte das machbar sein, "nicht das erhoffte Ergebnis" ist aber keine ausreichende Fehlerbeschreibung.bis bald
akari
-
akari schrieb:
Hallo
TTimer ist in der Tat nicht in der Lage, Intervalle unter ca. 30 ms präzise abzuarbeiten. Das liegt an der zugrundeliegendem Windows-Funktionalität, der Builder ist nicht schuldig.
Mit einer korrekten Verwendung von TThread sollte das machbar sein, "nicht das erhoffte Ergebnis" ist aber keine ausreichende Fehlerbeschreibung.bis bald
akariNaja, mit Thread ist das Timing auch nicht so wirklich gleichmässig steuerbar.
Direkt in ein TImage zeichnen ist auch nicht wirklich optimal.
Bei mir geht es flüssiger in einer TGraphicControl- Komponente. das Bild wird als OffScreen erzeugt und in die Komponente kopiert bei OnPaint().Gruss
Frank
-
akari schrieb:
Hallo
TTimer ist in der Tat nicht in der Lage, Intervalle unter ca. 30 ms präzise abzuarbeiten. Das liegt an der zugrundeliegendem Windows-Funktionalität, der Builder ist nicht schuldig.
is klar, liegt wohl in erster Linie an der System Clock, bzw. deren Resolution. Nur kann diese eben nicht mal einfach so softwaremässig 'nachgebessert' werden.
akari schrieb:
Hallo
Mit einer korrekten Verwendung von TThread sollte das machbar sein, "nicht das erhoffte Ergebnis" ist aber keine ausreichende Fehlerbeschreibung.bis bald
akariIch denke doch, da das Kernproblem die Ausführungsgeschwindigkeit ist. Und da ändert sich auch mit einem Thread - bei mir zumindest - nix
Aber wahrscheinlich liegt der Fehler in 'meiner' Verwendung des Thread's?! Habe noch nicht mit TThread gearbeitet.
Kleines CodeSample übrig? Kann auch Pseudocode sein.Thx für alles.
grüssle
-
Hallo,
Smitty schrieb:
[...]Habe noch nicht mit TThread gearbeitet.
Kleines CodeSample übrig? Kann auch Pseudocode sein.Das Forum ist randvoll von Themen zu Threads (Suchfunktion) und ein Tutorial gibts auch - ich würde fast wetten, dass sogar dein Problem in ähnlicher Form schon behandelt wurde...
MfG
-
Kolumbus schrieb:
Hallo,
Smitty schrieb:
[...]Habe noch nicht mit TThread gearbeitet.
Kleines CodeSample übrig? Kann auch Pseudocode sein.Das Forum ist randvoll von Themen zu Threads (Suchfunktion) und ein Tutorial gibts auch - ich würde fast wetten, dass sogar dein Problem in ähnlicher Form schon behandelt wurde...
MfG
leider nein, es sei denn ich habs übersehen. Würde mich ärgern, hab nämlich lange gesucht.
Naja, nochmal von vorn
grüssle
-
Hallo,
ein kurzes Threadbeispiel ausgehend vom BCB 6 (Englisch):
1. Threadobjekt erstellen
File -> New -> Other -> Thread Object auswählen und einen Namen für das Objekt vergeben. Ich habe es mal TMyThread genannt.
2. Thread erzeugen // starten
Im Header der Form:
private: TMyThread *MyThread;
In der CPP der Form:
// Die Stelle an der der Thread gestartet werden soll. MyThread = new TMyThread(false); //false -> gibt an dass der thread sofort gestartet werden soll...
3. Der Thread (Innenleben)
Ich habe hier ein einfaches Beispiel erstellt, in dem der Thread (ohne Zeitunterbrechung) eine variable hochzählt und diese in einem TLabel im "Parent-Form" anzeigt
Im Header des Thread Objekts:
private: int i; // Die Zählervariable protected: void __fastcall Execute(); // entscheidende Threadfunktion void __fastcall UpdateCaption(); // Funktion zum Synchronisieren mit "parent-form" public: bool IsActive;
Und nun die CPP des Thread Objektes
__fastcall TMyThread::TMyThread(cool CreateSuspended) : TThread(CreateSuspended) { i = 0; IsActive = true; } void __fastcall TMyThread::Execute() { // Hier kommt der Code rein, welcher beim laufenden Thread ausgeführt werden soll... while (IsActive) { i++; Synchronize(UpdateCaption); // Synchronisiert das "parent-form" über die UpdateCaption Funktion } } void __fastcall TMyThread::UpdateCaption() { Form1->Label1->Caption = IntToStr(i); }
4. Thread stoppen
Ein Thread kann - meines Wissens nach - nur gestoppt werden, wenn er nicht läuft. Dafür habe ich im Thread die Variable "IsActive" deklariert. Wenn man den Thread nun (im wahrsten Sinne des Wortes) töten will, muss man selbige Variable auf "false" setzen. Dann unterbricht der Thread den Ablauf und man kann ihn abschießen (while (IsActive))
Ich habe das in meinem Zählerbeispiel mal folgendermaßen gelöst:
Die CPP der Form
void __fastcall TForm1::Button1Click(TObject *Sender) { if (MyThread) { MyThread->IsActive = false; delete MyThread; MyThread = NULL; } else { MyThread = new TMyThread(false); } }
LG, Micha
-
BIG THX RA85, werds testen, sobald ich Zeit habe.
grüssle