元件製作之一(概念)

2022-03-24 16:48:48 字數 3737 閱讀 2784

作為元件製作的開始,應該了解一些概念,我以為這些概念是非常重要的,將可以作為以後實踐的理論基礎。

一、元件的簡要層次結構。一般情況下,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。面向方面的程式設計,...