作為元件製作的開始,應該了解一些概念,我以為這些概念是非常重要的,將可以作為以後實踐的理論基礎。
一、元件的簡要層次結構。一般情況下,vcl的元件可以從tcomponent為開始。其最明顯的特徵就是它的屬性可以在設計時通過物件察看器來操縱,另外,他還能擁有其他元件。
從tcomponent下,分出非可視元件和可視元件。
非可視元件如topendialog,ttimer,ttable等,這些元件因為繼承自tomponent,所以也就繼承了在設計時可以被操縱的特性。
視覺化元件始自tcontrol,是它引入了視覺化屬性和方法,使繼承自它的類都有了這些視覺化特性。
tcontrol又分出兩類元件型別:從twincontrol(視窗控制項)自下的控制項,和從tgraphiccontrol(圖形控制項)自下的控
制項。繼承自twincontrol的控制項將windows控制項進行封裝,所以擁有windows控制項的很多特性,比如可以得到焦點,有唯一的控制
碼,使用者可以通過傳送訊息與這些控制項進行互動等。而繼承自tgraphiccontrol的控制項,也是可見的,但沒有控制碼,可以稱之為圖形控制項,
比如tlabel,tbevel,都是delphi畫出來的,並不占用系統資源。
二、屬性
先看乙個簡單的屬性定義:
tsomeobj=class
private
fcount:integer;
protected
procedure setcount(value:integer);
published
property count:integer read fcount write setcount default 0;//屬性定義
end;
該屬性從私有成員fcount讀出值,而靠setcount方法設定值到私有成員fcount。
屬性的優勢在於可以很直觀進行讀寫,而又不同於私有成員。因為屬性可以通過寫訪問方法來保護私有成員:
procedure tsomeboj.setcount(value:integer);
begin
if fcount<>value then
fcount:=value;
end;
其中屬性定義中的default
0並不是預設值(即物件察看器顯示的值),預設值要在元件類的建構函式中設定。而default有這樣的作用,決定dfm檔中是否要儲存該屬性的值,比如
上面為default
0,即當該屬性值為0時,則該屬性不會被儲存到dfm中,如果該屬性值不為0,則該屬性會被儲存到dfm中。另外屬性定義還有乙個關鍵字為
nodefault,設定了這個關鍵字,比如
property count:integer read fcount write setcount nodefault;
則無論它的值是什麼,都會被寫到dfm檔中。
屬性可以有如下幾種型別,下面只給出簡單介紹,而這些型別的屬性,會在元件製作時詳細的運用:
簡單型別屬性:如上面定義的,加乙個例子
property text:string read ftext write settext;
列舉型別屬性:tenumtype=(enum1,enum2,enum3);
fenumtype:tenumtype;
property enumtype:tenumtype read fenumtype write fenumtype;
在物件察看器中看來就是下拉列框選擇值。
集合型別屬性:tset=(set1,set2,set3);
tsets=set of tset;
fsets:tsets;
property sets:tsets read fsets write fsets;
在物件察看器中看來,就是列出幾個選項分別設定真假。比如tform的bordericons屬性即是。
物件型別屬性:乙個屬性是乙個物件,而這個物件必須派生自tpersistent或者他之下的類,才能在物件察看器中可以展開它,並設定它裡面的屬性。
陣列型別屬性:陣列屬性如果要在物件察看器中看見,需要有自己的屬性編輯器(如果不想在物件察看器看當然就不用啦),是比較高階的元件,在後來的元件製作再來介紹,會更直觀一些。這裡只給出它的定義形式:
property selected[index: integer]: boolean read getselected write setselected;
三、事件:事件其實是一種特殊的屬性,他是指標型別,指向乙個事件方法型別。當有特定的事件發生時,它就會關聯到一段執行程式碼。
下面以乙個例子來講解事件是怎麼發生的。
我們先定義乙個滑鼠點下事件的滑鼠事件型別,它其實就是方法指標:
type tmouseevent = procedure (sender: tobject; button: tmousebutton; shift: tshiftstate; x, y: integer) of object;
又定義乙個私有成員:滑鼠事件型別的,即乙個方法指標型別
fonmousedown:tmouseevent
最後定義乙個屬性:類要通過這個屬性將外部的事件處理函式和fonmousedown關聯在一起:
onmousedown:tmouseevent read fonmousedown write fonmousedown;
當有滑鼠左鍵點選的,系統會向視窗會傳送wm_lbuttondown;訊息
delphi 可以截獲這個訊息,如下定義訊息函式:
procedure wmlbuttondown(var message: twmlbuttondown); message wm_lbuttondown;
在這個訊息處理函式中調domousedown,domousedown又調 用了mousedown
在這個函式裡面才到了最重要的部分
該函式是這樣的:
procedure tcontrol.mousedown(button: tmousebutton;shift: tshiftstate; x, y: integer);
begin
if assigned(fonmousedown) then fonmousedown(self, button, shift, x, y);
end;
而我們先來看看使用者外部是怎麼操作的,
他自己定義乙個someobjmousedown; 是乙個事件處理函式,必須和tmouseevent的形式一樣:
procedure someobjmousedown(sender: tobject; button: tmousebutton; shift: tshiftstate; x, y: integer);
然後他這樣賦值:someobj.onmousedown:=someobjmousedown;
當賦值以後,類內部其實是通過onmousedown屬性,將someobjmousedown;與fonmousedwon關聯在一起,也就是說,
mousedown方法中呼叫了fonmousedown(self, button, shift, x,
y);其實就等於呼叫了procedure someobjmousedown(sender: tobject; button:
tmousebutton;shift: tshiftstate; x, y: integer);
所以使用者就可以在這個自定義的事件方法中寫自己的程式碼,當事件發生時,該類的排程機制就會自動呼叫這個事件方法啦
也許有人會問,為什麼從訊息處理函式要呼叫domousedown,domousedown又呼叫mousedown,然後再呼叫事件方法呢。為什麼不直
Neo4j之一 概念 語句 函式
neo4j中基本元素有三種 結點 node 關係 relationships 路徑 path neo4j基於模式對graph查詢,因此要想查詢目標先得知道如何描述目標符合的模式。1.1.1 結點的描述 結點通過小括號描述,結點名可省略。a 1.1.2 結點的標籤 結點標籤通過 標籤名 描述,結點至少...
面試總結一(概念)
1.定義和宣告的區別 宣告是告訴編譯器這個函式或者變數可以在 找到,它的模樣是什麼。而定義是告訴編譯器 在這裡建立函式或變數,並為他們分配記憶體空間。變數的宣告 extern int a 變數的定義 int a 如果在此之前沒有對變數的宣告,則這裡既是宣告也是定義。編譯器會為其分配對應的記憶體。2....
Spring 運用(一) 概念
spring強大的核心功能之一,顛覆原有的依賴關係,後面稱為依賴注入。即由ioc容器管理依賴關係 依賴相關的bean的生命週期。註解spring註解很強大,類似於通過 autowire或者 resource進行bean的注入。配置配置又分為setter和construction。面向方面的程式設計,...