Board index » delphi » Drawing lines on top of everything

Drawing lines on top of everything

I've got an app that  I where people assign relationships between
objects.  These objects currently reside in different panels, and they
want to draw lines between the objects.  I'm able to accomplish this by
converting everything to screen coordinates, and using a canvas to draw
to the screen dc.  Everything works fine until part of the form is
either hidden, or I resize it, the lines are redrawn right where I want
them to be.  Once I do either of the things above though, the lines are
redrawn directly on the desktop.
Any able to enlighten me?
TIA
Mike
 

Re:Drawing lines on top of everything


You might want to try to just draw on the Form's canvas, since that's all you really need to do
anyway.

Kirk

Quote
On Tue, 16 Feb 1999 13:43:30 -0700, Mike Mormando <m...@mormando.com> wrote:
>I've got an app that  I where people assign relationships between
>objects.  These objects currently reside in different panels, and they
>want to draw lines between the objects.  I'm able to accomplish this by
>converting everything to screen coordinates, and using a canvas to draw
>to the screen dc.  Everything works fine until part of the form is
>either hidden, or I resize it, the lines are redrawn right where I want
>them to be.  Once I do either of the things above though, the lines are
>redrawn directly on the desktop.
>Any able to enlighten me?
>TIA
>Mike

Re:Drawing lines on top of everything


Not that I'm able to see, if I try to draw a line with the forms canvas, and the form has a couple
of panels on top of it, I never see the line, or am I doing something else wrong?
Mike
Quote
Kirk Woll wrote:
> You might want to try to just draw on the Form's canvas, since that's all you really need to do
> anyway.

> Kirk

> On Tue, 16 Feb 1999 13:43:30 -0700, Mike Mormando <m...@mormando.com> wrote:

> >I've got an app that  I where people assign relationships between
> >objects.  These objects currently reside in different panels, and they
> >want to draw lines between the objects.  I'm able to accomplish this by
> >converting everything to screen coordinates, and using a canvas to draw
> >to the screen dc.  Everything works fine until part of the form is
> >either hidden, or I resize it, the lines are redrawn right where I want
> >them to be.  Once I do either of the things above though, the lines are
> >redrawn directly on the desktop.
> >Any able to enlighten me?
> >TIA
> >Mike

Re:Drawing lines on top of everything


Are the Panels directly adjacent, or is there some of the form showing
between them?  The Paint that happens when uncovering or resizing will
probably paint the form, then the panels.  If the drawing of the connector
is part of the Form's Paint handler, as it ought to be, then it might be
being drawn and then overdrawn by the panels.  Or is it possible that you
are just drawing the connector once and not each time the Paint event fires?

Re:Drawing lines on top of everything


Mike Mormando ???g??31 <36C9DF50.67A4D...@mormando.com>...
Quote
>Not that I'm able to see, if I try to draw a line with the forms canvas,

and the form has a couple

Quote
>of panels on top of it, I never see the line, or am I doing something else
wrong?
>Mike

The following code may help you.
  TForm1 = class(TForm)
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormShow(Sender: TObject);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
    MD: Boolean;
    DP: TPoint;
  public
    { Public declarations }
    Procedure BoundMouse(const isLimit: Boolean);
    Procedure OverDraw(const isOver: Boolean);
  end;

......
procedure TForm1.FormShow(Sender: TObject);
begin
  MD:= False;
end;

Procedure TForm1.BoundMouse(const isLimit: Boolean);
Var
  MRect: TRect;
Begin
  If isLimit then
  Begin
    MRect.TopLeft:= ClientToScreen(Point(0,0));
    MRect.BottomRight:= ClientToScreen(Point(ClientRect.Right,
ClientRect.Bottom));
    ClipCursor(@MRect);
  End Else
    ClipCursor(nil);
End;

Procedure TForm1.OverDraw(const isOver: Boolean);
Var
  Style: Longint;
Begin
  Style:= GetWindowLong(Handle, GWl_Style);
  If isOver then
    Style:= Style and (not WS_ClipChildren)
  Else
    Style:= Style or WS_ClipChildren;

  SetWindowLong(Handle, GWl_Style, Style);
End;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  DP:= Point(X, Y);

  MD:= True;
  BoundMouse(MD);
  OverDraw(MD);
  Canvas.Pen.Width:= 2;
{2}  Canvas.Pen.Mode:= pmNotXor;
  Canvas.Pen.Color:= RGB(Random(256), Random(256), Random(256));{2}

