• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 235
  • Last Modified:

Drawing in a TCustomLabel

I have made a control which (amongst other things) changes colours when the mouse is moved over it.  Is there anyway that I can draw a black border around the label and then remove it when the mouse leaves??  I have tried just drawing directly on the canvas but it doesnt work.

0
Stuart_Johnson
Asked:
Stuart_Johnson
  • 3
  • 3
1 Solution
 
StevenBCommented:
 Stuart,

  Which bit exactly doesn't work? I have no problems drawing on the canvas of a TLabel. The following code shows how I would display a border round a label when the mouse is over it. Perhaps it would suffice for your needs.

  Steven.


unit NewLabel;

interface

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

type
  TNewLabel = class(TLabel)
  private
    MouseIn : Boolean;
    Procedure Paint; Override;
  protected
    procedure CMMouseEnter(var msg:TMessage); message CM_MouseEnter;
    procedure CMMouseLeave(var msg:TMessage); message CM_MouseLeave;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Steven', [TNewLabel]);
end;

Procedure TNewLabel.Paint;
begin
  inherited;
  If MouseIn then begin
    Canvas.Pen.Color := clBlack;
    Canvas.Brush.Style := bsClear;
    Canvas.Rectangle(0,0,width,height);
  end;
end;

procedure TNewLabel.CMMouseEnter(var msg:TMessage);
begin
  if Enabled then begin
    MouseIn := True;
    Repaint;
  end;
end;

procedure TNewLabel.CMMouseLeave(var msg:TMessage);
begin
  if Enabled then begin
    MouseIn := False;
    Repaint;
  end;
end;

end.



0
 
raunolCommented:
Hi,

Do You meen just Tlabel class or something else?

What about this principal:

Procedure TYourcomponent.WMMousemove(Var message:TWMMousemove);
Begin
     //Draw the frame around the control
     Canvas.Brush.Color:=clBlack;
     Canvas.FrameRect(clientRect);
     //run timer
     Timer.Enabled:=True;
End;

Procedure TYourComponent.OnTimer(sender:Tobject);
Begin
    Var Pt:Tpoint;
begin
     GetCursorPos(Pt);
     //check if the cursor is outside of the component
     If WindowFromPoint(pt)<>Handle Then
     Begin
          //Hide the frame without destroying other
          //information of it
          canvas.Brush.Color:=Color;
          Canvas.FrameRect(ClientRect);  
          Timer1.Enabled:=False;
     End;
End;

- Rauno



0
 
StevenBCommented:
 Raunol, I'm not sure how using the extra resources of a timer is more advantagous than using the messages CMMouseEnter and CMMouseLeave to check whether the cursor is over the label. I can't find an situation where my code fails to detect the presence of the cursor over the label.

  Steven.
0
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

 
raunolCommented:
Well. It should have to create first Timer for You
component Timer:=Ttimer.Create(self)
And then have to make Tmylabel.Ontimer(sender:Tobject)
function and then assign: Timer.onTimer:=Ontimer

But You are right and Stuart's code is much better. I
didn't discovered those messages. They should work.
But in Stuart's code I think, it is not nesissary to
repaint all contents of the label during framing. Just putting framerect under the Message-procedures should effects
borders without loosing the label contents already present.

Procedure Tmylabel.CMMouseEnter..
//paint frame
canvas.Brush.Color:=clBlack;
Canvas.FrameRect(ClientRect);

Procedure Tmylabel.CMMouseLeave..
//hide frame
canvas.Brush.Color:=color; //color=background color
Canvas.FrameRect(ClientRect);
 
- Rauno
0
 
Stuart_JohnsonAuthor Commented:
Raunol,

The answer I was looking for was provided by SteveB.  Sorry.

Steve, if you want to repost the comment as an answer, I'll award the points too you.

Thanks alL!

Stu
0
 
StevenBCommented:
 <<<See First Comment For Answer>>>

Raunol:

  I'd agree that in ithis example the use of a complete repaint to update the appearance of the components might be considered to be overkill, but there are reasons for it. If the component were to be obscured from view then the border would not reappear when it came back into view. By putting the commands in the Paint procedure, you can ensure that the border always displays correctly. Secondly, it is possible for a label to be transparent and for the background to be multicoloured (a bitmap for example) If you simply use Canvas.Brush.Color:=color;Canvas.FrameRect(ClientRect); to eliminate the border then the background will be corrupted.

  Steven.
       
0
 
raunolCommented:
Sorry, my mistake. You are Stuart. I had to say: code of
SteweB is better than mine. ;-)

- Rauno
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now