Avatar of APS NZ
APS NZ
Flag for New Zealand asked on

Trigger to paint a component after color change

Hi

I am using the default TColorProperty property editor so that users can choose the color they want from the list in my component.  How do I tell the component to repaint itself in the chosen color?  I have a Paint procedure but I need to know how to trigger it.

The property editor code is taken straight from the Delphi help.  Here is what I have.

----
published
    { Published declarations }
    property Color: TColor read FMyInplaceColor write FMyInplaceColor;
  end;

function MyInplaceEdit.GetAttributes: TPropertyAttributes;
begin
     Result := [paDialog];
end;

procedure MyInplaceEdit.Edit;
var
  ColorDialog: TColorDialog;
begin
  ColorDialog := TColorDialog.Create(Application);                { construct the editor }
  try
    ColorDialog.Color := GetOrdValue;                           { use the existing value }
    if ColorDialog.Execute then
    begin                             { if the user OKs the dialog... }
      SetOrdValue(ColorDialog.Color);
    end;                           { ...use the result to set value }
  finally
    ColorDialog.Free;                                               { destroy the editor }

  end;
end;

procedure TColorButton.Paint;
begin
     inherited Paint;
     With Canvas do
     begin
          Brush.Color := Color;
          Brush.Style := bsSolid;
          Rectangle(Left, Top, Left+Width, Top+Height);
     end;
end;
Delphi

Avatar of undefined
Last Comment
APS NZ

8/22/2022 - Mon
pcsentinel

If your code is right then you should just need a Component.Repaint;
Mike Littlewood

Or do a component.invalidate + component.refresh
LukA_YJK

Maybe you should change the code to repaint the Button once its colour changed by simply calling Paint. You could also add it as a last line into SetOrdValue();
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
APS NZ

ASKER
Thanks for the replies.  I really need to know where to put the code to trigger the painting after the color has been changed.  Whatever I add as a line after SetOrdValue throws an error saying "Undeclared Identifier Paint" or "Undeclared Identifier Invalidate" etc when I try to compile the unit.
ON031699

If your custom control is based on a windowed control, you can try this.
In your uses in the beginning of the unit, add 'Windows'
In your MyInplaceEdit.Edit
   begin
      SetOrdValue(ColorDialog.Color);
      InvalidateRect(TColorButton.Handle, nil, False);
   end;
TName

//Have yot tried - as suggested by others, but specifying that you want *TButton* to repaint:
SetOrdValue(ColorDialog.Color);
TColorButton.Invalidate;
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
LukA_YJK

"Undeclared Identifier Paint", huh? Where did you place your Paint()? It should not be private (protected?) to allow you to use it. Maybe it will help
APS NZ

ASKER
Thanks for the latest replies, but it's still not working.  I have discovered that if i remove the line "inherited Paint" from the Paint procedure the button disappears from the form.  On single-stepping through the code it definitely goes through the whole Paint procedure, so why will it not paint the button?  

ON and TName:  When I add InvalidateRect(TColorButton.Handle, nil, False); I get the error "Undeclared Identifier 'Handle'"

LukA YJK:  I have tried putting Paint in all the sections but it will not work.
ON031699

What class are your custom control based on?
All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
LukA_YJK

Yeah, better post your TColorButton class declaration. You have an inherited Paint, but calling your new Paint raises Exception. This is suspicious :)
APS NZ

ASKER
Thanks ON and Luka YJKOK - here's the declaration:

type
  MyInplaceEdit = class(TColorProperty)
  public
    procedure Edit;
    function GetAttributes: TPropertyAttributes;
  end ;

type
  TColorButton = class(TSpeedButton)
  private
    { Private declarations }
    FMyInplaceColor: TColor;
  protected
    { Protected declarations }
    procedure Paint; override;
  public
    { Public declarations }
  published
    { Published declarations }
    property Color: TColor read FMyInplaceColor write FMyInplaceColor;
  end;

procedure Register;

implementation
ASKER CERTIFIED SOLUTION
TName

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
TName

and try this in your MyInplaceEdit.Edit;

{...}
SetOrdValue(ColorDialog.Color);
      TSpeedButton(TColorButton).Invalidate;
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
APS NZ

ASKER
Thanks TName - we're almost there!  The color will change now, but only if I "do something" like resize it or toggle between the form and the code window.

TName

Try this:

SetOrdValue(ColorDialog.Color);
TSpeedButton(TColorButton).Invalidate;
Modified;

 (If it works, try it without the invalidate line - you shouldn't really need invalidate)
APS NZ

ASKER
Sorry TName - it doesn't work.
Your help has saved me hundreds of hours of internet surfing.
fblack61
APS NZ

ASKER
In the absence of further comments I will accepts TName's comment as an answer because it almost works