Creazione nuovo componente

di il
5 risposte

Creazione nuovo componente

Ciao a tutti,

avrei bisogno di creare un nuovo componente che funga da checkbox, ne ho bisogno uno personalizzato perche mi serve piu grande e con grafica diversa.

pensavo di ereditarlo da una timage ed assegnargli quindi una immagine per il true e una per il false, 

ma quando piazzo il componente nella form, a parte che sembra che si refresha in continuazione , ma non riesco ad assegnargli le immagini, mi rimane sempre aperta la finestra di assegnazione,

questo è il codice, se qualche anima pia riesce a darmi una dritta glele sono grato:

unit mycheckbox;
interface
uses
 System.Classes, Vcl.Controls, Vcl.ExtCtrls, Vcl.Graphics;
type
 Tmycheckbox = class(TImage)
 private
   FChecked: Boolean;
   FCheckedImage: TBitmap;
   FUncheckedImage: TBitmap;
   procedure SetChecked(Value: Boolean);
   procedure SetCheckedImage(Value: TBitmap);
   procedure SetUncheckedImage(Value: TBitmap);
   procedure ToggleChecked;
 protected
   procedure Click; override;
   procedure Paint; override;
 public
   constructor Create(AOwner: TComponent); override;
   destructor Destroy; override;
 published
   property Checked: Boolean read FChecked write SetChecked default False;
   property CheckedImage: TBitmap read FCheckedImage write SetCheckedImage;
   property UncheckedImage: TBitmap read FUncheckedImage write SetUncheckedImage;
 end;
procedure Register;
implementation
constructor Tmycheckbox.Create(AOwner: TComponent);
begin
 inherited Create(AOwner);
 Width := 40;
 Height := 40;
 FCheckedImage := TBitmap.Create;
 FUncheckedImage := TBitmap.Create;
end;
destructor Tmycheckbox.Destroy;
begin
 FCheckedImage.Free;
 FUncheckedImage.Free;
 inherited Destroy;
end;
procedure Tmycheckbox.SetChecked(Value: Boolean);
begin
 if FChecked <> Value then
 begin
   FChecked := Value;
   Invalidate;
 end;
end;
procedure Tmycheckbox.SetCheckedImage(Value: TBitmap);
begin
 FCheckedImage.Assign(Value);
 Invalidate;
end;
procedure Tmycheckbox.SetUncheckedImage(Value: TBitmap);
begin
 FUncheckedImage.Assign(Value);
 Invalidate;
end;
procedure Tmycheckbox.ToggleChecked;
begin
 Checked := not Checked;
end;
procedure Tmycheckbox.Click;
begin
 inherited Click;
 ToggleChecked;
end;
procedure Tmycheckbox.Paint;
var
 Image: TBitmap;
begin
 inherited Paint;
 if Checked then
   Image := FCheckedImage
 else
   Image := FUncheckedImage;
 if (Width > 0) and (Height > 0) then
   Canvas.StretchDraw(Rect(0, 0, Width, Height), Image);
end;
procedure Register;
begin
 RegisterComponents('mycomps', [Tmycheckbox]);
end;
end.

5 Risposte

  • Re: Creazione nuovo componente

    Fcheckedimage è timage giusto?

    FChecked := Value;  

    FCheckedImage.Assign(Value)

    Value è boolean?

    FCheckedImage.Assign(tbitmap)

    Mi sfugge qualcosa?

  • Re: Creazione nuovo componente

    22/05/2023 - ziobacco ha scritto:


    pensavo di ereditarlo da una timage ed assegnargli quindi una immagine per il true e una per il false, 

    Non mi sembra la classe giusta da cui partire, visto che ha già una proprietà Picture: quella come verrebbe gestita? ignorandola?

    Inoltre, se nel metodo Paint chiami l'implementazione ereditata, ottieni il disegno dell'immagine originale impostata nella suddetta proprietà, assieme al disegno della tua, da cui potrebbe dipendere il flickering.

    Infine, attento che il Click potrebbe essere scatenato anche in fase di progettazione, perché per selezionare e spostare il controllo di fatto fai clic sul controllo visuale, quindi scateni il cambio di stato.

    Forse è meglio partire dal controllo CheckBox, o meglio da TCustomCheckBox, esponendo solo le proprietà desiderate e implementando la tecnica di “owner drawing” per disegnare le immagini al posto del controllo (oppure il controllo secondo il proprio stile o quello configurato).

    Trovi un esempio in questo articolo, anche se lo scenario è leggermente diverso (ma serve per rendere l'idea).

  • Re: Creazione nuovo componente

    22/05/2023 - sihsandrea ha scritto:


    FChecked := Value;  

    FCheckedImage.Assign(Value)

    Value è boolean?

    FCheckedImage.Assign(tbitmap)

    Mi sfugge qualcosa?

    Sì, perché in un caso Value imposta FChecked ed è booleana nella dichiarazione, nell'altro caso un TBitmap: se i tipi non fossero stati compatibili, il progretto non avrebbe nemmeno compilato.

  • Re: Creazione nuovo componente

    Grazie Aika

    In verità all inizio ero partito dal tcheckbox ma ho avuto problemi proprio sul metodo paint, perche mi diceva che non esisteva nella classe base , per quello son passato al timage, cmq provo  dare un occhio al tuo link intanto, grazie.

  • Re: Creazione nuovo componente

    23/05/2023 - ziobacco ha scritto:


    In verità all inizio ero partito dal tcheckbox ma ho avuto problemi proprio sul metodo paint, perche mi diceva che non esisteva nella classe base

    Sì, questo è probabile in quanto la CheckBox stessa viene disegnata richiamando le API di Windows, e non disegnando direttamente il controllo, poiché Windows conosce e dispone di questo controllo nativamente.

    Se può esserti utile, puoi anche dare un'occhiata all'enorme quantità di componenti di questo tipo che si trovano sul sito Torry Delphi's Pages, la maggior parte disponibile con sorgente (e quindi valida per farsi una idea di come ottenere certi effetti e funzionalità).

Devi accedere o registrarti per scrivere nel forum
5 risposte