{1  Canvas.Pen.Mode:= pmXor;//pmNotXor;
  Canvas.Pen.Color:= RGB(Random(256), Random(256), Random(256));
  Canvas.Brush.Style:= bsClear;{1}

  Canvas.Rectangle(X-50, Y-50, X+50, Y+50);
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  If MD then
  Begin
    Canvas.Rectangle(DP.X-50, DP.Y-50, DP.X+50, DP.Y+50);
    DP:= Point(X, Y);
    Canvas.Rectangle(DP.X-50, DP.Y-50, DP.X+50, DP.Y+50);
  End;
end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Canvas.Rectangle(DP.X-50, DP.Y-50, DP.X+50, DP.Y+50);
  MD:= False;
  BoundMouse(MD);
  OverDraw(MD);
end;

Re:Drawing lines on top of everything


Maybe you could put a paintbox ON the panel and then draw on the paintbox?
Davie
Quote
David Boudreau wrote:
> Are the Panels directly adjacent, or is there some of the form showing
> between them?  The Paint that happens when uncovering or resizing will
> probably paint the form, then the panels.  If the drawing of the connector
> is part of the Form's Paint handler, as it ought to be, then it might be
> being drawn and then overdrawn by the panels.  Or is it possible that you
> are just drawing the connector once and not each time the Paint event fires?

Re:Drawing lines on top of everything


If it were a single panel, I could do it.  but I've got a multitude of panels,
some of which are nested inside other panels, and lets say I've got panels A, B,
and C, then within panel A, I've got d,e,f, B I've got g,h, and C I've got j,k,and
l.  Then I want to show a line from a component parented in panel l that the other
end is in a panel parented in panel d.  That's my problem.
As to the question of redrawing the lines, I'm keeping track of the form relative
points in a TList, and I draw them in an overridden Paint method, so I think it
should be re-painted every time.  As a matter of fact, it appears that it is, it's
just that instead of showing on my form, it looks like it's now being painted on
the Desktop!
Ah well, I've gotten a few other ideas here that I haven't tried out yet, I'll
give those a go and let everybody know the outcome.
Thx for everyones help!
Mike
Quote
Davie Reed wrote:
> Maybe you could put a paintbox ON the panel and then draw on the paintbox?
> Davie

> David Boudreau wrote:

> > Are the Panels directly adjacent, or is there some of the form showing
> > between them?  The Paint that happens when uncovering or resizing will
> > probably paint the form, then the panels.  If the drawing of the connector
> > is part of the Form's Paint handler, as it ought to be, then it might be
> > being drawn and then overdrawn by the panels.  Or is it possible that you
> > are just drawing the connector once and not each time the Paint event fires?

Re:Drawing lines on top of everything


Send me your code for painting and I will look at it for you.
Davie
Quote
Mike Mormando wrote:
> If it were a single panel, I could do it.  but I've got a multitude of panels,
> some of which are nested inside other panels, and lets say I've got panels A, B,
> and C, then within panel A, I've got d,e,f, B I've got g,h, and C I've got j,k,and
> l.  Then I want to show a line from a component parented in panel l that the other
> end is in a panel parented in panel d.  That's my problem.
> As to the question of redrawing the lines, I'm keeping track of the form relative
> points in a TList, and I draw them in an overridden Paint method, so I think it
> should be re-painted every time.  As a matter of fact, it appears that it is, it's
> just that instead of showing on my form, it looks like it's now being painted on
> the Desktop!
> Ah well, I've gotten a few other ideas here that I haven't tried out yet, I'll
> give those a go and let everybody know the outcome.
> Thx for everyones help!
> Mike

> Davie Reed wrote:

> > Maybe you could put a paintbox ON the panel and then draw on the paintbox?
> > Davie

> > David Boudreau wrote:

> > > Are the Panels directly adjacent, or is there some of the form showing
> > > between them?  The Paint that happens when uncovering or resizing will
> > > probably paint the form, then the panels.  If the drawing of the connector
> > > is part of the Form's Paint handler, as it ought to be, then it might be
> > > being drawn and then overdrawn by the panels.  Or is it possible that you
> > > are just drawing the connector once and not each time the Paint event fires?

Re:Drawing lines on top of everything


I've tried your code, and it seems to work fine, until it comes time to
repaint, it looks like the form repaints, then the panels repaint on top of
my lines, obscuring them.
Any other ideas?
Mike
Quote
Samson Fu wrote in message <7advfr$8i...@forums.borland.com>...
>Mike Mormando ???g??31 <36C9DF50.67A4D...@mormando.com>...
>>Not that I'm able to see, if I try to draw a line with the forms canvas,
>and the form has a couple
>>of panels on top of it, I never see the line, or am I doing something else
>wrong?
>>Mike

>The following code may help you.
>  TForm1 = class(TForm)
>    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
>      Shift: TShiftState; X, Y: Integer);
>    procedure FormShow(Sender: TObject);
>    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
>      Y: Integer);
>    procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
>      Shift: TShiftState; X, Y: Integer);
>  private
>    { Private declarations }
>    MD: Boolean;
>    DP: TPoint;
>  public
>    { Public declarations }
>    Procedure BoundMouse(const isLimit: Boolean);
>    Procedure OverDraw(const isOver: Boolean);
>  end;

>......
>procedure TForm1.FormShow(Sender: TObject);
>begin
>  MD:= False;
>end;

>Procedure TForm1.BoundMouse(const isLimit: Boolean);
>Var
>  MRect: TRect;
>Begin
>  If isLimit then
>  Begin
>    MRect.TopLeft:= ClientToScreen(Point(0,0));
>    MRect.BottomRight:= ClientToScreen(Point(ClientRect.Right,
>ClientRect.Bottom));
>    ClipCursor(@MRect);
>  End Else
>    ClipCursor(nil);
>End;

>Procedure TForm1.OverDraw(const isOver: Boolean);
>Var
>  Style: Longint;
>Begin
>  Style:= GetWindowLong(Handle, GWl_Style);
>  If isOver then
>    Style:= Style and (not WS_ClipChildren)
>  Else
>    Style:= Style or WS_ClipChildren;

>  SetWindowLong(Handle, GWl_Style, Style);
>End;

>procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
>  Shift: TShiftState; X, Y: Integer);
>begin
>  DP:= Point(X, Y);

>  MD:= True;
>  BoundMouse(MD);
>  OverDraw(MD);
>  Canvas.Pen.Width:= 2;
>{2}  Canvas.Pen.Mode:= pmNotXor;
>  Canvas.Pen.Color:= RGB(Random(256), Random(256), Random(256));{2}

>{1  Canvas.Pen.Mode:= pmXor;//pmNotXor;
>  Canvas.Pen.Color:= RGB(Random(256), Random(256), Random(256));
>  Canvas.Brush.Style:= bsClear;{1}

>  Canvas.Rectangle(X-50, Y-50, X+50, Y+50);
>end;

>procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
>  Y: Integer);
>begin
>  If MD then
>  Begin
>    Canvas.Rectangle(DP.X-50, DP.Y-50, DP.X+50, DP.Y+50);
>    DP:= Point(X, Y);
>    Canvas.Rectangle(DP.X-50, DP.Y-50, DP.X+50, DP.Y+50);
>  End;
>end;

>procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
>  Shift: TShiftState; X, Y: Integer);
>begin
>  Canvas.Rectangle(DP.X-50, DP.Y-50, DP.X+50, DP.Y+50);
>  MD:= False;
>  BoundMouse(MD);
>  OverDraw(MD);
>end;

Re:Drawing lines on top of everything


Thanks, I'll do that this evening.(No smtp access at work)
Mike
Quote
Davie Reed wrote:
> Send me your code for painting and I will look at it for you.
> Davie

Re:Drawing lines on top of everything


Mike,

If you figure this out, could you post your solution or send it to me. I'm
having a similar problem with panels in trying to draw a custom border on a
form. (Though I could solve my problem if I knew how to draw between the
forms edge and the client area.)

Thanks,

John Langley

Quote
Mike Mormando wrote:
> I've got an app that  I where people assign relationships between
> objects.  These objects currently reside in different panels, and they
> want to draw lines between the objects.  I'm able to accomplish this by
> converting everything to screen coordinates, and using a canvas to draw
> to the screen dc.  Everything works fine until part of the form is
> either hidden, or I resize it, the lines are redrawn right where I want
> them to be.  Once I do either of the things above though, the lines are
> redrawn directly on the desktop.
> Any able to enlighten me?
> TIA
> Mike

Re:Drawing lines on top of everything


Quote
>form. (Though I could solve my problem if I knew how to draw between the
>forms edge and the client area.)

Try trapping the WM_NCPAINT message or, if you're really carefull, drawing
directly to GetDC(GetDeskTopWindow);

Re:Drawing lines on top of everything


You can implement the "OnPaint" event of "Form1", and redraw your graphic
there.
and call "overdraw(True)" at begining, "overdraw(false)" at end.

Mike Mormando ???g??31 <7aqjm6$o...@forums.borland.com>...

Quote
>I've tried your code, and it seems to work fine, until it comes time to
>repaint, it looks like the form repaints, then the panels repaint on top of
>my lines, obscuring them.
>Any other ideas?

Re:Drawing lines on top of everything


To draw over all child windows, use the GetDCEx API function.

Samson Fu <samso...@hutchcity.com> wrote in article
<7b5qmu$gq...@forums.borland.com>...

Quote
> You can implement the "OnPaint" event of "Form1", and redraw your graphic
> there.
> and call "overdraw(True)" at begining, "overdraw(false)" at end.

> Mike Mormando ???g??31 <7aqjm6$o...@forums.borland.com>...
> >I've tried your code, and it seems to work fine, until it comes time to
> >repaint, it looks like the form repaints, then the panels repaint on top
of
> >my lines, obscuring them.
> >Any other ideas?

Other Threads