Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Restauration einer paintbox


Geri - Di 23.12.08 03:09
Titel: Restauration einer paintbox
Hallo zusammen

Ich habe eine Komponente TmyPaintBox von TPaintbox abgeleitet, die eine Grafik dargestellt. Wird die Grafik im Programmablauf z.B. von einem aufgerufenen Dialog (z.B. FileOpenDialog) überdeckt, dann wird die Methode TmyPaintBoxpaint aufgerufen und die Grafik neu gezeichnet. Allerdings wird der zuvor überdeckte Bildschirminhalt anschliessend von Windows an eine falsche Stelle kopiert und bestimmte Teile der Grafik erscheinen dann doppelt.

Wenn ich einen Breakpoint auf TmyPaintBox.paint setze, dann kann ich mitverfolgen wie die Paintbox zuerst neu gezeichnet wird, anschliessend allerdings s.w. von Windows der zuvor überdeckte Teil noch an einer falschen Stelle (weiter oben) restauriert wird.

Interessant ist auch, dass der restaurierte Teil nicht einem anderen Teil der Grafik entspricht, die zuvor gar nicht überdeckt war:)

Anbei ein Bild davon.

Habt ihre vielleicht eine Idee wo das Problem liegt?

Beste Grüsse

Geri


Delete - Di 23.12.08 03:17

Was soll man da ohne Quältext dazu sagen? Du hast aber "ganz normal" die Paint-Methode überschrieben, oder?


Geri - Do 25.12.08 23:12

Hallo

Die Komponente überschreibt die Paint-Methode von TPaintBox. Anbei ein Auszug davon. Vielleicht nutzt es was. Wenn ich später TView3D.invalidate() aufrufe, dann wird der Bildschirm richtig restauriert.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
Procedure Paint(); override;

Procedure TView3D.Paint();
Var SavePen:TPen;
    rect: TRect;
    i, j: Integer;
    obj: TGraphBase;
    View3DList: TView3DList;
begin

  SavePen := Canvas.Pen;
  Canvas.Brush.Color := mBackgroundColor;
  rect := ClientRect;
  Canvas.FillRect(rect);

  if not assigned(mProjection3D) then exit;
  // draw View3DLists
  if Assigned(mView3DLists) then
  begin
    if mView3DLists.count > 0 then
    begin
      for i:=0 to mView3DLists.count-1 do
      begin
        View3DList := mView3DLists[i];
        if View3DList.Active = True then
        begin
          if View3DList.Changed then Transform();
          for j:=0 to View3DList.count-1 do
          begin
            obj := View3DList[j];
            obj.Draw(Canvas);
          end;
        end;
      end;
    end;
  end;
...
End;

Beste Grüsse
Geri