Link to home
Start Free TrialLog in
Avatar of Paul Sinnema
Paul Sinnema

asked on

Delphi Component doesn't fire Paint at runtime

I'm a bit frustrated. The documentation tells me how to create a Graphical component but when I implement that it doesn't work. I've written the code below. Can anyone tell me why the Paint procedure isn't fired at runtime but is at designtime?

unit Meta;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  TMeta = class(TGraphicControl)
  private
    { Private declarations }
    FOnPaint:     TNotifyEvent;
  protected
    { Protected declarations }
          procedure          Paint; override;
       property          OnPaint:     TNotifyEvent read FOnPaint write FOnPaint;
  public
    { Public declarations }
          constructor          Create(Owner: TComponent); override;
          destructor          Destroy; override;
  published
    { Published declarations }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('MyComponents', [TMeta]);
end;

constructor     TMeta.Create(Owner: TComponent);
begin
     inherited     Create(Owner);
end;

destructor          TMeta.Destroy;
begin
     inherited     Destroy;
end;

procedure          TMeta.Paint;
var
     MyMetaFile:     TMetafile;
   I:     Integer;
begin
//   if not ( csDesigning in ComponentState ) then
   begin
        MyMetafile                := TMetafile.Create;
             MyMetafile.Width      := self.Width;
          MyMetafile.Height      := self.Height;

             with TMetafileCanvas.Create(MyMetafile, 0) do
             try
                  Brush.Color := clRed;

               for I := 0 to 100 do
                      Ellipse(I+3,I+3,I+100,I+100);
             finally
                  Free;
             end;

        self.Canvas.Draw(0,0,MyMetafile);  (* 100 red circle's  *)
    end;
end;

end.
Avatar of bugroger
bugroger

Hi,

Use this definition and add
"Inherited paint;" -> calls TGraphicControl().paint
at the first line of your paint function

type
 TMeta = class(TGraphicControl)
 private
   { Private declarations }
 protected
   { Protected declarations }
         procedure          Paint; override;
 public
   { Public declarations }
         constructor          Create(Owner: TComponent); override;
         destructor          Destroy; override;
 published
   { Published declarations }
 end;


procedure          TMeta.Paint;
var
    MyMetaFile:     TMetafile;
  I:     Integer;
begin
 Inherited Paint;
 ....
 ...
 ..
end;

GL
 bug
Avatar of kretzschmar
maybe you should call inherited once, before or after your code
hi bugroger, same idea :-)
Avatar of Paul Sinnema

ASKER

Boy, are you guys fast!

No, doesn't work. Still get no painting at runtime. Had already tried that myself. The problem is that the Paint Method isn't fired at. I even put in a MessageBox just to see what happens. At design time a get the messagebox at runtime I don't.

Paul
Boy, are you guys fast!

No, doesn't work. Still get no painting at runtime. Had already tried that myself. The problem is that the Paint Method isn't fired at. I even put in a MessageBox just to see what happens. At design time a get the messagebox at runtime I don't.

Paul

Does your current code have the "//" ?
//   if not ( csDesigning in ComponentState ) then
If i tried this code and it works fine:


Unit Meta;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
 TMeta = class(TGraphicControl)
 private
   { Private declarations }
 protected
   { Protected declarations }
   procedure          Paint; override;
 public
   { Public declarations }
    constructor         Create(Owner: TComponent); override;
    destructor          Destroy; override;
 published
   { Published declarations }
 end;

procedure Register;

implementation

procedure Register;
begin
 RegisterComponents('MyComponents', [TMeta]);
end;

constructor     TMeta.Create(Owner: TComponent);
begin
    inherited     Create(Owner);
end;

destructor          TMeta.Destroy;
begin
    inherited     Destroy;
end;

procedure          TMeta.Paint;
var
  MyMetaFile:     TMetafile;
  I:     Integer;
begin
  if not ( csDesigning in ComponentState ) then
  begin
       MyMetafile                := TMetafile.Create;
            MyMetafile.Width      := self.Width;
         MyMetafile.Height      := self.Height;

            with TMetafileCanvas.Create(MyMetafile, 0) do
            try
                 Brush.Color := clRed;

              for I := 0 to 100 do
                     Ellipse(I+3,I+3,I+100,I+100);
            finally
                 Free;
            end;

       self.Canvas.Draw(0,0,MyMetafile);  (* 100 red circle's  *)
   end;
end;

end.
yes, the // are in the code. So the drawing should be in both runtime and designtime.

What operating system are you on. I use windows 2000 professional. Could that make a difference? It doesn't work with me?
I'm using Windows 98
What version of Delphi do you have?
I have Delphi 5.

You can try to put a TImage component onto your form.
If it won' t be painted then you have a problem but
when it works you can try this Paint - code.
Also have a look at TImage.Paint !!!

procedure TMeta.Paint;
var
 MyMetaFile :     TMetafile;
 I          :     Integer;
begin
 with inherited Canvas do
 begin
  MyMetafile        := TMetafile.Create;
  MyMetafile.Width  := self.Width;
  MyMetafile.Height := self.Height;

   with TMetafileCanvas.Create(MyMetafile, 0) do
  try
   Brush.Color := clRed;

   for I := 0 to 100 do Ellipse(I+3,I+3,I+100,I+100);
  finally
   Free;
  end;
    Draw(0,0,MyMetafile);  (* 100 red circle's  *)
  end;
end;

procedure TImage.Paint;
var
  Save: Boolean;
begin
  if csDesigning in ComponentState then
    with inherited Canvas do
    begin
      Pen.Style := psDash;
      Brush.Style := bsClear;
      Rectangle(0, 0, Width, Height);
    end;
  Save := FDrawing;
  FDrawing := True;
  try
    with inherited Canvas do
      StretchDraw(DestRect, Picture.Graphic);
  finally
    FDrawing := Save;
  end;
end;

I've found the trouble. Somehow a Meta.dcu file along with a Meta.pas file was put into the Lib directory of Delphi. These were pretty old (I think I wrestled with the Meta problem earlier last year and gave up). Because of that, the wrong .dcu file was installed into Delphi. The weird thing however is that Delphi did see the new .dcu at design time and didn't at runtime (compiled version). After removing the Meta.dcu and Meta.pas from the Lib directory, recompiling the example, everything worked as it should. Sorry for buying your time, thanks for the effort.

Paul.
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

To be PAQ/Refund

Please leave any comments here within the next seven days.
 
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
 
Thank you,
Russell

EE Cleanup Volunteer
ASKER CERTIFIED SOLUTION
Avatar of PashaMod
PashaMod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial