Sie sind nicht angemeldet.

1

Dienstag, 17. November 2020, 12:39

Problem beim codegesteuerten Anzeigen von verschiedenen Bildern

Ich habe in der Menüzeile 2 Trigger, die mir nach Klick jeweils ein Bild (Bitmap) anzeigen. Ich beliebig zwischen den Bildern hin- und herwechseln. Ein 3. Button soll die beiden Bilder nun einmalig nacheinander anzeigen, mit einer kleinen Pause (TimerSleep) dazwischen. In der von Trigger 3 aufgerufenen Methode werden nacheinander die zu den Triggern 1 und 2 gehörenden Methoden aufgerufen. Ergebnis: Es erscheint immer nur das 2. Bild. Wenn ich die Pause vergrössere, erscheint das 2. Bild entsprechend verzögert. Wo liegt mein Denkfehler?

Wilfried

2

Dienstag, 17. November 2020, 15:47

Hallo!

Ich würde auf einen Tippfehler im Code tippen (irgendwo wird das falsche Bild, bzw. der falsche Trigger aufgerufen).
Sonst könnte man noch einen GrInvalRect, bzw. GrInvalRectDWord einbauen, nachdem das erste Bild geladen wurde...

Jörg
:D Most favorite keys by profession: astronauts: space, pirates: enter, German teachers: 6... :D

3

Dienstag, 17. November 2020, 15:51

Oder nach der geplanten Anzeige des ersten Bildes fehlt ein GrEndGString, GrEndPath oder GrEndUpdate oder so...
:D Most favorite keys by profession: astronauts: space, pirates: enter, German teachers: 6... :D

4

Dienstag, 17. November 2020, 17:02

Ich habe an den Methoden, die einzeln vom zugehörigen Trigger aufgerufen werden, ja nichts verändert. Der Unterschied besteht nur darin, dass sie jetzt von einem Trigger nacheinander aufgerufen werden. Wenn ich den Aufruf der 2. Methode auskommentiere, dann erscheint das 1. Bild. Es scheint so zu sein, dass nur angezeigt wird, was zuletzt gezeichnet wird.

Wilfried

5

Dienstag, 17. November 2020, 17:15

Vielleicht dann doch ein GrInvalRect einbauen?! Oder "überschreibst" Du irgendwo MSG_META_EXPOSED?
:D Most favorite keys by profession: astronauts: space, pirates: enter, German teachers: 6... :D

6

Dienstag, 17. November 2020, 20:02

Klingt nach einem Thread-Problem. Poste mal den Code, wie du die Trigger-Handler aufrufts. Und den UI-Code der Trigger.
Gruß
Rainer
Es gibt 10 Arten von Menschen - die einen wissen was binär ist, die anderen nicht.

7

Donnerstag, 19. November 2020, 12:38

@object GenTriggerClass Start = {
GI_visMoniker = 'S', "Start";
GTI_actionMsg = MSG_STARTE_UHR;
GTI_destination = process;
HINT_SEEK_MENU_BAR;
}
@object GenTriggerClass Bild1 = {
GI_visMoniker = '1', "Bild1";
GTI_actionMsg = MSG_BITMAP1_DRAW_TO_DYNAMIC_BITMAP;
GTI_destination = process;
HINT_SEEK_MENU_BAR;
}
@object GenTriggerClass Bild2 = {
GI_visMoniker = '2', "Bild2";
GTI_actionMsg = MSG_BITMAP2_DRAW_TO_DYNAMIC_BITMAP;
GTI_destination = process;
HINT_SEEK_MENU_BAR;
}

