Einzelnen Beitrag anzeigen

Benutzerbild von TERWI
TERWI

Registriert seit: 29. Mär 2008
Ort: D-49626
378 Beiträge
 
Delphi 11 Alexandria
 
#45

AW: Bitmap.Canvas -> Form.Canvas ... nix zu sehen

  Alt 17. Jul 2018, 13:19
Das mit den Handles zuweisen hat hier auch nur bedingt geklappt. Der Effekt wie bei meinen weiteren Versuchen:
Die Anzeige kommt, keine Fehler - aber irgendwann friert das OSD ein, obwohl der Datenstrom / Generierung der Quell-BitMap weiter läuft.

Synchronize kann ich hier nicht nutzen, weil ich (im eigentlichen Programm) nicht explizit einen Thread selbst mache, sondern der Thread-Kontext offensichtlich durch den Direct-Show-Filter (Data-Sink Transport-Stream) ensteht - ich habe jedenfalls verschiedene Thread-IDs.

Mittlerweile scheint es dauerhaft (!?) zu funzen. Was hab ich für "Safe" geändert ?
Aufruf des OSD aus dem Parser:
Delphi-Quellcode:
procedure TOSD_data.OnReceiveData(Counter : DWORD);
begin
  if NOT FEnable then exit;
  FormMain.lbl_CountData.Caption := inttostr(FCount); // Visualisierungs-Krücke
  _TextOut(0, 0, inttostr(Counter));
  FOutputCS.Enter;
  try
    FormOSD.OSDUpdate(FBMOSD);
  finally
    FOutputCS.Leave;
  end;
  inc(FCount);
end;
Zuweisung des Image im OSD:
Delphi-Quellcode:
procedure TFormOSD.OSDupdate(BM : TBitMap);
begin
  if NOT Visible then exit;
  FormMain.lbl_CountOSD.Caption := inttostr(FCount); // Visualisierungs-Krücke
  inc(FCount);
  FInputCS.Enter;
  try
    if Assigned(BM) then
      Image.Picture.Bitmap.Assign(BM);
  finally
    FInputCS.Leave;
  end;
end;
Das läuft nun tadellos ohne Exception (auch vorher noch nie) oder Hänger auch über Nacht. Ob ich den Rechner anderweitig stresse, scheint keine Rolle zu spielen.

Ich hab mein komplexes Projekt mal stark vereinfacht und als Anhang mit EXE beigefügt. Das ganze funktioniert wie folgt, besteht aus
- Form Main:
mit 3 Buttons (als Toggle) und 3 Labels zur "Visualisierung".
Dazu hilfsweise ein Thread, der den Datenstrom simuliert. Hier wird einfach nur ein Counter hochgezählt. Die Wiederholrate ist hier mit Sleep(Randomzahl) zwischen 50 und 250 ms angelegt, damit das "wie in echt" zufällig ist.

- Unit OSD_Data:
Entspricht meinem Daten-Parser. Wird getriggert durch den Thread und bekommt die forlaufende Zahl, welche einfach nur ein eine (formatierte) BitMap geschrieben wird.
Ein weiterer interner Zähler (<= Thread-Counter) zählt die Aufrufe mit, wenn solange der Parser aktiv (mitlesen) ist.
"Enable" und "ShowData" wird von der Main-Form gesteuert.

- Form OSD:
Ist einfach nur eine Anzeige der fortlaufend generierten Parser-Bitmap und wird indirekt von der Main-Form über den Parser/OSD-Data gesteuert. D. h., ausschliesslich der Parser greift (direkt) auf diese Form zu.
Aufruf von OSD_Show zeigt die Form an oder schliesst diese, OSD_Update "assigned" die Parser-Bitmap auf das interne Image.

Funktion der Buttons:
Sind als Toggle ausgelegt, d.h. Klick -> aus, Klick -> an usw.

- Start/Stop Source
Startet/pausiert den Thread. Das Label neben dem Button zeigt die generierte, fortlaufende Zahl an.
Hat der Thread (Daten-Strom) Pause, passiert logo nix im Parser und OSD.

- Start/Stop Parser:
Wie Button "Start/Stop Source". Im eigentlichen Programm dient das zum Ein-/Ausschalten des Hintergrund-Monitoring/Datemsammeln (auch ohne OSD).
Das Label zum Button zeigt die tatsächlich gelesenen "Datenpakete" an.

- Start/Stop OSD:
Wie Button "Start/Stop Source". OSD_Show intialisiert jedes mal das Image in grün mit "Hello World !".
Solange Source und Parser auf STOP sind, passiert nix. Bei OSD_update wird das Image rot mit der aktuellen Zahl der Source-Threads.

Erstellt mit Delphi 2009 auf Win 8.1.
Angehängte Dateien
Dateityp: zip OSD_Test.zip (275,1 KB, 6x aufgerufen)
  Mit Zitat antworten Zitat