1、包的命名介紹:
包的命名沒(méi)有規則,但是建議遵守包的命名約定:包的命名與包的版本相關(guān),包的名稱(chēng)前面幾個(gè)字符通常表示作者或公司名,也可以是控件的一個(gè)描述詞,后面緊跟的Std表示運行期包,Dsgn表示設計期包,然后是版本號。如:MyDataEditStd60,MyDataEditDsgn60。
2、對象瀏覽器【Object Inspector】中一個(gè)屬性感知一類(lèi)控件的原理:
控件屬性的感知只不過(guò)是將它的一個(gè)屬性聲明為將要感知的控件類(lèi)而已,例如要感知Image控件,則:property MyImage:TImage read GetImage write SetImage;這樣之后,窗體中的所有的TImage類(lèi)型的控件,它都能感知到。
3、數據感知控件與其他相關(guān)控件進(jìn)行交互的方法:
數據感知控件通過(guò)DataLink對象與DataSource進(jìn)行交互,所以為控件增加數據感知能力需要創(chuàng )建一個(gè)TDataLink(或其派生類(lèi))對象作為控件的成員,并為控件創(chuàng )建公開(kāi)的DataField和DataSource屬性;然后需響應TDataLink對象的OnDataChange和OnUpdateData事件。
我們用到了一個(gè)重要的類(lèi)TFieldDataLink。它是控件內部的數據聯(lián)接對象,從TDataLink繼承下來(lái),它的作用是與TDataSource組件相互通信,連接單個(gè)字段進(jìn)行數據提取。我們將要處理這個(gè)對象的OnDataChange事件,這樣,當字段或記錄有所改變時(shí)就會(huì )得到通知,進(jìn)行相應的數據處理。
4、當其中一個(gè)控件被刪除或者斷開(kāi)時(shí),通知其他控件的通知函數:
感知組件需要和DataSource數據源控件和DataSet數據集控件相組合才能實(shí)現數據庫數據的讀寫(xiě),那么當刪除其中一個(gè)時(shí),如果其他兩個(gè)控件不知道,就會(huì )出現異常,甚至導致死機。那么我們怎樣才能做到通知其他組件呢?Value.FreeNotification(Self)就是做這個(gè)工作的!FreeNotification(self)將會(huì )把我們的組件置入其通知對象列表中,被撤消時(shí),它會(huì )依次調用通知對象列表中所有對象的Notification方法。每個(gè)數據控件都有一個(gè)Notification方法,當某一控件從窗體上移走時(shí),DELPHI的IDE調用該方法通知其它控件。
本文以制作一個(gè)類(lèi)似于DBEdit的控件為例。
1、 創(chuàng )建組件,并安裝在新包中。
1>、首先使用組件向導從TEdit(StdCtrls)下繼承下來(lái),命名TMyDataBaseEdit,單元名為MyDataBaseEdit.pas,
2>、安裝在一個(gè)新的包文件中,起名為MyDataEditStd60.Dpk。 (此種不需要dpr工程)
(【Delphi 編寫(xiě)Pas文件類(lèi)型的組件】 中的 【二、制作一個(gè)簡(jiǎn)單的組件基本步驟】 有介紹)
2、 添加屬性。
1>、聲明一個(gè)內部數據連接對象:TfieldDataLink,用于與TDataSource進(jìn)行通信。
在Private中添加代碼: FDataLink: TFieldDataLink; // Uses DBCtrls;
2>、添加數據源感知屬性:DataSource 和字段感知屬性:DataField ;其值就顯示Text中,處理事件是DataChange
和UpdateData。
只需在Pubished域添加以下代碼:
property DataSource: TDataSource read GetDataSource write SetDataSource;// Uses DB:
property DataField: string read GetDataField write SetDataField;
3>、按下【shift +ctrl+ C】組合鍵完成屬性的自動(dòng)結構化功能,
private域自動(dòng)添加四個(gè)函數:
procedure SetDataSource(const Value: TDataSource);
function GetDataSource: TDataSource;
procedure SetDataField(const Value: string);
function GetDataField: string;
4>、上面四個(gè)函數的實(shí)現方法:
function TMyDataBaseEdit.GetDataSource: TDataSource;
begin
Result := FDataLink.DataSource;
end;
procedure TMyDataBaseEdit.SetDataSource(const Value: TDataSource);
begin
if not(FDataLink.DataSourceFixed and (csLoading in ComponentState)) then
begin
FDataLink.DataSource := Value;
end;
if Value <> nil then
begin
// 將會(huì )把我們的組件置入其通知對象列表中,被撤消時(shí),它會(huì )依次調用通知對象列表
// 中所有對象的Notification方法,
Value.FreeNotification(Self);
end;
end;
function TMyDataBaseEdit.GetDataField: string;
begin
Result := FDataLink.FieldName;
end;
procedure TMyDataBaseEdit.SetDataField(const Value: string);
begin
FDataLink.FieldName := value;
end;
3、 添加方法:
1>、實(shí)現通知函數(必須的)。
當某一控件從窗體上移走時(shí),DELPHI的IDE調用該方法通知其它控件。這樣,當關(guān)聯(lián)的參考控件被刪除時(shí),控件就會(huì )得到消息,來(lái)處理事件,防止異常的發(fā)生,否則將會(huì )導致Delphi開(kāi)發(fā)環(huán)境的不穩定甚至死機。
在protected中添加代碼:
procedure Notification(AComponent: TComponent;Operation: TOperation);override;
添加實(shí)現的代碼:
procedure TMyDataBaseEdit.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
// 當與控件相連的TdataSource控件被刪除時(shí)將控件的DataSource屬性置為空
if (Operation = opRemove) and (FDataLink <> nil) and (AComponent = DataSource) then
DataSource := nil;
end;
2>、實(shí)現數據處理過(guò)程
當DataSet的記錄改變(如在DBGrid中滑動(dòng)滾輪的瀏覽記錄)時(shí)觸發(fā)OnDataChange事件,DataChange作為該事件的事件處理句柄。
在Private中添加代碼:
procedure DataChange(Sender: TObject);
添加實(shí)現的代碼:
procedure TMyDataBaseEdit.DataChange(Sender: TObject);
begin
//若控件連接了的DataSet,則數據集變動(dòng)時(shí)控件顯示當前記錄的相應字段值
if FDataLink.Field <> nil then
begin
Text := FDataLink.Field.Text;
end;
end;
3>、實(shí)現數據更新過(guò)程:
更新DataSet前將觸發(fā)OnUpdateData事件,UpdateData將作為該事件的事件處理句柄;
在Private中添加代碼:
procedure UpdateData(Sender: TObject);
添加實(shí)現的代碼:
procedure TMyDataBaseEdit.UpdateData(Sender: TObject);
begin
// 用控件中的Text更新到相應的字段
FDataLink.Field.Text := Text;
end;
4>、實(shí)現控件失去焦點(diǎn)時(shí)的消息處理函數:
當控件失去焦點(diǎn)時(shí)觸發(fā)CM_EXIT消息
在private中添加代碼:
procedure CMExit(var Message: TCMExit);Message CM_Exit;
添加實(shí)現的代碼:
procedure TMyDataBaseEdit.CMExit(var Message: TCMExit);
begin
try
// 控件失去焦點(diǎn)時(shí)更新DataSet,這將觸發(fā)OnUpdateData事件
FDataLink.UpdateRecord;
except
setFocus;
//這里是將發(fā)生的異常顯現出來(lái)。因為用了try except end后就不會(huì )顯示出異常和錯誤。
raise;
end;
DoExit;
end;
5>、重新編寫(xiě)構造函數:
在構造函數中創(chuàng )建DataLink對象,連接OnDataChange、OnUpdateData事件處理句柄。
在public中添加代碼:
constructor Create(AOwner: TComponent);Override;
添加實(shí)現的代碼:
constructor TMyDataBaseEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner); //必須加上這句話(huà);
//創(chuàng )建DataLink對象,連接OnDataChange、OnUpdateData事件處理句柄
FDataLink := TFieldDataLink.Create;
FDataLink.OnDataChange := DataChange;
FDataLink.OnUpdateData := UpdateData;
end;
6>、重新編寫(xiě)析構函數:
在析構函數中銷(xiāo)毀DataLink對象,并釋放對OnDataChange、OnUpdateData事件的連接。確保使用完之后銷(xiāo)毀FDataLink的實(shí)例,釋放空間,無(wú)論是寫(xiě)組件還是寫(xiě)程序我們都要嚴格注意聲明的對象,一定要在使用完之后釋放!
在public中添加代碼:
destructor Destroy;override;
添加實(shí)現的代碼:
destructor TMyDataBaseEdit.Destroy;
begin
FDataLink.OnDataChange := nil;
FDataLink.OnUpdateData := nil;
FreeAndNil(FDataLink);
Inherited ;
end;
1、在創(chuàng )建新包dpk或者選擇已經(jīng)存在的包之后,點(diǎn)擊【Ok】之后會(huì )出現安裝【dpk文件對話(huà)框】,按其中的【Compile】就可以檢查你編寫(xiě)的代碼是否存在錯誤,但不能檢測邏輯錯誤。
2、【Project】—>【Build XXX】也能檢測代碼中的錯誤。但是直接打開(kāi)Pas文件,這個(gè)按鈕不可用??梢韵赛c(diǎn)擊打開(kāi)其所在的dpk,然后打開(kāi)pas文件, 但不能檢測邏輯錯誤.
3、安裝完自定義控件后,在自定義控件的Pas中修改代碼,會(huì )直接影響到調用他的程序中,所以可以直接在自定義控件的Pas文件中設置斷點(diǎn),進(jìn)入調試, 可以檢測邏輯錯誤;
4、在自定義控件的Pas文件中,添加的新屬性、事件。在應用程序中能通過(guò)代碼直接調用,但是在對象監控器【Object Inspector】中不會(huì )顯示,只能重新加載自定義控件,才能顯示。
第一種方法:
1、【File】-> 【Open Project】命令,然后在對話(huà)框中選擇文件類(lèi)型為【*.dpk;*.dpkw】的文件;
2、然后【打開(kāi)】,會(huì )出現【dpk文件對話(huà)框】,點(diǎn)擊【Compile】—>【Install】,進(jìn)行安裝.。
第二種方法:
1、直接在dpk文件上雙擊,就會(huì )出現【dpk文件對話(huà)框】,點(diǎn)擊【Compile】—>【Install】,進(jìn)行安裝.。
1、【Component】—>【Install Packages】,出現一個(gè)對話(huà)框。
2、然后在【Designs Packages】 中找到當前包相對應的同名bpl文件。
3、然后【Edit】->【Yes】,打開(kāi)【dpk文件對話(huà)框】,然后選擇對應的文件,點(diǎn)擊【Remove】刪除。
然后再編譯安裝。
(也可以直接找到相應的DPK文件,雙擊進(jìn)入【dpk文件對話(huà)框】,一般默認在lib下)
查看組件所屬的包:
在【組件面板】上相應的組件上【右擊】—>【Properties】,然后打開(kāi)對話(huà)框,可以在【Palette】中,右側欄中看【Components】中看到name,和它所處的包。
聯(lián)系客服