@method BitmapProcessClass, MSG_STARTE_UHR
{
@call self::MSG_BITMAP1_DRAW_TO_DYNAMIC_BITMAP();
TimerSleep(100);
@call self::MSG_BITMAP2_DRAW_TO_DYNAMIC_BITMAP();
}
@method BitmapProcessClass, MSG_BITMAP1_DRAW_TO_DYNAMIC_BITMAP
{
VMFileHandle vmfBitmap;
VMBlockHandle vmbBitmap;
GStateHandle gsBitmap;
Bitmap *ptrDoggyBmp;

@call Doggy::MSG_DOGGY_GET_HUGE_BITMAP_INFO(&vmfBitmap, &vmbBitmap, &gsBitmap);

MemLock(OptrToHandle(@doggyBmp));
ptrDoggyBmp = LMemDeref(@doggyBmp);
GrClearBitmap(gsBitmap); //Ki
GrDrawBitmap(gsBitmap, 5, 5, ptrDoggyBmp, 0);
MemUnlock(OptrToHandle(@doggyBmp));

GrDrawVLine(gsBitmap, 29, 29, (DOGGY_HEIGHT-10));

@send Doggy::MSG_VIS_INVALIDATE();
}
@method BitmapProcessClass, MSG_BITMAP2_DRAW_TO_DYNAMIC_BITMAP
{
...
GrDrawHLine(gsBitmap, 29, 29, (DOGGY_WIDTH-10));
...
}

Klick auf Trigger Bild1->Bild1 erscheint, Klick auf Trigger Bild2-> Bild2 erscheint. Beliebig wiederholbar.
Klick auf Trigger Start-> Bild 2 erscheint nach einer kleinen Pause.
Tatsächlich sichtbar wird das Bild durch MSG_VIS_DRAW. Diese Methode sollte ja eigentlich durch @send Doggy::MSG_VIS_INVALIDATE() aufgerufen werden. Wenn ich mit Swat einen Stop in MSG_VIS_DRAW setze und dann im Einzelschrittmodus weitergehe, wird mir das bestätigt. Bei Klick auf Trigger Start erfolgt der Stop aber erst mit der 2. Methode.

Wilfried

8

Donnerstag, 19. November 2020, 15:22

Hmmm... blockiert das MSG_STARTE_UHR vielleicht den UI-Thread?
Kannst Du mal aus dem @send Doggy::MSG_VIS_INVALIDATE(); ein @call Doggy::MSG_VIS_INVALIDATE(); machen, damit "TimerSleep" erst dann startet, wenn das MSG_VIS_INVALIDATE durch ist?
:D Most favorite keys by profession: astronauts: space, pirates: enter, German teachers: 6... :D

9

Donnerstag, 19. November 2020, 16:05

Leider keine Veränderung.

10

Donnerstag, 19. November 2020, 17:35

Versuch doch mal testweise, den Rumpf der Beide DRAW_ Handler in je eine Routine zu packen. Und dann rufst du in Start_uhr die routinen.
Bauchschmerzen habe ich bei der Zeile @call Doggy::.......
Es kann sein, dass sich hier Threads blockieren.
Ich müsste noch mal in das Beispiel sehen, fand das aber damals nicht so toll.


@method BitmapProcessClass, MSG_BITMAP1_DRAW_TO_DYNAMIC_BITMAP
{
DrawBitmap1(...);

}
@method BitmapProcessClass, MSG_STARTE_UHR{
DrawBitmap1(...);
TimerSleep(100);
DrawBitmap2(...);

}Gruß
Rainer
Es gibt 10 Arten von Menschen - die einen wissen was binär ist, die anderen nicht.

11

Donnerstag, 19. November 2020, 17:42

Dann musst Du wohl das TimerSleep ausbauen und das MSG_BITMAP2_DRAW_TO_DYNAMIC_BITMAP() über einen Timer starten...
:D Most favorite keys by profession: astronauts: space, pirates: enter, German teachers: 6... :D

12

Donnerstag, 19. November 2020, 17:53

Also irgendwie so:

//globale Variable:
word timerid;

//neue Methode
@method BitmapProcessClass, MSG_STARTE_UHR
{
@call self::MSG_BITMAP1_DRAW_TO_DYNAMIC_BITMAP();
TimerStart(TIMER_EVENT_ONE_SHOT, oself, 100, MSG_BITMAP2_DRAW_TO_DYNAMIC_BITMAP, 0, &timerid);
}
:D Most favorite keys by profession: astronauts: space, pirates: enter, German teachers: 6... :D

