自定義一個圖形控件(繼承自TGraphicControl
類),須要在不一樣區域顯示不一樣字體的內容,此時會須要在設計器中加入多個字體,方法是在控件的published
區增長對應的字體屬性便可(使用Ctrl+Shift+C
可快速生成),如:ide
TMyGraphicControl = class(GraphicControl) private FText1Font: TFont; FText2Font: TFont; procedure SetText1Font(const Value: TFont); procedure SetText2Font(const Value: TFont); protected procedure Paint; override; public { public declarations } published property Text1Font:TFont read FText1Font write SetText1Font; property Text2Font:TFont read FText2Font write SetText2Font; end;
這樣就能夠在設計器裏像使用原生控件同樣使用本身的控件了。字體
可是,若是在設計期選擇了彈出字體對話框進行設置字體,IDE就會報錯(大意是讀或寫某個地址異常),而在運行期則正常!設計
對比查看Delphi自帶的控件源碼,終於找到了緣由。指針
//Delphi TControl類設置字體屬性的方法 procedure TControl.SetFont(Value: TFont); begin FFont.Assign(Value); end; //本身設置字體屬性的方法 procedure TMyGraphicControl.SetText1Font(const Value: TFont); begin FText1Font := Value; end;
由此,真相大白!code
TFont
是類,其實例使用:=
賦值時,實例上是把實例的指針指向了值的來源;而使用Assign
方法,則是把各字段值複製了一份存放在實例的字段中。在運行期,對字體賦值,值的來源在上下文環境中是肯定且存在的;在設計期經過設計器直接對字體各子項賦值,其實是在逐一對其字段賦值;而在設計期經過字體對話框進行賦值,實際是產生了一條Windows消息
,消息傳遞完成以後內容就會銷燬,因此使用:=
賦值就會產生地址讀寫的異常。繼承
對類的實例進行賦值時,必定要想清楚最終想要的效果是什麼,由此來肯定是使用:=
仍是Assign
方法。源碼