国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院

首頁 > 編程 > Delphi > 正文

Delphi程序設計之--慣用法

2019-11-18 18:34:49
字體:
來源:轉載
供稿:網友
 

Delphi --技巧探索:  
{ No. 1 }
創建模式窗體的句子:
class PRocedure TMyForm.RunForm(AObj1, AObj2: TObject);
var
vForm: TMyForm;
begin
vForm := TMyForm.Create(application);
with vForm do
Try
 InitForm(AObj1, AObj2);
 ShowModal;
Finally
 Free;
end;
end;
//*說明:
通過class聲明的函數,類似與VC中的靜態函數;使用語句:TMyForm.RunForm(vObj1, vObj2);
其他具體的,參考:Delphi 幫助中的,class 類說明。
強調這個慣用法,就是為了:
1、如果此窗體在多處被使用,那么可以保證統一都調用此段代碼;
2、如果功能上有所修改,比如:根據ShowModal的返回值不同進行處理,那么只修改此函數就行了。
3、程序封裝性好,易于維護和工作交接。*//

{ No. 2 }//Tag 的使用
窗體工具欄按鈕事件的響應
procedure TMyForm.RunOperate(ATag: Integer);
begin
 Case ATag of
 1: MyButton.Color := clRed;
 2: MyButton.Color := clGreen;
 3: MyButton.Color := clBlack;
 end;
end;

procedure TMyForm.ToolBtnClick(Sender: TObject);
begin
 RunOperate(TControl(Sender).Tag);
end;

如果你在某下拉菜單中,也需要執行類似功能則
procedure TMyForm.MenuItemClick(Sender: TObject);
begin
 RunOperate(TMenuItem(Sender).Tag);
end;

//*說明:
1、結構清晰
2、相關的信息集中,比較容易查錯、修改和維護
3、提高程序的適應、擴展能力;比如現在要求不在工具欄按鈕中實現,而要求在不同按鈕中實現,則修改容易。
建議:每個分類后面只跟一行或不多的幾行代碼,如果代碼比較多,使用過程函數替代。
比較有意思的是,我經常如下寫:
Case btnMyButton.Visible of
{ 顯示 } True: ...
{不顯示} False: ...
end;    *//

 

{ No. 3 }//事件指針做參數
//對于列表等的讀取使用事件指針的方式
type
 TDataSetEvent = procedure (DataSet: TDataSet; AIndex, ACount: Integer) of Object;
//從 TADOQuery派生而來的類
procedure TMyADOQuery.EnumRecord(AWhereStr: String; APro: TDataSetEvent);
begin
 Close;
 SQL.Clear;
 SQL.Add('Select * From Table1');
 if AWhereStr <> '' then
   SQL.Add('Where ' + AWhereStr);
 Open;
 While Not Eof do
 begin
   if Assigned(APro) then APro(Self, RecNo, RecordCount);
   Next;
 end;  
 Close;
end;

//*說明:
此方法來自與Window中,枚舉當前所有子窗體的API函數,EnumChildWindow
1、原則:盡量將數據讀取與數據顯示、數據處理等分離;如:MVC等都是此目的。
2、程序擴展性增強,如果您原來希望在列表中顯示或處理某列信息,后來改為用ComboBox,則在修改程序時,不在閱讀數據讀取部分,只需要修改信息顯示等即可。又比如,現在要求您在讀取記錄時,用進度條顯示讀取進度等。
*//

 

{ No. 4 }//常量數組

{ 在 No.2 中,實現了如下的內容
procedure TMyForm.RunOperate(ATag: Integer);
begin
Case ATag of
1: MyButton.Color := clRed;
2: MyButton.Color := clGreen;
3: MyButton.Color := clBlack;
end;
end;
}
//那么用數組方式實現,則就比較理想了
procedure TMyForm.RunOperate(ATag: Integer);
const
 MyButtonColorMax := 3;
 MyButtonColor: array [1..MyButtonColorMax] of TColor = (clRed, clGreen, clBlack);
