《Delphi高手突破》中一个可显示Image的Panel控件的一些问题! (200分)

  • 主题发起人 主题发起人 coolqiang
  • 开始时间 开始时间
C

coolqiang

Unregistered / Unconfirmed
GUEST, unregistred user!
下面是《Delphi高手突破》中的一个可显示Image的Panel控件的源码:

unit ImagePanel;

interface

uses
Windows, Classes, Graphics, Controls, ExtCtrls;

type
TImagePanel = class(TCustomPanel)
private
FPicture: TPicture;
FTransparent: Boolean;
FAutoSize: Boolean;

procedure PictureChanged(Sender: TObject);

procedure SetPicture(const Value: TPicture);
procedure SetTransparent(const Value: Boolean);
procedure SetAutoSize(const Value: Boolean); reintroduce; //问题一

procedure SetFont(const Value: TFont);
procedure SetCaption(const Value: TCaption);
procedure SetAlignment(const Value: TAlignment);
protected
procedure Paint; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Picture: TPicture read FPicture write SetPicture;
property Transparent: Boolean read FTransparent write SetTransparent default False;
property AutoSize: Boolean read FAutoSize write SetAutoSize;

property Font write SetFont;
property Caption write SetCaption;
property Alignment write SetAlignment;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('我的控件', [TImagePanel]);
end;

{ TImagePanel }

constructor TImagePanel.Create(AOwner: TComponent);
begin
inherited Create(AOwner); //问题二

FPicture := TPicture.Create;
FPicture.OnChange := PictureChanged;
Repaint;
end;

destructor TImagePanel.Destroy;
begin
FPicture.Free;
FPicture := nil;

inherited;
end;

procedure TImagePanel.Paint;
const
Alignments : array[TAlignment] of Longint = (DT_LEFT, DT_RIGHT, DT_CENTER);
var
Flags : Longint;
Rect : TRect;
FontHeight : Integer;
begin
Canvas.Brush.Style := bsClear;
Canvas.Font := Font;

if Assigned(FPicture.Graphic) then
begin
if FAutoSize then
begin
Width := FPicture.Width;
Height := FPicture.Height;
end;

if FPicture.Graphic.Transparent <> FTransparent then
FPicture.Graphic.Transparent := FTransparent;

Canvas.StretchDraw(ClientRect, FPicture.Graphic);
end else
begin
Canvas.Brush.Color := Color;
Canvas.FillRect(ClientRect);
end;

if Caption <> '' then
begin
Rect := GetClientRect;
FontHeight := Canvas.TextHeight('W');

Rect.Top := ((Rect.Bottom + Rect.Top) - FontHeight) div 2;
Rect.Bottom := Rect.Top + FontHeight;

Flags := DT_EXPANDTABS or DT_VCENTER or Alignments[Alignment];
Flags := DrawTextBiDiModeFlags(Flags);
DrawText(Canvas.Handle, PChar(Caption), -1, Rect, Flags);
end;
end;

procedure TImagePanel.PictureChanged(Sender: TObject);
begin
Repaint;
end;

procedure TImagePanel.SetAlignment(const Value: TAlignment);
begin
inherited Alignment := Value; //问题三
Repaint;
end;

procedure TImagePanel.SetAutoSize(const Value: Boolean);
begin
FAutoSize := Value;
Repaint;
end;

procedure TImagePanel.SetCaption(const Value: TCaption);
begin
inherited Caption := Value;
Repaint;
end;

procedure TImagePanel.SetColor(const Value: TColor);
begin
inherited Color := Value;
Repaint;
end;

procedure TImagePanel.SetFont(const Value: TFont);
begin
inherited Font := Value;
Repaint;
end;

procedure TImagePanel.SetPicture(const Value: TPicture);
begin
FPicture.Assign(Value);
Repaint;
end;

procedure TImagePanel.SetTransparent(const Value: Boolean);
begin
FTransparent := Value;
Repaint;
end;

end.

问题一:此处的reintroduce是什么意思?有何用途?

问题二:为何不是简单的inherited就行了?为何Create要加AOwner参数?是否为了指明其拥有者?

问题三:为何这里要加inherited?和Caption为Published有关吗?

问题四:Image控件可在设计时双击弹出“Picture Editor”,如何在此控件中实现?

问题五:在新建的From上添加一个Button时,代码如下:
TForm1 = class(TForm)
Button1: TButton;
private
{ Private declarations }
public
{ Public declarations }
end;
那么,Button1未指明是何类别(private、public等),它有默认值吗?

在下初学控件开发,让各位见笑了,请各位大虾不吝赐教!谢谢!
 
问题一:此处的reintroduce是什么意思?有何用途?
A method can be redeclared using the overload directive. In this case, if the redeclared method has a different parameter signature from its ancestor, it overloads the inherited method without hiding it. Calling the method in a descendant class activates whichever implementation matches the parameters in the call.
覆盖掉父类的一个静态方法, 用reintroduce告诉编译器, "我是要这样做的, 不用再提示我"

问题二:为何不是简单的inherited就行了?为何Create要加AOwner参数?是否为了指明其拥有者?
因為要傳遞參數! 是為了指明擁有者

问题三:为何这里要加inherited?和Caption为Published有关吗?
因為, 這個功能父類已經實現, 就讓父類去完成就可! 與Published沒有關系!

问题四:Image控件可在设计时双击弹出“Picture Editor”,如何在此控件中实现?
要自己定義屬性對話框, 當然, delphi也做了些通用的, 可以使用

问题五:在新建的From上添加一个Button时,代码如下:
應該是 published 的







 
同意楼上。
对于问题4,楼主可以参见许多控件源码。
只是Delphi在诸多版本变化过程中对屬性编辑器TPropertyEditor的继承性不好。
若要使你的控件通用,要么针对不同版本进行修改,要么使用通用的属性编辑器。
没有特殊要求,不要写专用的。
如你的这个TImagePanel,只要将Picture设计为TPicture类型属性,IDE将自动为它准备Picture Dialog.当然,如果不能满足需要的话,可以另写。
 
楼上回答的很好。
我补充一点:
问题二:为何不是简单的inherited就行了?为何Create要加AOwner参数?是否为了指明其拥有者?
因為要傳遞參數! 是為了指明擁有者

一般情况下可以使用简单的inherited就行了,但在构建过程中需要构建必须具有Parent的组件时,在inherited时必须传递参数
 
楼上的回答应该可以了。
 
多人接受答案了。
 
后退
顶部