Solved

My panel based component will not repaint correctly

Posted on 2002-03-07
5
331 Views
Last Modified: 2010-04-05
I have a crude component based on a Tpanel that is intended to provide the effect of a speed button where I can set the color. I create an image and a label when the panel is created. When the panel is clicked I change its BevelOuter property between raised and lowered on MouseDown and MouseUp. I also try to shift the position of the image and the label down and right on the mouseDown and back up and left on the mouseUp. The problem is that the label does not change position while the image does and I cannot see why. (The label does sometimes flicker as if it is being repainted more than once.) I am using D6. It is probably something obvious but I would be grateful if someone can tell me how to fix it. - regards - Dan

 Here is the component code

unit ReadBtn;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, ExtCtrls, Graphics, StdCtrls;

type
  TButtonLayout = (blGlyphLeft, {blGlyphRight,} blGlyphTop{, blGlyphBottom});
  TReadBtn = class(TPanel)
  private
    { Private declarations }
    MouseOffSet : integer;
  protected
    { Protected declarations }
    fImage : TImage;
    fPicture : TPicture;
    fLabel : TLabel;
    fCaptionX : string;
    FLayout: TButtonLayout;
    procedure setPic(aPic : TPicture);
    function getPic : TPicture;
    procedure setCaptionX(aCaption : string);
    procedure SetLayout(Value: TButtonLayout);
    procedure myClick(Sender: TObject);
    procedure ButtonOut(Sender: TObject; Button: TMouseButton;
    Shift: TShiftState; X, Y: Integer);
    procedure ButtonIn(Sender: TObject; Button: TMouseButton;
    Shift: TShiftState; X, Y: Integer);
  public
    { Public declarations }
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure Paint; override;
    constructor create(owner : TComponent); override;
  published
    { Published declarations }
    property Picture : TPicture read getPic write setPic;
    property CaptionX : string read fCaptionX write setCaptionX;
    property Layout: TButtonLayout read FLayout write SetLayout default blGlyphTop;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TReadBtn]);
end;

{ TReadBtn }

constructor TReadBtn.create(owner: TComponent);
begin
    inherited create(owner);
    Height := 59;
    Width := 58;
    Caption := '';
    BevelWidth := 2;
    Color := $00DFDFDF;  //very light grey
    layout := blGlyphTop;
    MouseOffSet := 0;

    fImage := TImage.Create(self);
    fImage.Parent := self;
    fImage.Top := 1;
    fImage.Left := 1;
    fImage.Transparent := true;
    fImage.Center := true;
    fImage.OnClick := myClick;
    fImage.OnMouseDown := ButtonIn;
    fImage.OnMouseUp := ButtonOut;

    fLabel := TLabel.create(self);
    fLabel.parent := self;
    fLabel.Left := 2;
    flabel.Alignment := taCenter;
    flabel.Anchors := [];
    flabel.OnClick := myClick;
    flabel.OnMouseDown := ButtonIn;
    flabel.OnMouseUp := ButtonOut;
end;

function TReadBtn.getPic: TPicture;
begin
    result := fimage.Picture;
end;

procedure TReadBtn.MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer);
begin
    ButtonIn(self,button,shift,x,y);
    inherited;
end;

procedure TReadBtn.MouseUp(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer);
begin
    ButtonOut(self,button,shift,x,y);
    inherited;
end;

procedure TReadBtn.ButtonIn(Sender: TObject; Button: TMouseButton;
    Shift: TShiftState; X, Y: Integer);
begin
  MouseOffSet := 2;
  bevelOuter := bvLowered;
end;

procedure TReadBtn.ButtonOut(Sender: TObject; Button: TMouseButton;
    Shift: TShiftState; X, Y: Integer);
begin
  MouseOffSet := -2;
  bevelOuter := bvRaised;
end;

procedure TReadBtn.myClick(Sender: TObject);
begin
    if assigned(OnClick) then
        OnClick(self);
end;

procedure TReadBtn.Paint;
begin
    caption := '';
    fLabel.Color := color;
    fLabel.Height := canvas.TextHeight('Aq');
    fImage.Top := fImage.Top + MouseOffSet;
    if layout = blGlyphTop then
    begin
      fLabel.Width := width - 4;
      fLabel.Top := height - fLabel.Height - 1 + MouseOffSet;
      flabel.Left := 2 + MouseOffSet;

      fImage.Height := height - fLabel.Height - 1;
      fImage.Width := width - 2;
      fImage.Left := fImage.Left + MouseOffSet;
    end
    else if layout = blGlyphLeft then
    begin
      fImage.Height := height - 2;
      fImage.Width := fImage.Height;
      fImage.Left := fImage.Left + MouseOffSet;

      fLabel.Top := trunc((height - fLabel.Height - 1) /2) + MouseOffSet;
      fLabel.Width := canvas.textwidth(CaptionX) + 4;
      flabel.Left := fImage.Width + 4 + MouseOffSet;
    end;
    MouseOffSet := 0;
    inherited;
end;

procedure TReadBtn.SetLayout(Value: TButtonLayout);
begin
  if FLayout <> Value then
  begin
    FLayout := Value;
    Invalidate;
  end;
end;

procedure TReadBtn.setCaptionX(aCaption: string);
begin
    fCaptionX := aCaption;
    flabel.Caption := fCaptionX;
    Invalidate;
end;

procedure TReadBtn.setPic(aPic: TPicture);
begin
    fImage.Picture.Assign(aPic);
    Invalidate;
end;

end.
0
Comment
Question by:seabear
5 Comments
 
LVL 6

Expert Comment

by:DrDelphi
ID: 6849412
Hmmm, while I do see a very slight flicker, other than that it seems to work for me.

0
 
LVL 33

Accepted Solution

by:
Slick812 earned 200 total points
ID: 6849601
The TLabel for text display may be more than you need, Leave out the TLabel and try just using Canvas.TextOut(fImage.Width + 4 + MouseOffSet, height - Canvas.TextHeight('M') - 1) /2) + MouseOffSet,fCaptionX);
in your TReadBtn.Paint;

you will have to set your Canvas.Font := Font in your create.

you might be better off leaving out the TImage and just drawing the fPicture on the canvas in tne TReadBtn.Paint;
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6849762
in your paint-method,
call inherited first (or let it be) and
then paint your stuff

just a guess

meikl ;-)
0
 
LVL 1

Expert Comment

by:Moondancer
ID: 6853380
Question(s) below appears to have been abandoned. Your options are:
 
1. Accept a Comment As Answer (use the button next to the Expert's name).
2. Close the question if the information was not useful to you. You must tell the participants why you wish to do this, and allow for Expert response.
3. Ask Community Support to help split points between participating experts, or just comment here with details and we'll respond with the process.
4. Delete the question. Again, please comment to advise the other participants why you wish to do this.

For special handling needs, please post a zero point question in the link below and include the question QID/link(s) that it regards.
http://www.experts-exchange.com/jsp/qList.jsp?ta=commspt
 
Please click the Help Desk link on the left for Member Guidelines, Member Agreement and the Question/Answer process.  http://www.experts-exchange.com/jsp/cmtyHelpDesk.jsp

Please click you Member Profile to view your question history and keep them all current with updates as the collaboration effort continues, to track all your open and locked questions at this site.  If you are an EE Pro user, use the Power Search option to find them.

To view your open questions, please click the following link(s) and keep them all current with updates.
http://www.experts-exchange.com/questions/Q.11719378.html
http://www.experts-exchange.com/questions/Q.20243147.html
http://www.experts-exchange.com/questions/Q.20243174.html
http://www.experts-exchange.com/questions/Q.20274702.html

PLEASE DO NOT AWARD THE POINTS TO ME.  
 
------------>  EXPERTS:  Please leave any comments regarding your closing recommendations if this item remains inactive another seven (7) days.  Also, if you are interested in the cleanup effort, please click this link http://www.experts-exchange.com/jsp/qManageQuestion.jsp?ta=commspt&qid=20274643
 
Thank you everyone.
 
Moondancer
Moderator @ Experts Exchange

P.S.  For any year 2000 questions, special attention is needed to ensure the first correct response is awarded, since they are not in the comment date order, but rather in Member ID order.
0
 

Author Comment

by:seabear
ID: 6858960
Yes, using textout instead of a label fixes it - thanks.

DrDelphi - I am using Win98 problem may be dependant on Windows version

Meikle - Tried playing with the position of the call to the inherited paint method but it does not fix the problem

Thanks to everyone - Dan
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now