begin
Case ATag of
1..MyButtonColorMax:  MyButton.Color := MyButtonColor[ATag];
101:....
end;
end;

//*說明:
對于數組方式使用,只要注意數組的上限或下限使用常量來實現,然后在以后使用中都盡量使用此常量進行數組循環讀取就行了。
*//

 

{ No. 5 }消息機制 減少類公共函數
//如何讓一個窗體中,盡量減少公共函數的定義;
{ 比如:要實現一個當前窗體控件的屬性列表窗體,當需要刷新屬性窗體;改變某屬性值;添加新的屬性等;會有很多需要交互的信息。如果我們使用類公共函數,則需要定義很多的公共函數。同時,如果需要進行窗體類型轉換,轉換為目標窗體類型才可以使用公共函數。所以,會遇到兩個單元需要互相包含的情況 }
//解決方案:
TfrmMyForm = class(TForm)
 FfrmProperty: TForm;
end;

...
 FfrmProperty := TfrmProperty.MyCreate(Application, Self);
...

//當需要刷新屬性窗體時
 FfrmProperty.Perform(WD_REFRESHPROPERTYLIST, 0, 0);

TfrmProperty = class(TForm)
private
 FMyForm: TForm;
 procedure WDREFRESHPROPERTYLIST(var Message: TMessage); message WD_REFRESHPROPERTYLIST;
public
 constructor MyCreate(Owner: TComponent; AForm: TForm);
end;

constructor TfrmProperty.MyCreate(Owner: TComponent; AForm: TForm);
begin
 inherited Create(Owner);
 FMyForm := AForm;
end;

//* 對于使用消息的方式,可以減少窗體公共函數的定義。同時,提高程序的可擴充性。如果,使用他的窗體替代時,則可以比較輕松的轉換,因為如果最多也就是您的窗體,對當前的消息沒有進行處理而已 *)// 

 

 

{ No. 6 }使用注冊列表管理可能擴充的模塊
//項目:要求你對一個數據集支持多種輸出顯示方式

...例子,以后給出

//* 說明:
1、“多種輸出方式”,說明輸出方式在今后的應用中可能會經常擴充,因此要在程序設計時考慮到輸出方式的易擴充性。
2、參考VCL中,控件注冊(RegisterComponents)的機制,可以發現VCL中大量的使用到了注冊機制;其中比較經典的就是控件屬性編輯器的注冊了。
*//

{ No. 7 }使用預定義控制程序版本

//如果您做的是一個二次開發平臺的程序,則必須涉及到產品版本控制和項目版本控制問題
//通常使用預定義的方式控制

//語句比較簡單了就是:
{$DEFINE JOYYUAN97}
{$IFDEF JOYYUAN97} {ELSE} {ENDIF}
{$UNDEF JOYYUAN97}

*說明:
1、將預定義劃分在多個單獨的文件中。
2、在每個單元的最前頭但在Unit 后,使用{$I ...} 將文件包含(Include)進當前單元
3、根據預定義情況控制當前單元所能包含的單元文件
4、盡量單獨劃分一個針對項目的預定義文件在包含所有預定義文件后,包含此文件,則在此文件中,可以針對項目的需要,將取消部分預定義{$UNDEF JOYYUAN97}
*//

{ No. 8 } 使用函數指針,減少單元項目包含

//我經常的認為減少單元的包含,是做公共單元的第一步,所以在如何盡量減少單元包含
//也就是如何減少程序單元的耦合性上,應多下工夫。

