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.
onPaint Canvas Parameter
- fliegermichl
- Lazarusforum e. V.
- Beiträge: 1436
- Registriert: Do 9. Jun 2011, 09:42
- OS, Lazarus, FPC: Lazarus Fixes FPC Stable
- CPU-Target: 32/64Bit
- Wohnort: Echzell
-
- Beiträge: 2013
- Registriert: Do 16. Okt 2008, 10:22
- OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
- CPU-Target: x86,x64,ARM
Re: onPaint Canvas Parameter
Die MSEgui Haupt-Zeichenfunktion ist
Normalerweise wird twidget.paint() für das top-level-widget von twindow.internalupdate() aufgerufen. twindow.internalupdate() stellt ein canvas-Objekt zur Verfügung.
twidget.paint() ruft die paint() Prozeduren der Kinder unter Weitergabe des canvas Parameters auf:
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
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.
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.
- fliegermichl
- Lazarusforum e. V.
- Beiträge: 1436
- Registriert: Do 9. Jun 2011, 09:42
- OS, Lazarus, FPC: Lazarus Fixes FPC Stable
- CPU-Target: 32/64Bit
- Wohnort: Echzell
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;
Also reicht ja dann das Paintbox.invalidate;