onPaint Canvas Parameter

Forum für alles rund um die MSEide und MSEgui

onPaint Canvas Parameter

Beitragvon fliegermichl » 8. Nov 2017, 11:47 onPaint Canvas Parameter

Ich komme schon ganz gut voran. Meine Hauptunit cadtypes.pas mit fast 60000 Zeilen compiliert schon in der mseide.
Jetzt stecke ich beim zeichnen fest.

Der Event TPaintbox.onPaint verlangt einen Parameter Canvas. Die Paintbox hat aber gar keinen Canvas.

Da habe ich wohl noch ein grundsätzliches Verständnisproblem.
fliegermichl
 
Beiträge: 145
Registriert: 9. Jun 2011, 08:42

Beitragvon mse » 8. Nov 2017, 13:46 Re: onPaint Canvas Parameter

Die MSEgui Haupt-Zeichenfunktion ist
Code: Alles auswählen
 
 twidget = class(tactcomponent,iscrollframe,iface,iassistiveclient)
[...]
   procedure paint(const canvas: tcanvas); virtual;
 

Normalerweise wird twidget.paint() für das top-level-widget von twindow.internalupdate() aufgerufen. twindow.internalupdate() stellt ein canvas-Objekt zur Verfügung.
Code: Alles auswählen
 
function twindow.internalupdate: boolean; //false if nothing is painted
var
 bo1: boolean;
 bmp: tbitmap;
 rect1: rectty;
 po1: pointty;
 reg1: regionty;
begin
 result:= false;
 if (ws_visible in fownerwidget.fwidgetstate) and (fupdateregion.region <> 0) then begin
  checkwindow(false); //ev. reposition window
  fcanvas.reset;
  fcanvas.clipregion:= fupdateregion.region; //canvas owns the region
  {
  bo1:= appinst.caret.islinkedto(fcanvas) and
   testintersectrect(fcanvas.clipbox,appinst.caret.rootcliprect);
  }

  bo1:= false;
  if appinst.caret.islinkedto(fcanvas) and appinst.fcaret.active and
      testintersectrect(fcanvas.clipbox,appinst.caret.rootcliprect) then begin
   reg1:= fcanvas.copyclipregion;
   fcanvas.regintersectrect(reg1,appinst.caret.rootcliprect);
   bo1:= not fcanvas.regionisempty(reg1);
   fcanvas.destroyregion(reg1);
   if bo1 then begin
    tcaret1(appinst.fcaret).remove;
   end;
  end;
  include(fstate,tws_painting);
  if flushgdi then begin
   try
    fupdateregion.region:= 0;
    result:= true;
    fownerwidget.paint(fcanvas);
   finally
    if bo1 then begin
     tcaret1(appinst.fcaret).restore;
    end;
    fcanvas.endpaint;
   end;
  end
  else begin
   bmp:= tbitmap.create(bmk_rgb,fgdi);
   try
    if intersectrect(fcanvas.clipbox,
            makerect(nullpoint,fownerwidget.widgetrect.size),rect1) then begin
     bmp.size:= rect1.size;
     bmp.canvas.clipregion:= bmp.canvas.createregion(fupdateregion.region);
     po1.x:= -rect1.x;
     po1.y:= -rect1.y;
     tcanvas1(bmp.canvas).setcliporigin(po1);
     bmp.canvas.origin:= nullpoint;
     fupdateregion.region:= 0;
     result:= true;
     fownerwidget.paint(bmp.canvas);
     bmp.paint(fcanvas,rect1);
    end
    else begin
     fupdateregion.region:= 0;
    end;
   finally
    bmp.Free;
    if bo1 then begin
     tcaret1(appinst.fcaret).restore;
    end;
   end;
  end;
  exclude(fstate,tws_painting);
 end;
 

twidget.paint() ruft die paint() Prozeduren der Kinder unter Weitergabe des canvas Parameters auf:
Code: Alles auswählen
 
procedure twidget.paint(const canvas: tcanvas);
[...]
 if (widgetcount > 0) then begin
  if (fframe <> nil) and not (ow_nochildpaintclip in foptionswidget) then begin
   fframe.checkstate;
   canvas.intersectcliprect(fframe.fpaintrect);
  end;
  rect1:= canvas.clipbox;
  for int1:= 0 to widgetcount-1 do begin
   widget1:= twidget(fwidgets[int1]);
   with widget1 do begin
    if isvisible and testintersectrect(rect1,fwidgetrect) then begin
     saveindex:= canvas.save;
     if not (ow_nochildclipsiblings in self.foptionswidget) then begin
      for int2:= int1 + 1 to self.widgetcount - 1 do begin
       with self.fwidgets[int2],tcanvas1(canvas) do begin
        if visible and testintersectrect(widget1.fwidgetrect,fwidgetrect) then begin
             //clip higher level siblings
         if (ws_opaque in fwidgetstate) then begin
          subcliprect(fwidgetrect);
         end
         else begin
          reg1:= msegui.createregion(self.window.fgdi);
          addopaquechildren(reg1);
          subclipregion(reg1.region);
          msegui.destroyregion(reg1);
         end;
        end;
       end;
      end;
     end;
     if not canvas.clipregionisempty then begin
      canvas.move(fwidgetrect.pos);
      paint(canvas);
     end;
     canvas.restore(saveindex);
    end;
   end;
  end;
 end;
[...]
 

Um ein Neuzeichnen der tpaintbox auszulösen, rufe "tpaintbox.invalidate()" auf, MSEgui kümmert sich dann um den Rest.
Soll ein twidget in eine bitmap gezeichnet werden, kann
Code: Alles auswählen
 
 <twidget>.paint(<tbitmap>.canvas);
 

verwendet werden. Die Printer Komponenten besitzen ebenfalls eine canvas Property.
Falls ein tcanvas Objekt ausserhalb der paint()-Prozedur benötigt wird, z.B. zur Berechnung von Textabmessungen, gibt es "twidget.getcanvas()". "twidget.getcanvas()" sollte nicht zum Zeichnen verwendet werden.
mse
 
Beiträge: 1713
Registriert: 16. Okt 2008, 09:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.4.2,git master FPC 3.0,fixes_3_0) | 
CPU-Target: x86,x64,ARM
Nach oben

Beitragvon fliegermichl » 8. Nov 2017, 13:58 Re: onPaint Canvas Parameter

Danke, ich brauchte es nur um die Paintbox neu zeichnen zu lassen, wenn eine CAD Komponente verändert wurde.
Also reicht ja dann das Paintbox.invalidate;
fliegermichl
 
Beiträge: 145
Registriert: 9. Jun 2011, 08:42

• Themenende •

Zurück zu MSEide und MSEgui



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

porpoises-institution
accuracy-worried