{ 情景描述:
TMyFormManager: 窗體管理類
TMyForm:數據窗體基礎類
TMyFormaccess:窗體信息保存和讀取類。將窗體信息保存到數據庫或其他什么類型的結構中
分析:
1、窗體基礎類(TMyForm) 和 窗體管理類(TMyFormManager)需要在一個單元 uManagers中實現。
2、窗體具體實現類(TMyImageForm)單元 fMyImange 需要包含單元uManagers,進行窗體繼承,和窗體管理。
3、窗體數據讀取類(TMyFormAccess)單元 uMyAccess 需要包含單元uManagers和單元fMyImange
問題:
 如果我希望實現窗體保存,那么應該在窗體的某個按鈕事件中實現。則涉及到窗體單元需要包含窗體數據訪問類單元,而如果放在窗體基礎類中,則單元uManager又必須包含單元uMyAccess。
 當數據訪問,即數據存儲格式會根據要求而改變并要求可擴充時,則單元包含必定是一個隱患。
解決辦法:使用函數指針變量。
1、在單元uManagers中定義一個,保存數據信息的函數指針變量。
2、在應用程序初始化的時候給這個函數指針變量賦值。
3、在需要保存窗體信息時,判斷如果指針不為空,則執行函數保存窗體信息。

{ No. 9 } 常量,認識常量,使用常量
有很多書都都介紹了常量定義的重要性,我也會經常想到,但是看看VCL源碼才知道,自己忽略了,別人對常量的使用情況。

1、我們經常使用的消息的定義就是:聲明一個常量,然后在適當的時候使用之。
 通常定義和使用:
 const
   WD_MyMessage = WM_User + 101;
 type
 TMyForm = class(TForm)
 ...
   procedure WDMyMessage(var message: TMessage); message WD_MyMessage; {響應消息位置}
 end;
 但是,如果您將{響應消息位置}語句改寫為:
   procedure WDMyMessage(var message: TMessage); message WM_User + 101;
 同樣,編譯可以成功,使用也正常。所以,常量定義在Window系統處理和接口中應用非常普遍。

2、在Delphi中,我們定義了顏色變量,clRed, clGreen等,也都是定義的常量,便于以后的使用。通過這個觀察我發現,常量的定義應該是在項目中,可部分復用的,所以,可以定義一個標準常量單元,以便在個項目中,復用定義的常量。

 

 { No. 10 }一個Delphi中,常用到的數組

對TIdentMapEntryd類型的數組定義和使用,Delphi中,有比較完善的實現。
 TIdentMapEntry = record
   Value: Integer;
   Name: String;
 end;

1、數組定義:array[0..ArrMax] of TIdentMapEntry
 可參考:Controls單元中:
 Cursors: array[0..21] of TIdentMapEntry = (
 ...
 );
2、兩個互相求值得函數: IntToIdent(由Value求Name)和 IdentToInt(由Name求Value);
 具體應用可以參考:IdentToCursor 和 CursorToIdent。

3、應用:a、直接應用此樹組定義方式和數組操縱函數;b、學習函數中,對數組訪問和操縱的方式。c、學習標準的信息訪問函數定義: function IntToIdent(Int: Longint; var Ident: string; const Map: array of TIdentMapEntry): Boolean; 具體返回的信息由參數方式返回回來,至于訪問是否有效,則通過函數的布爾返回值加以判斷。

 

{ No. 11 } 由特例到普通的發現
我通過對 Cursors 的定義和操作函數的跟蹤發現:
1、如 { No. 10 }中介紹的,將Cursors的定義和一般操作通用化。
2、提供 Int 和 Ident互轉化的函數。
3、提供數組列表信息循讀取的函數: GetCursorValues;其中,使用了 { No. 3 } 中介紹的“事件指針 做參數”讀取列表信息的方法。

{ No. 6 } 的補充:
例子:
procedure RegisterComponents(const Page: string;
 ComponentClasses: array of TComponentClass);
begin
 if Assigned(RegisterComponentsProc) then
   RegisterComponentsProc(Page, ComponentClasses)
 else
   raise EComponentError.CreateRes(@SRegisterError);
end;

解讀:
1、使用注冊的方式,記錄可使用的控件的類型等。
3、對于 RegisterComponentsProc 使用了{ No. 8 } 中“使用函數指針,減少單元項目包含”的方法,便于將來程序的擴充,版本的升級等。

 

 { No. 11 }只定義一個公共函數
//項目描述:現在要實現一個CAD畫圖或Visio系統,要求有好的擴展性和易維護性;
//并且要求耦合性低,便于,將來系統的部分或擴展后的系統封裝后,直接在今后的項目中使用

設計:
1、設計一個圖形對象抽象類,在此類中,定義一個抽象函數 CadPerform,函數的參數參照function TControl.Perform(Msg: Cardinal; WParam, LParam: Longint): Longint;
2、在圖形管理類中,實現一個圖形對象列表的管理,列表中保存的是抽象對象的指針。
3、對于要對具體類對象進行操縱控制時,只需通過條用CanPerform函數,然后根據當前操作的類別傳入 Msg, 并傳入相應的參數信息。

實現: TCad 為由抽象類繼承下來的第一層控件類
function TCad.CadPerform(Msg: Cardinal; WParam, LParam: Longint): Longint;
begin
 Case Msg of
 My_Message1: Result := MyMessage1(WParam, LParam);
 My_Message2: Result := MyMessage2(WParam, LParam);
 end;
end;
對于,TPoint繼承自 TCad, CadPerform函數實現如下。
function TPoint.CadPerform(Msg: Cardinal; WParam, LParam: Longint): Longint;
begin
 Case Msg of
 My_Message1: Result := MyMessage1(WParam, LParam); //屏蔽了TCad中此操作類型的處理
 My_Message3: Result := MyMessage3(WParam, LParam);
 else Result := inherited CadPerform(Msg, WParam, LParam);
 end;
end;

*說明:
因為,我們對圖形對象的操作會非常頻繁,所以我們通過定義一個公共開放的接口函數來實現,類的高封裝性和程序的易維護性、好擴展等性能。
*//

 

{ No. 12 }

以下是我編程時的要求:(部分信息沒有語言限制)
//以下的解決方案,幾乎都可以在上面的方法中,找到
1、減少程序的復雜度。a、減少函數個數,使用Case、Tag方式,學習實現Perform定義方式;b、減少單元嵌套關系,使用消息傳遞方式,減少窗體單元的互相包含。
2、減少

 

{ No. 13 }使用廣播,實現管理類對管理列表對象的通知

//對于{ No. 12 } 項目描述中,當畫圖的窗體控件屬性或狀態改變時,經常會需要通知所有的圖形對象,進行相應的改變。
//則如果只定義一個廣播函數,就可以實現父子通知的話,也會提高程序的可重用性、擴展性、易維護性等,使類結構清晰。

//比如:1、在Visio和MapInfo中,如果當前窗體的比例尺(縮放比例)改變時,需要用新的比例尺重畫當前所有的顯示圖形對象。2、當當前窗體默認窗體字體改變后,對于默認使用窗體字體顯示文字信息的圖形對象,他們的文字字體也應該相應的改變。

//解決方案,參考TWinControl中,屬性或狀態改變時,通知所有子Controls的處理機制:
procedure TWinControl.NotifyControls(Msg: Word);
var
 Message: TMessage;
begin
 Message.Msg := Msg;
 Message.WParam := 0;
 Message.LParam := 0;
 Message.Result := 0;
 Broadcast(Message);//廣播當前的變更消息
end;
其中:
procedure TWinControl.Broadcast(var Message);
var
 I: Integer;
begin
 for I := 0 to ControlCount - 1 do
 begin
   Controls[I].WindowProc(TMessage(Message));
//改為:with TMessage(Message) do Cads[I].CadPerform(msg, WParam, LParam);
   if TMessage(Message).Result <> 0 then Exit;
 end;
end;
但是,我們處理圖形對象時,可能會直接調用 Cads 的CanPerform公共函數即可

{ No. 14 }需要時,動態創建你的對象

比如:http://www.delphibbs.com/keylife/iblog_show.asp?xid=824 中的
//*******方案二  當需要的時候在創建屬性窗體
uses
...
fProperty;
type
TfrmMyMap = class
  ...
  procedure OnfrmMyMapDestroy(Sender: TObject);
  procedure OnMapGeoSelected(AGeo: TGeometry);
private
  FfrmProperty: TfrmProperty;
  procedure ShowPropertyForm(aVisible: Boolean);
public
end;

procedure TfrmMyMap.ShowPropertyForm(aVisible: Boolean);
begin
if Not Assigned(FfrmProperty) then FfrmProperty := TfrmProperty.Create(Application);
FfrmProperty.Visible := aVisible;
end;

procedure TfrmMyMap.OnfrmMyMapDestroy(Sender: TObject);
begin
if Assigned(FfrmProperty) then FfrmProperty.Free;
end;

procedure TfrmMyMap.OnMapGeoSelected(AGeo: TGeometry);
begin
if Assigned(FfrmProperty) then FfrmProperty.MyRefresh(AGeo);
end;

這里說明了:
1、需要時,動態創建你的對象 FfrmProperty
2、當前對象釋放時,判斷你的對象的合法性,然后釋放動態創建的對象。

 

 { No. 15 }創建接口還是創建結構

//項目描述:我開發一個表格控件時,如果我將單元格設置為一個Com,則如果表格現實的信息過多的話,則裝載速度無法保證,甚至于有死機的可能。我之所以用Com是為了將來每個單元格的處理和信息都可以在控件外擴展。

我的解決辦法是:對于每個從Cell派生來的控件創建一個實例,通過動態創建若干個結構對象Record來記錄個單元格的信息,如果需要對單元格進行操作,則將結構對象指針賦值給Cell組件,測試結果很令人滿意。

所以,如果需要使用某個Com大量實例的話,盡量管理和維護一個實例,而對于其中的數據可以實行動態創建管理,速度上會有很好的效果。
另外,盡量聲明一個 pMyInterface = ^IMyInterface 借口指針,參數傳遞或使用時,直接使用接口指針,這樣可以減少調用計數函數_AddInft等,如果操作平凡也可以提高速度的。


上一篇:用API函數在DELPHI中實現“非典型”窗體

下一篇:NeHe的opengl教程delphi版(7)----濾波

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院
aaa大片在线观看| 最近中文字幕mv免费高清电影| 最近中文字幕在线中文视频| 蜜桃视频网站在线| 国内精品不卡| 国产精品666| 亚洲视频网站在线| 黄色一级片视频| 国产导航在线| 久蕉依人在线视频| 在线成人一区| 午夜国产福利在线| 午夜影院免费看| 欧美日韩在线视频免费观看 | 国产中文伊人| 国产黄色av免费看| 国产资源在线看| av免费在线免费| 国产高清av| 国产三级做爰在线观看| 九九热在线免费视频| 在线观看免费黄色| 国产黄色网页| 中文字幕一区免费| www.av在线视频| 精品麻豆一区二区三区| 中文字幕国产在线| 免费午夜一级| 开心丁香婷婷深爱五月| 亚洲v片在线观看| 在线影视一区| 在线观看免费观看在线91| 国产一二三区在线视频| 国产在线一区二区视频| 日本在线天堂| 日本电影全部在线观看网站视频| 精精国产xxxx视频在线中文版| 国产精品第八页| 91九色在线看| 国产成人亚洲精品播放器下载| 国产无遮挡又黄又爽免费软件| 成人日韩欧美| 国产区视频在线播放| 国产精品视频福利一区二区| 国产日本视频| av免费在线观看网站| 四虎精品成人a在线观看| аⅴ成人天堂中文在线| 另类专区欧美| 国产一区精品| 国产黄色av免费看| 亚洲综合激情六月婷婷在线观看| 亚洲综合色视频在线观看| 亚洲精品视频区| 日本亚洲精品| 国产秒拍福利视频露脸| 国产精品视频h| 夜夜爽视频导航| 成年午夜在线| aaa大片在线观看| 激情四房婷婷| 91免费日韩| xxxxx中文字幕| 国产三级在线免费观看| av中文在线资源| 天天操天天是| 天海翼中文字幕| 国产一级片麻豆| 欧洲有码在线视频| 最近中文字幕大全中文字幕免费| 69日小视频在线观看| 久草网在线视频| av日韩在线免费| 国产福利免费观看| 高潮白浆视频| 亚洲国产日韩在线人成电影| 国产深夜视频在线观看| 久久精品国产亚洲777| 97人人在线| 天堂在线看视频| 亚洲精品少妇久久久久久| 国产视频中文字幕在线观看| 欧美精品另类| 四虎成人精品在永久在线观看| 资源视频在线播放免费| 牛牛精品视频在线| 亚洲免费国产| 精品视频一二区| 国产精品久久久久久福利| 另类综合图区| 本道综合精品| 四虎精品视频| 日韩精品免费一区二区| 中文字幕2020第一页| 国产高清在线看| 国产高清在线a视频大全| 最近高清中文在线字幕在线观看| 免费看的av| 欧美96在线| www.成人.com| 青草视频在线播放| 日本成a人片在线观看| 久热久精久品这里在线观看| 开心婷婷激情五月| 成人亚洲一区二区三区| 国产乱xxⅹxx国语对白| 丁香婷婷在线观看| 国产精品不卡一区二区三区在线观看| 中文字幕在线播放网址| 国产精品久久久精品a级小说| 国产精品178页| 亚洲国产成人综合| 黄色国产网站在线播放| 国产偷窥洗澡视频| 精品国产丝袜高跟鞋| xxxxx中文字幕| 国产麻豆视频网站| 国产www网站| 老司机在线视频二区| 午夜视频免费在线观看| 国产传媒在线播放| 欧美精品日韩少妇| 国产一级片麻豆| 亚洲欧美综合乱码精品成人网 | 精品51国产黑色丝袜高跟鞋| 99爱视频在线观看| 国产在线色视频| 2019年中文字幕| 九九视频精品在线| 精品a在线观看| 天天操天天曰| 日韩国产成人| 国产三级在线| 欧美高清视频| 在线观看中文| 国产porn在线| 日本中文字幕视频| 九九精品视频在线观看九九| 在线观看精品一区二区三区| 黄色av免费在线| 一级二级三级在线观看| 中文字幕在线第一页| 青青草视频免费在线观看| 国产精品视频福利一区二区| 牛牛精品视频在线| 精品国内一区二区三区免费视频| 国产精品外围在线观看| 欧美高清视频| 免费电影网站在线视频观看福利| 99reav| 精品无人区乱码1区2区3区免费 | 开心快乐六月丁香婷婷| 国产高清一区二区三区视频| 国内a∨免费播放| gogo高清在线播放免费| 精品国产丝袜高跟鞋| 国产porn在线| 精品视频一二三| 国产高清在线| 99视频资源网| 国产精品视频h| 国产porny蝌蚪视频| 国产日韩欧美精品一区二区三区| 91xxx在线观看| 天天操天天操天天色天天要| 国产一区二区三区不卡免费观看 | 狠狠操狠狠色| 日本中文字幕视频| 国产丝袜在线观看视频| 国产极品一区二区三区 | gogo在线高清视频| 牛牛精品视频在线| 91av久久| 在线观看免费高清完整| 在线观看av网站永久| 亚洲天堂影院在线观看| 青青草免费在线视频| 国产理论片免费观看| 国产福利资源| 快射av在线播放一区| 国产精品免费91| 人人澡人人爽| 国产一区二区三区不卡免费观看 | 在线91av| 色悠久久久久综合网小说| www在线视频| 中文字幕国产视频| 热99re久久精品这里都是免费| 国产自产视频| 日本高清中文字幕| 丁香视频五月| 精品视频一二三| 国产麻豆精品入口在线观看| 91九色在线看| 国产麻豆免费| 欧美精品日韩少妇| 91黄色在线| 国产一级在线| 九九热视频免费观看| 精品176二区|