13

Donnerstag, 19. November 2020, 18:08

@Jörg,
nein, vom "Prinzip" her muss es so gehen, wie Wilfried es will.

@Wilfried
Ich erinnere mich, das sich meine ersten Gehversuche zum Thema Bitmap auch mit diesem Beipiel begonnen habe. Aber das Beispiel ist einfach nur grottig. Vielleicht ist es gut, wenn man Objektorientiert mit VisObjekten und (einfachen) Bitmaps arbeiten will.

Ich häng mal was dran.
1. eine modifizierte Doggy-Bitmap variante und 2. ein BMP-Game, das genau das macht, was du willst - aber natürlich viel komplexer ist.

Gruß


Rainer
P.S.
erstezt doch mal dein MSG_VIS_INVALIDATE durch
@call Doggy::MSG_VIS_MARK_INVALID(VOF_GEOMETRY_INVALID | VOF_IMAGE_INVALID, VUM_NOW);
»Rainer« hat folgende Dateien angehängt:
  • bitm_modi.zip (5,13 kB - 92 mal heruntergeladen - zuletzt: Heute, 13:48)
  • BMPGAMSR.ZIP (29,27 kB - 92 mal heruntergeladen - zuletzt: Heute, 12:01)
Es gibt 10 Arten von Menschen - die einen wissen was binär ist, die anderen nicht.

14

Freitag, 20. November 2020, 16:53

Hallo Rainer,

zuerst mal vielen Dank für deine Mühe!

Dein BMPGAMSR ist mir tatsächlich viel zu komplex, um es gleich zu verstehen, dein modifiziertes Doggy-Bitmap dagegen habe ich verstanden :) .

Trotzdem wollte ich wissen, warum meine Version nicht wie gewünscht funktioniert. Ich habe mit Swat herausgefunden, dass @call Doggy::MSG_VIS_INVALIDATE erst zur Wirkung kommt, wenn alle Methoden abgeschlossen sind. Dann wird der letzte Stand der Bitmap angezeigt. Keine Ahnung, warum das so ist.

In deiner Version bin ich auf @call Doggy::MSG_VIS_REDRAW_ENTIRE_OBJECT gestoßen und habe @call Doggy::MSG_VIS_INVALIDATE damit ersetzt. Und siehe da: Jetzt funktioniert meine Version wie gewünscht! :) :)



Wilfried

Ergänzung: MSG_VIS_MARK_INVALID(VOF_GEOMETRY_INVALID | VOF_IMAGE_INVALID, VUM_NOW) wirkt auch nicht.

15

Freitag, 20. November 2020, 21:08

Hallo Wilfried,
ich hab keine Ahnung, warm deins nicht geht. Meine Vermutung ist, dass MSG_VIS_INVALIDATE nur das Objekt als "geändert" markiert, aber kein "visual update" (neuzeichnen) auslöst. Das passiert offensichtlich erst, wenn "alles fertig" ist. Der ganze Mechanismus ist so komplex, dass ich ihn konzeptionell nicht verstanden habe. Deswegen habe ich einfache Wege gesucht, Bitmaps darzustellen und schließlich auch gefunden.
Wenn ich eine Uhr via Bitmap programmieren wollte, würde ich auf keinen Fall ein VisObject nehmen, sondern das VisContent selbst die Bitmap darstellen lassen, z.B. via MSG_VIS_REDRAW_ENTIRE_OBJECT. Damit vereinfachst du vieles.
Gruß
Rainer
Es gibt 10 Arten von Menschen - die einen wissen was binär ist, die anderen nicht.

Zur Zeit ist neben Ihnen 1 Benutzer in diesem Thema unterwegs:

1 Besucher

Ähnliche Themen

Thema bewerten