I created an custom control for the TStatusbar. Its in old Delphi5 for windows. The goal is, if I click the panel or the image, an event should be raise. But I get an error by assigning the click event to the image. The error is in line starts with _Image.OnClick := ButtonClick; Can anyone solve this? Thank you!
I modified the code, it works now. Any suggestions to make it even better? My main mistake was that I misunderstand
self := TPanelImageButton(template);
I read, that in this case self should inherit all from template. But I guess this was wrong. So I now set the properties I need in code.
Thank you!
unit PanelImageButton;
{
Usage:
var
PanelUser: TPanelImageButton;
PanelUser :=TPanelImageButton.Create(self,PanelUserTemplate,Image1);
PanelUser.OnClick:= PanelUserClicked;
procedure TForm1.PanelUserClicked(Sender:TObject);
begin
end;
FormClose() -> FreeAndNil(PanelUser);
}
interface
//Delphi: uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls, ExtCtrls;
//Lazarus: uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls;
uses
Windows, Messages, Classes, SysUtils, FileUtil, Forms, Controls,
Graphics, Dialogs, StdCtrls, ExtCtrls,{für Fehler}debug;
type
//define usercontrol
TPanelImageButton = class(TPanel)
private
_PanelIndex: integer;
_Image: TImage;
//define event
FOnClick: TNotifyEvent;
procedure ButtonClick(Sender: TObject);
procedure Resizeing(Sender: TObject);
protected
procedure Click; override; //override;//dynamic;
public
constructor Create(TheOwner: TComponent); overload; override;
constructor Create(TheOwner: TComponent; template: TPanel; imageTemplate: TImage);
reintroduce; overload;
destructor Destroy; override;
function HasImage(): boolean;
published
property PanelIndex: integer read _PanelIndex write _PanelIndex;
property OnClick: TNotifyEvent read FOnClick write FOnClick;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('PHOENIX', [TPanelImageButton]);
end;
constructor TPanelImageButton.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
PanelIndex := -1;
_Image := nil;
self.Caption := '';
end;
constructor TPanelImageButton.Create(TheOwner: TComponent;
template: TPanel; imageTemplate: TImage);
begin
inherited Create(TheOwner);
try
PanelIndex := -1;
self.Caption := template.Caption;
self.Color := template.Color;
self.Font := template.Font;
if (assigned(imageTemplate)) then
begin
_Image := TImage.Create(self);
_Image.Picture.Assign(imageTemplate.Picture);
_Image.Transparent := True;
_Image.Parent := self;
_Image.Visible := True;
_Image.AutoSize := False;
_Image.Stretch := True;
_Image.OnClick := ButtonClick;
imageTemplate.Visible := False;
_Image.Cursor := crHandPoint;
end
else
if assigned(_Image) then
FreeAndNil(_Image);
self.OnResize := Resizeing;
//keine Ränder:
self.BevelOuter := bvNone;
self.BevelInner := bvNone;
self.Cursor := crHandPoint;
except
on e: Exception do
WriteDebug('PanelImageButton: ' + e.Message);
end;
end;
destructor TPanelImageButton.Destroy;
begin
try
self.Parent := nil;
if assigned(_Image) then
begin
_Image.parent := nil;
FreeAndNil(_Image);
end;
except
on e: Exception do
WriteDebug('TPanelImageButton.Destroy: ' + e.Message);
end;
inherited;
end;
function TPanelImageButton.HasImage(): boolean;
begin
Result := False;
if assigned(_Image) then
Result := True;
end;
procedure TPanelImageButton.Resizeing(Sender: TObject);
begin
if not (assigned(_Image)) then
exit;
try
_Image.Left := 6;
_Image.Height := self.Height - 12;
_Image.Top := 6;
_Image.Width := _Image.Height;
except
on e: Exception do
WriteDebug('PanelImageButton: ' + e.Message);
end;
end;
procedure TPanelImageButton.ButtonClick(Sender: TObject);
begin
Click;
end;
procedure TPanelImageButton.Click;
begin
try
if Assigned(FOnClick) then
FOnClick(Self);
except
on e: Exception do
WriteDebug('PanelImageButton: ' + e.Message);
end;
end;
end.
I propose that you read up on:
Self- and what it is for and that assigning something else to it basically makes it useless. You could have made it_Image.Parent := template;. But you assignedtemplatetoselfand then later you doself.OnResize := Resizeing;. Do you want to handleOnResizefor thisTPanelImageButton(which should have beenSelfif you did not change it) or do you want to handleOnResizefortemplate? Leaveselfalone. Use it to access this instance of the class you are currently coding in.@operator - In one of you comments above you dobuttonUser.OnClick := @buttonUserClick;. What is that about? The@operator is discussed everywhere. Read up. Its a cool thing but should be used correctly. This blog post is so cool: http://rvelthuis.de/articles/articles-pointers.htmlThere are some basics that needs to be addressed and I strongly recommend you study how components in Delphi are made.
The last very important thing is for you to include the errors you see into the Stack Overflow question. If you did that we could have given you more specific answers on your particular issue. You would have returned complaining about some other error but at least you would have learned about the first one, hopefully.